Ради вашего удобства наш сайт использует cookies! Узнать больше! Мы используем cookies

SQLite API [MP/SP]

LuaSQLite — SQLite API for Project Zomboid Mods [b]A Java patch that exposes a full SQLite API to Lua scripts.[/b] Store persistent mod data in real .db files — no more serializing everything into ModData. What is this? Project Zomboid ships SQLite inside its JAR but never exposed it to mod scripts. This patch adds [b]LuaSQLite[/b] as a global Lua object, giving any mod direct access to a relational database. Features [list] [*] Open or create a [b].db file[/b] anywhere on disk [*] Run any SQL: CREATE TABLE, INSERT, UPDATE, DELETE, SELECT, PRAGMA [*] [b]Parameterized queries[/b] (?) — safe from SQL injection [*] [b]Transactions[/b]: beginTransaction / commit / rollback [*] Results as Lua tables, ready to iterate [*] Thread-safe — all methods are synchronized [*] No external dependencies — uses the SQLite driver already bundled in PZ [/list] API LuaSQLite.open(path) -- opens/creates a database db:exec(sql) -- DDL/DML, returns rows affected db:execParams(sql, params) -- DML with ? placeholders db:query(sql) -- SELECT, returns table with rows db:queryParams(sql, params) -- SELECT with ? placeholders db:beginTransaction() db:commit() db:rollback() db:close() db:isOpen() How to install [b]You do NOT need to enable this mod in server settings or the client mod list.[/b] Just inject the .class files into [b]projectzomboid.jar[/b] in the [b]PZ root folder[/b]. After subscribing, find the .class files inside the mod at: [b]sqliteModule → 42 → media → lua → zombie → Lua[/b] Method 1 — Manual (WinRAR / 7-Zip, no terminal needed) [list] [*] Open [b]projectzomboid.jar[/b] with WinRAR or 7-Zip [*] Navigate to [b]zombie → Lua[/b] inside the archive [*] Drag all .class files from the mod folder into the archive [*] Confirm overwrite — done [/list] [i]WinRAR and 7-Zip treat .jar files as regular zip archives.[/i] Method 2 — Command line (Windows, Linux, macOS) Run from the PZ root folder. Replace [b]path\to\sqliteModule[/b] with the actual Workshop mod path. [b]Windows:[/b] jar uf projectzomboid.jar ^ -C "path\to\sqliteModule\42\media\lua" zombie/Lua/LuaSQLite.class ^ -C "path\to\sqliteModule\42\media\lua" zombie/Lua/LuaManager.class ^ -C "path\to\sqliteModule\42\media\lua" "zombie/Lua/LuaManager$Exposer.class" ^ -C "path\to\sqliteModule\42\media\lua" "zombie/Lua/LuaManager$GlobalObject.class" ^ -C "path\to\sqliteModule\42\media\lua" "zombie/Lua/LuaManager$GlobalObject$1.class" ^ -C "path\to\sqliteModule\42\media\lua" "zombie/Lua/LuaManager$GlobalObject$LuaFileWriter.class" ^ -C "path\to\sqliteModule\42\media\lua" "zombie/Lua/LuaManager$GlobalObject$TimSortComparator.class" ^ -C "path\to\sqliteModule\42\media\lua" "zombie/Lua/LuaManager$GlobalObject$ItemQuery.class" ^ -C "path\to\sqliteModule\42\media\lua" "zombie/Lua/LuaManager$GlobalObject$ItemQueryJava.class" [b]Linux / macOS:[/b] jar uf projectzomboid.jar \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaSQLite.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager\$Exposer.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager\$GlobalObject.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager\$GlobalObject\$1.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager\$GlobalObject\$LuaFileWriter.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager\$GlobalObject\$TimSortComparator.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager\$GlobalObject\$ItemQuery.class \ -C "path/to/sqliteModule/42/media/lua" zombie/Lua/LuaManager\$GlobalObject\$ItemQueryJava.class Singleplayer vs Multiplayer [b]LuaSQLite works in singleplayer and multiplayer.[/b] Context isServer() isClient() Runs? Singleplayer true true YES MP host true true YES Dedicated server true false YES MP client false true NO Always add this at the top of your server scripts — it handles all cases correctly: if isClient() and not isServer() then return end [b]getAbsoluteSaveFolderName()[/b] resolves the correct save path automatically for both SP and MP. How to use (Lua) Place your script at [b]MyMod/media/lua/server/MyMod.lua[/b] if isClient() and not isServer() then return end local db = nil Events.OnInitGlobalModData.Add(function() db = LuaSQLite.open(getAbsoluteSaveFolderName("MyMod.db")) if not db then return end db:exec("PRAGMA journal_mode=DELETE") db:exec("PRAGMA synchronous=NORMAL") db:exec("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT)") end) -- INSERT / UPDATE / DELETE with parameters (? placeholders) db:execParams("INSERT OR REPLACE INTO kv VALUES (?, ?)", {"hp", "100"}) db:execParams("UPDATE kv SET value=? WHERE key=?", {"200", "hp"}) db:execParams("DELETE FROM kv WHERE key=?", {"hp"}) -- SELECT — rows.n is the count, rows[i].column_name is each field local rows = db:queryParams("SELECT * FROM kv WHERE key=?", {"hp"}) for i = 1, rows.n do print(rows[i].key, rows[i].value) end -- Transactions db:beginTransaction() db:execParams("INSERT INTO kv VALUES (?,?)", {"a","1"}) db:execParams("INSERT INTO kv VALUES (?,?)", {"b","2"}) db:commit() -- or db:rollback() db:close()[/code] Notes [list] [*] [b]Numbers come back as Double[/b] — use [b]math.floor()[/b] when you need an integer [*] [b]Do NOT use journal_mode=WAL[/b] — data won't appear in DB viewers until server shutdown. Use [b]journal_mode=DELETE[/b] [*] [b]getSteamID()[/b] may return empty in singleplayer — use [b]getUsername()[/b] as fallback [*] The connection is not closed automatically — call [b]db:close()[/b] on shutdown [*] If execParams returns -1, check the server console for the SQL error [/list] Compatibility [list] [*] Project Zomboid [b]Build 42[/b] [*] Singleplayer and Multiplayer [*] Works as a dependency for any mod — this is a library, not a gameplay mod [/list] Source Source available on GitHub. Two files changed: [b]LuaSQLite.java[/b] (new) + one line in [b]LuaManager.java[/b]. [i]Credit appreciated but not required.[/i][/i][/i][/i]