diff --git a/ladm/core/commands.lua b/ladm/core/commands.lua new file mode 100644 index 0000000..3146068 --- /dev/null +++ b/ladm/core/commands.lua @@ -0,0 +1,9 @@ +Command = {} + +Command["hello"] = function() + et.G_Print ( "Hello, my friend.\n" ) +end + +Command["bye"] = function() + et.G_Print ( "Good bye, hope to see you again soon.\n" ) +end diff --git a/ladm/core/db.lua b/ladm/core/db.lua index f671f0e..396efff 100644 --- a/ladm/core/db.lua +++ b/ladm/core/db.lua @@ -3,7 +3,7 @@ env = {} -- environment object con = {} -- database connection cur = {} -- cursor -dofile("ladm.cfg") +dofile("legacy/ladm/ladm.cfg") -- 1) load the chosen driver -- 2) create environement object @@ -19,6 +19,9 @@ function db_init ( ) luasql = require "luasql.sqlite3" env = assert ( luasql.sqlite3() ) con = assert ( env:connect( dbdatabase .. ".sqlite" ) ) + else + print ( "Unsupported database driver. Please set either mysql or sqlite in the config file." ) + return end if not installed then db_create() end @@ -39,6 +42,7 @@ function db_rows ( connection, sql_statement ) end end -- rows +-- called only the first time ladm starts function db_create () print ( "INSTALLING DATABASE RECORDS" ) --cur = assert (con:execute( "DROP TABLE users" )) @@ -79,9 +83,8 @@ function db_create () local configfile = io.open ( "ladm.cfg", "a" ) configfile:write ( "\ninstalled = true\n" ) configfile:close() - --print ( "Done. Please remember to change the 'installed' variable in the ladm.cfg file to 'false'." ) - --et.G_Print ("^4List of users in XP Save database:\n") + --et.G_Print ("^4List of users in the 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)) --end diff --git a/ladm/core/user.lua b/ladm/core/user.lua index 0f0d888..112ad49 100644 --- a/ladm/core/user.lua +++ b/ladm/core/user.lua @@ -19,12 +19,24 @@ skills[COVERTOPS] = "Covert ops" -- con:prepare with bind_names should be used to prevent sql injections -- but it doesn't work on my version of luasql -function validateGUID(cno, guid) +-- cno is optional +-- TODO: log his ip +function validateGUID(guid, cno) -- allow only alphanumeric characters in guid if(string.match(guid, "%W")) then + if not cno then + cno = 0 + while cno < tonumber( et.trap_Cvar_Get( "sv_maxclients" ) ) do + local checkguid = et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "cl_guid" ) + if guid == checkguid then + break + end + cno = cno + 1 + end + end -- Invalid characters detected. We should probably drop this client - et.G_Print("^3WARNING: (XP Save) user with id " .. cno .. " has an invalid GUID: " .. guid .. "\n") - et.trap_SendServerCommand (cno, "cpm \"" .. "Your XP won't be saved because you have an invalid cl_guid.\n\"") + et.G_Print("^3WARNING: user with id " .. cno .. " has an invalid GUID: " .. guid .. "\n") + et.trap_SendServerCommand (cno, "cpm \"" .. "^1Your XP won't be saved because you have an invalid cl_guid.\n\"") return false end @@ -38,18 +50,17 @@ function saveXP(cno) if not validateGUID(cno, guid) then return end - cur = assert (con:execute(string.format("SELECT * FROM users WHERE guid='%s' LIMIT 1", guid))) + cur = assert (con:execute(string.format("SELECT * FROM %susers WHERE guid='%s' LIMIT 1", dbprefix, guid))) local player = cur:fetch({}, 'a') if not player then -- This should not happen - et.G_Print ("^1ERROR: (XP Save) user was not found in the database!\n") + et.G_Print ("^1ERROR: user was not found in the database!\n") return else - et.trap_SendServerCommand (cno, "cpm \"" .. "See you again soon, " .. 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 + cur = assert (con:execute(string.format([[UPDATE %susers SET last_seen='%s', xp_battlesense='%s', xp_engineering='%s', @@ -59,6 +70,7 @@ function saveXP(cno) xp_heavyweapons='%s', xp_covertops='%s' WHERE guid='%s']], + dbprefix, os.date("%Y-%m-%d %H:%M:%S"), et.gentity_get (cno, "sess.skillpoints", BATTLESENSE), et.gentity_get (cno, "sess.skillpoints", ENGINEERING), @@ -71,3 +83,10 @@ function saveXP(cno) ))) end end + +function getPlayerByGUID(guid) + if not validateGUID(guid) then return nil end + + cur = assert (con:execute(string.format("SELECT * FROM %susers WHERE guid='%s'", dbprefix, guid))) + return cur:fetch({}, 'a') -- player table or nil +end \ No newline at end of file diff --git a/ladm/ladm.cfg b/ladm/ladm.cfg index a6dfaf1..b14fae6 100644 --- a/ladm/ladm.cfg +++ b/ladm/ladm.cfg @@ -2,7 +2,8 @@ -- Configuration file for Legacy Admin Mod -- -debug = false +website = "http://etlegacy.com/stats" +debug = false -- Database dbdriver = "mysql" diff --git a/ladm/ladm.lua b/ladm/ladm.lua index 9910602..8d1ecd8 100755 --- a/ladm/ladm.lua +++ b/ladm/ladm.lua @@ -12,17 +12,16 @@ -- load the config file dofile "ladm.cfg" -require "core/db" - -db_init() +require "ladm/core/db" +require "ladm/core/user" +require "ladm/core/commands" function et_InitGame(levelTime, randomSeed, restart) -- name of this module et.RegisterModname ( "Lightweight administration suite for the Legacy mod" ) -- init db on game start - - + db_init() end -- et_InitGame function et_ShutdownGame(restart) @@ -49,21 +48,16 @@ end -- et_ShutdownGame function et_ClientBegin(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'", guid))) - local player = cur:fetch({}, 'a') + local player = getPlayerByGUID(guid) if not player then -- First time we see this player et.trap_SendServerCommand (cno, "cpm \"" .. "Welcome, " .. name .. "^7! You are playing on an XP save server.\n\"") - cur = assert (con:execute(string.format("INSERT INTO users VALUES ('%s', '%s', '%s', 0, 0, 0, 0, 0, 0, 0)", guid, os.date("%Y-%m-%d %H:%M:%S"), os.date("%Y-%m-%d %H:%M:%S")))) + cur = assert (con:execute(string.format("INSERT INTO %susers VALUES ('%s', '%s', '%s', 0, 0, 0, 0, 0, 0, 0)", dbprefix, guid, os.date("%Y-%m-%d %H:%M:%S"), os.date("%Y-%m-%d %H:%M:%S")))) else et.trap_SendServerCommand (cno, "cpm \"" .. "Welcome back, " .. name .. "^7! 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) @@ -74,7 +68,8 @@ function et_ClientBegin(cno) 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") + et.G_Print ("| " .. skill .. ": " .. et.gentity_get (cno, "sess.skillpoints", id) .. " XP ") + et.G_Print ("|\n") end end end -- et_ClientBegin @@ -82,3 +77,18 @@ end -- et_ClientBegin function et_ClientDisconnect(cno) saveXP(cno) end -- et_ClientDisconnect + +function et_ClientCommand(cno, cmd) + for cmd_name, cmd_function in pairs(Command) do + -- string.lower(et.trap_Argv(0)) + if cmd == cmd_name then + cmd_function() + return 1 + end + end +end -- et_ClientCommand + +-- testing +function et_ConsoleCommand(cmd) + et_ClientCommand(nil, cmd) +end -- et_ConsoleCommand \ No newline at end of file