diff --git a/xpsave/xpsave.lua b/xpsave/xpsave.lua index 05184e7..1eb0e08 100755 --- a/xpsave/xpsave.lua +++ b/xpsave/xpsave.lua @@ -5,7 +5,7 @@ Website: http://www.etlegacy.com Mod: compatible with Legacy, but might also work with other mods - Description: this script saves users' experience points into + Description: this script saves users' experience points into a database and thus preserves them between connections ]]-- @@ -37,13 +37,13 @@ skills[LIGHTWEAPONS] = "Light weapons" skills[HEAVYWEAPONS] = "Heavy weapons" skills[COVERTOPS] = "Covert ops" --- database helper function --- returns database rows matching sql_statement -function rows(connection, sql_statement) - local cursor = assert (connection:execute (sql_statement)) - return function () - return cursor:fetch() - end +-- database helper function +-- returns database rows matching sql_statement +function rows(connection, sql_statement) + local cursor = assert (connection:execute (sql_statement)) + return function () + return cursor:fetch() + end end -- rows -- con:prepare with bind_names should be used to prevent sql injections @@ -56,7 +56,7 @@ function validateGUID(cno, guid) et.trap_SendServerCommand (cno, "cpm \"" .. "^3Your XP won't be saved because you have an invalid GUID!\n\"") return false end - + return true end @@ -64,38 +64,38 @@ end function saveXP(cno) local name = et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "name" ) local guid = et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "cl_guid" ) - + if not validateGUID(cno, guid) then return end - + cur = assert (con:execute(string.format("SELECT * FROM users WHERE guid='%s' LIMIT 1", guid))) local player = cur:fetch({}, 'a') - + if not player then - -- This should not happen + -- This should not happen et.G_Print ("^1ERROR: (XP Save) user was not found in the database!\n") return else et.trap_SendServerCommand (cno, "cpm \"" .. "^3See you again soon, ^7" .. name .. "\n\"") --for id, name in pairs(skills) do et.G_Print (name .. ": " .. et.gentity_get (cno, "sess.skillpoints", id) .. " XP\n") end - - cur = assert (con:execute(string.format([[UPDATE users SET - last_seen='%s', + + cur = assert (con:execute(string.format([[UPDATE users SET + last_seen='%s', xp_battlesense='%s', - xp_engineering='%s', - xp_medic='%s', - xp_fieldops='%s', - xp_lightweapons='%s', - xp_heavyweapons='%s', - xp_covertops='%s' - WHERE guid='%s']], - os.date("%Y-%m-%d %H:%M:%S"), - et.gentity_get (cno, "sess.skillpoints", BATTLESENSE), - et.gentity_get (cno, "sess.skillpoints", ENGINEERING), - et.gentity_get (cno, "sess.skillpoints", MEDIC), - et.gentity_get (cno, "sess.skillpoints", FIELDOPS), - et.gentity_get (cno, "sess.skillpoints", LIGHTWEAPONS), - et.gentity_get (cno, "sess.skillpoints", HEAVYWEAPONS), - et.gentity_get (cno, "sess.skillpoints", COVERTOPS), + xp_engineering='%s', + xp_medic='%s', + xp_fieldops='%s', + xp_lightweapons='%s', + xp_heavyweapons='%s', + xp_covertops='%s' + WHERE guid='%s']], + os.date("%Y-%m-%d %H:%M:%S"), + et.gentity_get (cno, "sess.skillpoints", BATTLESENSE), + et.gentity_get (cno, "sess.skillpoints", ENGINEERING), + et.gentity_get (cno, "sess.skillpoints", MEDIC), + et.gentity_get (cno, "sess.skillpoints", FIELDOPS), + et.gentity_get (cno, "sess.skillpoints", LIGHTWEAPONS), + et.gentity_get (cno, "sess.skillpoints", HEAVYWEAPONS), + et.gentity_get (cno, "sess.skillpoints", COVERTOPS), guid ))) end @@ -105,15 +105,15 @@ end function et_InitGame(levelTime, randomSeed, restart) -- register name of this module et.RegisterModname ("XP Save Module " .. version) - + -- create environement object env = assert (luasql.sqlite3()) -- connect to database - con = assert (env:connect("xpsave.sqlite")) - + con = assert (env:connect("xpsave.sqlite")) + --cur = assert (con:execute("DROP TABLE users")) - + cur = assert (con:execute[[ CREATE TABLE IF NOT EXISTS users( guid VARCHAR(64), @@ -125,16 +125,16 @@ function et_InitGame(levelTime, randomSeed, restart) xp_fieldops REAL, xp_lightweapons REAL, xp_heavyweapons REAL, - xp_covertops REAL, + xp_covertops REAL, UNIQUE (guid) ) ]]) - - cur = assert (con:execute("SELECT COUNT(*) FROM users")) - + + cur = assert (con:execute(string.format("SELECT COUNT(*) FROM users"))) + et.G_Print("XP Save: there are " .. tonumber(cur:fetch(row, 'a')) .. " users in the database\n") - + --et.G_Print ("^4List of users in XP Save database:\n") --for guid, date in rows (con, "SELECT * FROM users") do -- et.G_Print (string.format ("\tGUID %s was last seen on %s\n", guid, date)) @@ -150,27 +150,27 @@ function et_ShutdownGame(restart) local cs = et.trap_GetConfigstring(tonumber(et.CS_PLAYERS) + cno) if not cs or cs == "" then break end - + saveXP(cno) cno = cno + 1 end - - -- clean up - cur:close() - con:close() - env:close() + + -- clean up + cur:close() + con:close() + env:close() end -- et_ShutdownGame -- called when a client enters the game world function et_ClientBegin(cno) - local name = et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "name" ) + local name = et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "name" ) local guid = et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "cl_guid" ) - + if not validateGUID(cno, guid) then return end cur = assert (con:execute(string.format("SELECT * FROM users WHERE guid='%s'", guid))) local player = cur:fetch({}, 'a') - + if not player then -- First time we see this player et.trap_SendServerCommand (cno, "cpm \"" .. "^3Welcome, ^7" .. name .. "^3! You are playing on an XP save server\n\"") @@ -179,18 +179,18 @@ function et_ClientBegin(cno) et.trap_SendServerCommand (cno, "cpm \"" .. "^3Welcome back, ^7" .. name .. "^3! Your last connection was on " .. player.last_seen .. "\n\"") -- in db: player.name --et.G_Print ("Loading XP from database: " .. player.xp_battlesense .. " | " .. player.xp_engineering .. " | " .. player.xp_medic .. " | " .. player.xp_fieldops .. " | " .. player.xp_lightweapons .. " | " .. player.xp_heavyweapons .. " | " .. player.xp_covertops .. "\n\n") - - et.G_XP_Set (cno, player.xp_battlesense, BATTLESENSE, 0) - et.G_XP_Set (cno, player.xp_engineering, ENGINEERING, 0) - et.G_XP_Set (cno, player.xp_medic, MEDIC, 0) - et.G_XP_Set (cno, player.xp_fieldops, FIELDOPS, 0) - et.G_XP_Set (cno, player.xp_lightweapons, LIGHTWEAPONS, 0) - et.G_XP_Set (cno, player.xp_heavyweapons, HEAVYWEAPONS, 0) + + et.G_XP_Set (cno, player.xp_battlesense, BATTLESENSE, 0) + et.G_XP_Set (cno, player.xp_engineering, ENGINEERING, 0) + et.G_XP_Set (cno, player.xp_medic, MEDIC, 0) + et.G_XP_Set (cno, player.xp_fieldops, FIELDOPS, 0) + et.G_XP_Set (cno, player.xp_lightweapons, LIGHTWEAPONS, 0) + et.G_XP_Set (cno, player.xp_heavyweapons, HEAVYWEAPONS, 0) et.G_XP_Set (cno, player.xp_covertops, COVERTOPS, 0) - + et.G_Print (name .. "'s current XP levels:\n") - for id, skill in pairs(skills) do - et.G_Print ("\t" .. skill .. ": " .. et.gentity_get (cno, "sess.skillpoints", id) .. " XP\n") + for id, skill in pairs(skills) do + et.G_Print ("\t" .. skill .. ": " .. et.gentity_get (cno, "sess.skillpoints", id) .. " XP\n") end end end -- et_ClientBegin