From a172ad86c33cd6144e159a5d486d8193b64508bc Mon Sep 17 00:00:00 2001 From: Remy Marquis Date: Sat, 4 Mar 2017 20:01:56 +0100 Subject: [PATCH] removed obsolete scripts --- README.md | 19 +- ladm/core/commands.lua | 66 - ladm/core/db.lua | 116 -- ladm/core/user.lua | 110 -- ladm/ladm.cfg | 15 - ladm/ladm.lua | 98 -- ladm/ladm.sqlite | Bin 12288 -> 0 bytes noq/legacy_mods.cfg | 73 - noq/legacy_mods_names.cfg | 73 - noq/legacy_weapons.cfg | 65 - noq/legacy_weapons_names.cfg | 63 - noq/noq.lua | 2921 --------------------------------- noq/noq_c.lua | 177 -- noq/noq_commands.cfg | 136 -- noq/noq_config.cfg.sample | 42 - noq/noq_db.lua | 331 ---- noq/noq_greetings.cfg | 10 - noq/noq_i.lua | 409 ----- noq/noq_mods.cfg | 83 - noq/noq_mods_130.cfg | 84 - noq/noq_mods_names.cfg | 83 - noq/noq_mods_names_130.cfg | 84 - noq/noq_weapons.cfg | 74 - noq/noq_weapons_130.cfg | 75 - noq/noq_weapons_names.cfg | 71 - noq/noq_weapons_names_130.cfg | 72 - noq/nqconst.lua | 86 - noq/readme.txt | 18 - pm/pm.lua | 33 - rating/rating.lua | 370 ----- 30 files changed, 1 insertion(+), 5856 deletions(-) delete mode 100644 ladm/core/commands.lua delete mode 100644 ladm/core/db.lua delete mode 100644 ladm/core/user.lua delete mode 100644 ladm/ladm.cfg delete mode 100755 ladm/ladm.lua delete mode 100644 ladm/ladm.sqlite delete mode 100644 noq/legacy_mods.cfg delete mode 100644 noq/legacy_mods_names.cfg delete mode 100644 noq/legacy_weapons.cfg delete mode 100644 noq/legacy_weapons_names.cfg delete mode 100644 noq/noq.lua delete mode 100644 noq/noq_c.lua delete mode 100644 noq/noq_commands.cfg delete mode 100644 noq/noq_config.cfg.sample delete mode 100644 noq/noq_db.lua delete mode 100644 noq/noq_greetings.cfg delete mode 100644 noq/noq_i.lua delete mode 100644 noq/noq_mods.cfg delete mode 100644 noq/noq_mods_130.cfg delete mode 100644 noq/noq_mods_names.cfg delete mode 100644 noq/noq_mods_names_130.cfg delete mode 100644 noq/noq_weapons.cfg delete mode 100644 noq/noq_weapons_130.cfg delete mode 100644 noq/noq_weapons_names.cfg delete mode 100644 noq/noq_weapons_names_130.cfg delete mode 100644 noq/nqconst.lua delete mode 100644 noq/readme.txt delete mode 100644 pm/pm.lua delete mode 100755 rating/rating.lua diff --git a/README.md b/README.md index 0a731bf..bfcd595 100644 --- a/README.md +++ b/README.md @@ -22,27 +22,10 @@ * LuaSQL module with sqlite3 driver is required * The script could be tweaked to use file backend or other database drivers instead of sqlite3 -## noq (under construction) - -* Game manager, shrubbot and/or ET admin mod replacement -* LuaSQL module with sqlite3 or mysql driver are required - -## pm - private messages - -* use ```pm``` console command to send a private message to another player -* message is sent to the first matched player name -* player name is a colour and case-insensitive pattern, e.g. ton will match player /-^321ToN-/ -* usage: pm player Hello, how are you? - -## ladm - lightweight administration suite - -* NOTE: not even alpha state. Do not use. -* manage users on your server - ## announcehp * Killer's HP is displayed to their victims. - + # Notes * Please always add modname and version to your lua script ``` diff --git a/ladm/core/commands.lua b/ladm/core/commands.lua deleted file mode 100644 index 933c209..0000000 --- a/ladm/core/commands.lua +++ /dev/null @@ -1,66 +0,0 @@ -require "core/user" -require "core/db" - -Command = {} - --- Heads or tails -Command["cointoss"] = function(cno, cmd) - local player = getPlayerName( cno ) - local number = math.random( 0, 99 ) - - math.randomseed( os.time() ) - - et.G_Print( "cointoss: " .. player .. " " .. number .. "\n" ) - - et.trap_SendServerCommand ( -1, "chat \"" .. player .. "^7 tossed a coin...\"" ) - - if number < 49 then - et.trap_SendServerCommand ( -1, "chat \"Heads.\"" ) - elseif number > 50 then - et.trap_SendServerCommand ( -1, "chat \"Tails.\"" ) - elseif number == 49 then - et.trap_SendServerCommand ( -1, "chat \"The coin falls on its side!\"" ) - elseif number == 50 then - et.trap_SendServerCommand ( -1, "chat \"A gypsy stole the coin.\"" ) - end -end - --- Private message -Command["pm"] = function(cno, cmd) - if tonumber( et.trap_Argc() ) < 3 then - et.trap_SendServerCommand( cno, "chat \"Usage: pm name message\"" ) - return(1) - end - - local recipient_name = string.lower( et.Q_CleanStr( et.trap_Argv(1) ) ) - - if recipient_name then - for i=0, tonumber( et.trap_Cvar_Get( "sv_maxclients" ) )-1 do - local player_name = getPlayerName( i ) - - if player_name then - local sender_name = getPlayerName( cno ) - s, e = string.find( string.lower( et.Q_CleanStr( player_name ) ), recipient_name ) - if s and e then - if i ~= cno then -- PMing yourself? - et.trap_SendServerCommand( i, "chat \"" .. sender_name .. "^7 -> " .. player_name .. "^7: ^5" .. et.ConcatArgs(2) .. "\"" ) - et.trap_SendServerCommand( cno, "chat \"" .. sender_name .. "^7 -> " .. player_name .. "^7: ^5" .. et.ConcatArgs(2) .. "\"" ) - return(1) -- send only to the first player matched - end - end - end - end - et.trap_SendServerCommand( cno, "chat \"No player whose name matches the pattern \'" .. recipient_name .. "\' was found.\"" ) - return(1) - end -end - --- List users -Command["users"] = function(cno, cmd) - et.G_Print ("^4List of users in the database:\n") - for guid, nick, first_seen, last_seen, privilege, xp_battlesense, xp_engineering, xp_medic, xp_fieldops, xp_lightweapons, xp_heavyweapons, xp_covertops - in db_rows ( con, string.format ( [[ SELECT * FROM %susers ORDER BY nick DESC ]], dbprefix ) ) do - et.G_Print (string.format ( "\t%s is a level %i user who was last seen on %s and has a total of %i XP\n", - nick, privilege, last_seen, (xp_battlesense + xp_engineering + xp_medic + xp_fieldops + xp_lightweapons + xp_heavyweapons + xp_covertops) ) ) - end -end diff --git a/ladm/core/db.lua b/ladm/core/db.lua deleted file mode 100644 index 49b0d9f..0000000 --- a/ladm/core/db.lua +++ /dev/null @@ -1,116 +0,0 @@ -luasql = {} -- sql driver -env = {} -- environment object -con = {} -- database connection -cur = {} -- cursor - -dofile(et.trap_Cvar_Get("fs_basepath") .. "/" .. et.trap_Cvar_Get("fs_game") .. "/ladm/ladm.cfg") - --- 1) load the chosen driver --- 2) create environement object --- 3) connect to database -function db_init ( ) - et.G_Print ( "Connecting to " .. dbdriver .. " database...\n" ) - - if ( dbdriver == "mysql" ) then - luasql = require "luasql.mysql" - env = assert ( luasql.mysql() ) - con = assert ( env:connect( dbdatabase, dbuser, dbpassword, dbhost, dbport ) ) - elseif ( dbdriver == "sqlite" or dbdriver == "sqlite3" ) then - luasql = require "luasql.sqlite3" - env = assert ( luasql.sqlite3() ) - con = assert ( env:connect( dbdatabase .. ".sqlite" ) ) - --elseif ( dbdriver == "postgres") then - -- luasql = require "luasql.postgres" - -- env = assert ( luasql.postgres() ) - -- con = assert ( env:connect( dbdatabase, ... ) ) - else - print ( "Unsupported database driver. Please set either mysql or sqlite in the config file." ) - return - end - - if not installed then db_create() end - - cur = assert ( con:execute ( string.format ( "SELECT COUNT(*) FROM %susers", dbprefix ) ) ) - et.G_Print("There are " .. tonumber(cur:fetch(row, 'a')) .. " users in the database.\n") - - cur = assert ( con:execute ( string.format ( "SELECT COUNT(*) FROM %svariables", dbprefix ) ) ) - et.G_Print("There are " .. tonumber(cur:fetch(row, 'a')) .. " variables in the database.\n") -end - --- database helper function --- returns database rows matching sql_statement -function db_rows ( connection, sql_statement ) - local cursor = assert (connection:execute (sql_statement)) - return function () - return cursor:fetch() - end -end -- rows - --- called only the first time ladm starts -function db_create () - - et.G_Print ( "^5ladm(sql): installing initial databases\n" ) - -- cur = assert ( con:execute ( string.format ( [[ DROP TABLE %susers ]], dbprefix ) ) ) - - cur = assert ( con:execute ( string.format ( [[ - CREATE TABLE IF NOT EXISTS %susers( - guid VARCHAR(64), - nick VARCHAR(64), - first_seen VARCHAR(64), - last_seen VARCHAR(64), - - privilege INT(11), - - xp_battlesense REAL, - xp_engineering REAL, - xp_medic REAL, - xp_fieldops REAL, - xp_lightweapons REAL, - xp_heavyweapons REAL, - xp_covertops REAL, - - UNIQUE (guid) - ); - ]], dbprefix ) ) ) - - -- incompatible sqlite/mysql syntax - if ( dbdriver == "sqlite" or dbdriver == "sqlite3" ) then - sql_ai = "" -- no need as the PRIMARY KEY column is incremented automatically - else - sql_ai = "AUTO_INCREMENT" - end - - cur = assert ( con:execute ( string.format ( [[ - CREATE TABLE IF NOT EXISTS %svariables( - id INT(11) NOT NULL %s, - type VARCHAR(128) NOT NULL, - name VARCHAR(128) NOT NULL, - value VARCHAR(128) NOT NULL, - description TEXT NOT NULL, - - PRIMARY KEY (id), - UNIQUE (name) - ); - ]], dbprefix, sql_ai ) ) ) - - local file, len = et.trap_FS_FOpenFile( "ladm/ladm.cfg", 2 ) - - if len == -1 then - -- TODO: log this - et.G_Printf("failed to open %s\n", file) - return - end - - local text = "\ninstalled = true\n" - et.trap_FS_Write(text, string.len(text), file) - et.trap_FS_FCloseFile(file) - - --local configfile = io.open ( "ladm.cfg", "a" ) - --configfile:write ( "\ninstalled = true\n" ) - --configfile:close() - - --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 -end \ No newline at end of file diff --git a/ladm/core/user.lua b/ladm/core/user.lua deleted file mode 100644 index 876b983..0000000 --- a/ladm/core/user.lua +++ /dev/null @@ -1,110 +0,0 @@ - --- skill identifiers -BATTLESENSE = 0 -ENGINEERING = 1 -MEDIC = 2 -FIELDOPS = 3 -LIGHTWEAPONS = 4 -HEAVYWEAPONS = 5 -COVERTOPS = 6 - -skills = {} -skills[BATTLESENSE] = "Battlesense" -skills[ENGINEERING] = "Engineering" -skills[MEDIC] = "Medic" -skills[FIELDOPS] = "Field ops" -skills[LIGHTWEAPONS] = "Light weapons" -skills[HEAVYWEAPONS] = "Heavy weapons" -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 --- 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: 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 - - return true -end - --- saves XP values of a player with id 'cno' into sqlite database -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 %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: user was not found in the database!\n") - return - else - --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 %susers SET - nick='%s', - 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']], - dbprefix, - name, - 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 -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 - -function getPlayerName(id) - local name - - if not id or not (id >= 0 or id < tonumber(et.trap_Cvar_Get("sv_maxclients"))) and not (id == 999) then - return nil - end - - if id == 999 then - name = "^JServer" - else - name = et.gentity_get( id, "pers.netname" ) - end - - return name -end \ No newline at end of file diff --git a/ladm/ladm.cfg b/ladm/ladm.cfg deleted file mode 100644 index b14fae6..0000000 --- a/ladm/ladm.cfg +++ /dev/null @@ -1,15 +0,0 @@ --- --- Configuration file for Legacy Admin Mod --- - -website = "http://etlegacy.com/stats" -debug = false - --- Database -dbdriver = "mysql" -dbport = 3306 -dbhost = "localhost" -dbdatabase = "legacy_server" -dbprefix = "legacy_" -dbuser = "legacy_user" -dbpassword = "test" \ No newline at end of file diff --git a/ladm/ladm.lua b/ladm/ladm.lua deleted file mode 100755 index 6a3d0e0..0000000 --- a/ladm/ladm.lua +++ /dev/null @@ -1,98 +0,0 @@ ---[[ - Author: Jan Šimek [Radegast] - Version 0.1 - License: MIT - Released on 09.02.2014 - Website: http://www.etlegacy.com - Mod: intended for the Legacy mod - - Description: lightweight user administration suite -]]-- - -package.path = "./" .. et.trap_Cvar_Get("fs_game") .. "/ladm/?.lua;" .. package.path - --- load the config file -dofile ("./" .. et.trap_Cvar_Get("fs_game") .. "/ladm/ladm.cfg") - -require "core/db" -require "core/user" -require "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) - local cno = 0 - local maxclients = tonumber(et.trap_Cvar_Get("sv_maxclients")) - - -- iterate through clients and save their XP - while cno < maxclients do - local cs = et.trap_GetConfigstring(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() -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 guid = et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "cl_guid" ) - - 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 %susers VALUES ( - '%s', '%s', '%s', '%s', 0, 0, 0, 0, 0, 0, 0, 0 - )]], dbprefix, guid, name, 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_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 ("| " .. skill .. ": " .. et.gentity_get (cno, "sess.skillpoints", id) .. " XP |\n") - --end - end -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(cno, cmd) - return 1 - end - end -end -- et_ClientCommand - --- testing -function et_ConsoleCommand(cmd) - et_ClientCommand(999, cmd) -end -- et_ConsoleCommand \ No newline at end of file diff --git a/ladm/ladm.sqlite b/ladm/ladm.sqlite deleted file mode 100644 index f3495ed45b8e79e76ba601f866c34d77088ad5ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI#&q~8E90%}p4yA+rx%HZhu%aHsKR3ZD1%)AOZeB~b{?-M$bT-+XSMg2uM81O0 z;lZXbp*YwB^czUS@Ao5V^Jy-5?)QWyK25WEsQCr!Fw0`MoHNF(ydUI!+e}>F2Ki{> zea&KL-^b1N5398{thH%>?VEr)1Rwwb2tWV=5P$##AOHafR94{Q#5!^u$NId|;W(kC zqD&Q!+Wo-yhCUy9cRimMscyrz?RY67{^AYpAG|^L`qDi$$*IVc4iu66S4zU26*FtS z2*#n-2`Q3_c>ca#v09!d84F322^p92bBe^Il$i=jqI983$wb66{YK#;mF2>W!qxk( z!X#Z$rvKKl8|DK?PmleP&%0*NZk}-6+M#pfSWL)>*6KCMZ}&mC)M*h11yXQc4CZcM zZ<=G(sqERp#vuR!2tWV=5P$##AOHafKmY=j5NMcP;{IQWe~nE-00Izz00bZa0SG_< L0uX>ebp?I_g=}wo diff --git a/noq/legacy_mods.cfg b/noq/legacy_mods.cfg deleted file mode 100644 index b189329..0000000 --- a/noq/legacy_mods.cfg +++ /dev/null @@ -1,73 +0,0 @@ --- put this file into your legacy path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - [0]="MOD_UNKNOWN", - "MOD_MACHINEGUN", - "MOD_BROWNING", - "MOD_MG42", - "MOD_GRENADE", - "MOD_KNIFE", - "MOD_LUGER", - "MOD_COLT", - "MOD_MP40", - "MOD_THOMPSON", - "MOD_STEN", - "MOD_GARAND", - "MOD_SILENCER", - "MOD_FG42", - "MOD_FG42SCOPE", - "MOD_PANZERFAUST", - "MOD_GRENADE_LAUNCHER", - "MOD_FLAMETHROWER", - "MOD_GRENADE_PINEAPPLE", - "MOD_MAPMORTAR", - "MOD_MAPMORTAR_SPLASH", - "MOD_KICKED", - "MOD_DYNAMITE", - "MOD_AIRSTRIKE", - "MOD_SYRINGE", - "MOD_AMMO", - "MOD_ARTY", - "MOD_WATER", - "MOD_SLIME", - "MOD_LAVA", - "MOD_CRUSH", - "MOD_TELEFRAG", - "MOD_FALLING", - "MOD_SUICIDE", - "MOD_TARGET_LASER", - "MOD_TRIGGER_HURT", - "MOD_EXPLOSIVE", - "MOD_CARBINE", - "MOD_KAR98", - "MOD_GPG40", - "MOD_M7", - "MOD_LANDMINE", - "MOD_SATCHEL", - "MOD_SMOKEBOMB", - "MOD_MOBILE_MG42", - "MOD_SILENCED_COLT", - "MOD_GARAND_SCOPE", - "MOD_CRUSH_CONSTRUCTION", - "MOD_CRUSH_CONSTRUCTIONDEATH", - "MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER", - "MOD_K43", - "MOD_K43_SCOPE", - "MOD_MORTAR", - "MOD_AKIMBO_COLT", - "MOD_AKIMBO_LUGER", - "MOD_AKIMBO_SILENCEDCOLT", - "MOD_AKIMBO_SILENCEDLUGER", - "MOD_SMOKEGRENADE", - "MOD_SWAP_PLACES", - "MOD_SWITCHTEAM", - "MOD_SHOVE", - "MOD_KNIFE_KABAR", - "MOD_MOBILE_BROWNING", - "MOD_MORTAR2", - "MOD_BAZOOKA", - "MOD_NUM_MODS", -}, -} diff --git a/noq/legacy_mods_names.cfg b/noq/legacy_mods_names.cfg deleted file mode 100644 index 43e2666..0000000 --- a/noq/legacy_mods_names.cfg +++ /dev/null @@ -1,73 +0,0 @@ --- put this file into your legacy path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - MOD_UNKNOWN=0, - MOD_MACHINEGUN=1, - MOD_BROWNING=2, - MOD_MG42=3, - MOD_GRENADE=4, - MOD_KNIFE=5, - MOD_LUGER=6, - MOD_COLT=7, - MOD_MP40=8, - MOD_THOMPSON=9, - MOD_STEN=10, - MOD_GARAND=11, - MOD_SILENCER=12, - MOD_FG42=13, - MOD_FG42SCOPE=14, - MOD_PANZERFAUST=15, - MOD_GRENADE_LAUNCHER=16, - MOD_FLAMETHROWER=17, - MOD_GRENADE_PINEAPPLE=18, - MOD_MAPMORTAR=19, - MOD_MAPMORTAR_SPLASH=20, - MOD_KICKED=21, - MOD_DYNAMITE=22, - MOD_AIRSTRIKE=23, - MOD_SYRINGE=24, - MOD_AMMO=25, - MOD_ARTY=26, - MOD_WATER=27, - MOD_SLIME=28, - MOD_LAVA=29, - MOD_CRUSH=30, - MOD_TELEFRAG=31, - MOD_FALLING=32, - MOD_SUICIDE=33, - MOD_TARGET_LASER=34, - MOD_TRIGGER_HURT=35, - MOD_EXPLOSIVE=36, - MOD_CARBINE=37, - MOD_KAR98=38, - MOD_GPG40=39, - MOD_M7=40, - MOD_LANDMINE=41, - MOD_SATCHEL=42, - MOD_SMOKEBOMB=43, - MOD_MOBILE_MG42=44, - MOD_SILENCED_COLT=45, - MOD_GARAND_SCOPE=46, - MOD_CRUSH_CONSTRUCTION=47, - MOD_CRUSH_CONSTRUCTIONDEATH=48, - MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER=49, - MOD_K43=50, - MOD_K43_SCOPE=51, - MOD_MORTAR=52, - MOD_AKIMBO_COLT=53, - MOD_AKIMBO_LUGER=54, - MOD_AKIMBO_SILENCEDCOLT=55, - MOD_AKIMBO_SILENCEDLUGER=56, - MOD_SMOKEGRENADE=57, - MOD_SWAP_PLACES=58, - MOD_SWITCHTEAM=59, - MOD_SHOVE=60, - MOD_KNIFE_KABAR=61, - MOD_MOBILE_BROWNING=62, - MOD_MORTAR2=63, - MOD_BAZOOKA=64, - MOD_NUM_MODS=65, -}, -} diff --git a/noq/legacy_weapons.cfg b/noq/legacy_weapons.cfg deleted file mode 100644 index e828b71..0000000 --- a/noq/legacy_weapons.cfg +++ /dev/null @@ -1,65 +0,0 @@ --- put this file into your legacy path (fs_homepath) --- never change values here unless you exactly know what you are doing - --- TODO: We can use better names here - -return { --- Table: {1} -{ - [0]="WP_NONE", - "WP_KNIFE", - "WP_LUGER", - "WP_MP40", - "WP_GRENADE_LAUNCHER", - "WP_PANZERFAUST", - "WP_FLAMETHROWER", - "WP_COLT", - "WP_THOMPSON", - "WP_GRENADE_PINEAPPLE", - "WP_STEN", - "WP_MEDIC_SYRINGE", - "WP_AMMO", - "WP_ARTY", - "WP_SILENCER", - "WP_DYNAMITE", - "WP_SMOKETRAIL", - "WP_MAPMORTAR", - "VERYBIGEXPLOSION", - "WP_MEDKIT", - "WP_BINOCULARS", - "WP_PLIERS", - "WP_SMOKE_MARKER", - "WP_KAR98", - "WP_CARBINE", - "WP_GARAND", - "WP_LANDMINE", - "WP_SATCHEL", - "WP_SATCHEL_DET", - "WP_SMOKE_BOMB", - "WP_MOBILE_MG42", - "WP_K43", - "WP_FG42", - "WP_DUMMY_MG42", - "WP_MORTAR", - "WP_AKIMBO_COLT", - "WP_AKIMBO_LUGER", - "WP_GPG40", - "WP_M7", - "WP_SILENCED_COLT", - "WP_GARAND_SCOPE", - "WP_K43_SCOPE", - "WP_FG42SCOPE", - "WP_MORTAR_SET", - "WP_MEDIC_ADRENALINE", - "WP_AKIMBO_SILENCEDCOLT", - "WP_AKIMBO_SILENCEDLUGER", - "WP_MOBILE_MG42_SET", - "WP_KNIFE_KABAR", - "WP_MOBILE_BROWNING", - "WP_MOBILE_BROWNING_SET", - "WP_MORTAR2", - "WP_MORTAR2_SET", - "WP_BAZOOKA", - "WP_NUM_WEAPONS", -}, -} \ No newline at end of file diff --git a/noq/legacy_weapons_names.cfg b/noq/legacy_weapons_names.cfg deleted file mode 100644 index 4491379..0000000 --- a/noq/legacy_weapons_names.cfg +++ /dev/null @@ -1,63 +0,0 @@ --- put this file into your legacy path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - WP_NONE=0, - WP_KNIFE=1, - WP_LUGER=2, - WP_MP40=3, - WP_GRENADE_LAUNCHER=4, - WP_PANZERFAUST=5, - WP_FLAMETHROWER=6, - WP_COLT=7, - WP_THOMPSON=8, - WP_GRENADE_PINEAPPLE=9, - WP_STEN=10, - WP_MEDIC_SYRINGE=11, - WP_AMMO=12, - WP_ARTY=13, - WP_SILENCER=14, - WP_DYNAMITE=15, - WP_SMOKETRAIL=16, - WP_MAPMORTAR=17, - VERYBIGEXPLOSION=18, - WP_MEDKIT=19, - WP_BINOCULARS=20, - WP_PLIERS=21, - WP_SMOKE_MARKER=22, - WP_KAR98=23, - WP_CARBINE=24, - WP_GARAND=25, - WP_LANDMINE=26, - WP_SATCHEL=27, - WP_SATCHEL_DET=28, - WP_SMOKE_BOMB=29, - WP_MOBILE_MG42=30, - WP_K43=31, - WP_FG42=32, - WP_DUMMY_MG42=33, - WP_MORTAR=34, - WP_AKIMBO_COLT=35, - WP_AKIMBO_LUGER=36, - WP_GPG40=37, - WP_M7=38, - WP_SILENCED_COLT=39, - WP_GARAND_SCOPE=40, - WP_K43_SCOPE=41, - WP_FG42SCOPE=42, - WP_MORTAR_SET=43, - WP_MEDIC_ADRENALINE=44, - WP_AKIMBO_SILENCEDCOLT=45, - WP_AKIMBO_SILENCEDLUGER=46, - WP_MOBILE_MG42_SET=47, - WP_KNIFE_KABAR=48, - WP_MOBILE_BROWNING=49, - WP_MOBILE_BROWNING_SET=50, - WP_MORTAR2=51, - WP_MORTAR2_SET=52, - WP_BAZOOKA=53, - WP_NUM_WEAPONS=54, - -}, -} \ No newline at end of file diff --git a/noq/noq.lua b/noq/noq.lua deleted file mode 100644 index 19e54a0..0000000 --- a/noq/noq.lua +++ /dev/null @@ -1,2921 +0,0 @@ --- The NOQ - No Quarter Lua next generation game manager --- --- A Shrubbot replacement and also kind of new game manager and tracking system based on mysql or sqlite3. --- Both are supported and in case of sqlite there is no extra sqlite installation needed. Use with NQ 1.2.9 and later only! --- --- NQ Lua team 2009-2011 - No warranty :) - --- NQ Lua team is: --- ailmanki --- BubbaG1 --- Hose --- IlDuca --- IRATA [*] --- Luborg - --- Webpage: http://dev.kernwaffe.de/projects/noq/ --- Wiki: http://dev.kernwaffe.de/projects/noq/wiki/ --- --- Please don't do any posts related to this script to the NQ forums - --- Setup: --- - Make sure all required Lua SQL libs are on server and run properly. --- For MySQL dbms you need the additional lib in the path. --- - If you want to use sqlite make sure your server instance has write permissions in fs_homepath. --- SQLite will create a file "noquarter.sqlite" at this location. --- --- - Copy the content of this path to fs_homepath/fs_game/nq/noq --- - for example /home//.etlegacy/legacy/noq (default case if fs_homepath is not set by admin) --- --- - Set lua_modules "noq/noq.lua noq/noq_i.lua" --- --- - Make the config your own. There is no need to change code in the NOQ. If you want to see changes use the forum --- - Restart the server and check if all lua_modules noq_i.lua, noq_c.lua (optional) and noq.lua are registered. --- - Call /rcon !sqlcreate - Done. Your system is set up - you should remove noq_i.lua from lua_modules now. --- --- NOQ basic files: --- noq_i.lua - Install script remove after install --- noq_c.lua - Additional tool to enter sql cmds on the ET console --- noq_config.cfg - Stores all data to run & control the NOQ. Make this file your own! --- noq_commands.cfg - Commands definition file - Make this file your own! --- --- legacy_mods_names_.cfg - Methods of death enum file - never touch! --- legacy_mods_.cfg - Methods of death enum file - never touch! --- legacy_weapons_.cfg - Weapon enum config file - never touch! --- legacy_weapons_names_.cfg - Weapon enum config file - never touch! --- --- nqconst.lua - No Quarter constants --- legacyconst.lua - legacy constants --- noq_db.lua - No Quarter DB functions --- - --- Note: --- Again - you don't have to modyfiy any code in this script. If you disagree contact the dev team. - - --- FIXME legacy mod --- et.G_shrubbot_level(_clientNum) (keep for NQ) - -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- - --- SCRIPT VARS - don't touch ! - -------------------------------------------------------------------------------- - --- LUA module version -version = "1" -- see version table // FIXME: version is an int ! -> version = 1 - --- TODO get from 'version' cvar '/' for linux/mac, '\' for win -pathSeparator = "/" - -homepath = et.trap_Cvar_Get("fs_homepath") .. pathSeparator -fs_game = et.trap_Cvar_Get("fs_game") .. pathSeparator -pbpath = homepath .. "pb" .. pathSeparator -noqpath = "noq" .. pathSeparator -scriptpath = homepath .. fs_game .. noqpath -- full qualified path for the NOQ scripts - -------------------------------------------------------------------------------- --- table functions - don't move down! -------------------------------------------------------------------------------- - --- The table load -function table.load( sfile ) - -- catch marker for stringtable - if string.sub( sfile,-3,-1 ) == "--|" then - tables,err = loadstring( sfile ) - else - tables,err = loadfile( sfile ) - end - if err then return _,err - end - tables = tables() - for idx = 1,#tables do - local tolinkv,tolinki = {},{} - for i,v in pairs( tables[idx] ) do - if type( v ) == "table" and tables[v[1]] then - table.insert( tolinkv,{ i,tables[v[1]] } ) - end - if type( i ) == "table" and tables[i[1]] then - table.insert( tolinki,{ i,tables[i[1]] } ) - end - end - -- link values, first due to possible changes of indices - for _,v in ipairs( tolinkv ) do - tables[idx][v[1]] = v[2] - end - -- link indices - for _,v in ipairs( tolinki ) do - tables[idx][v[2]],tables[idx][v[1]] = tables[idx][v[1]],nil - end - end - return tables[1] -end - - --- table helper -function debug_getInfoFromTable( _table ) - -- table.sort(cvartable) - debugPrint("log","************************") - for k,v in pairs(_table) do debugPrint("log",k .. "=" .. v) end - debugPrint("log","************************") - -- setn not set so empty - -- et.G_Print("size:" .. table.getn(cvartable) .. "\n") -end --- table functions end - -------------------------------------------------------------------------------- --- debugPrint --- Helper function to print to log --- target: can be 'cpm','print','logprint'? --- TODO: extend to be able to print variables recursively out --- TODO: http://lua-users.org/wiki/SwitchStatement ? -------------------------------------------------------------------------------- -function debugPrint( target, msg ) - if debug ~= 0 then - - local lmsg = "[DBG] " .. msg .. "\n" - local lcmsg = "^7[DBG] " .. color .. msg .. "\n" - - if target == "cpm" then - et.trap_SendServerCommand( -1 ,"cpm \"" .. lcmsg .. "\"") - - -- elseif target == "cpmnow" then - -- et.trap_SendConsoleCommand(et.EXEC_NOW , "cpm \"" .. lcmsg .. "\"" ) - - elseif target == "print" then - et.G_Print( lcmsg ) - - elseif target == "logprint" then - et.G_LogPrint( lmsg ) - - -- elseif slot[target] ~= nil then - end - end -end - --- at first we need to check for the modversion - -modname = et.trap_Cvar_Get( "gamename" ) -modprefix = "" - -if modname == "nq" then --- TODO: check for version incompatibilities... ---version = et.trap_Cvar_Get( cvarname ) - modprefix = "noq" -elseif modname == "legacy" then - modprefix = "legacy" -end - -et.G_LogPrint("Loading NOQ config files from ".. scriptpath.."\n") -noqvartable = assert(table.load( scriptpath .. "noq_config.cfg")) --- TODO: check if we can do this in total 2 tables -meansofdeath = assert(table.load( scriptpath .. modprefix .. "_mods.cfg")) -- all MODS -weapons = assert(table.load( scriptpath .. modprefix .. "_weapons.cfg")) -- all weapons -mod = assert(table.load( scriptpath .. modprefix .. "_mods_names.cfg")) -- mods by name -w = assert(table.load( scriptpath .. modprefix .. "_weapons_names.cfg")) -- weapons by name --- end TODO -greetings = assert(table.load( scriptpath .. "noq_greetings.cfg")) -- all greetings, customize as wished -et.G_LogPrint("NOQ config files loaded.\n") -tkweight = {} -- TODO: external table - --- Gets varvalue else null -function getConfig ( varname ) - local value = noqvartable[varname] - - if value then - return value - else - et.G_Print("warning, invalid config value for " .. varname .. "\n") - return "null" - end -end - --- don't get often used vars from noqvartable ... - -databasecheck = tonumber((getConfig("useDB"))) -- Is DB on? -mail = tonumber((getConfig("mail"))) -- Is Mail on? -recordbots = tonumber(getConfig("recordbots")) -- don't write session for bots -color = getConfig("color") -commandprefix = getConfig("commandprefix") -debug = tonumber(getConfig("debug")) -- debug 0/1 --- moved to noq_db.lua --- debugquerries = tonumber(getConfig("debugquerries")) -usecommands = tonumber(getConfig("usecommands")) -- are commands on? -xprestore = tonumber(getConfig("xprestore")) -- is xprestore on? -pussyfact = tonumber(getConfig("pussyfactor")) -lognames = tonumber(getConfig("lognames")) -nextmapVoteTime = tonumber(getConfig("nextmapVoteSec")) -evenerdist = tonumber(getConfig("evenerCheckallSec")) -polldist = tonumber(getConfig("polldistance")) -- time in seconds between polls, -1 to disable -maxSelfKills = tonumber(getConfig("maxSelfKills")) -- Selfkill restriction: -1 to disable -serverid = et.trap_Cvar_Get( "servid" ) -- Unique Server Identifier -if serverid == "" then - serverid = getConfig("serverID") -- Unique Server Identifier -end -irchost = getConfig("irchost") -ircport = tonumber(getConfig("ircport")) - --- disable the !force command hardcoded. -disableforce = false - - --- Prints the configuration -debug_getInfoFromTable(noqvartable) - ---[[----------------------------------------------------------------------------- --- DOCU of Datastructurs in this script --- --- The table slot[clientNum] is created each time someone connects and will store the current client information --- The current fields are(with default values): --- --- ["team"] = false --- --- ["id"] = nil --- ["pkey"] = 0 --- ["conname"] = row.conname --- ["regname"] = row.regname --- ["netname"] = row.netname --- ["isBot"] = 0 --- ["clan"] = 0 --- ["level"] = 0 --- ["flags"] = '' --- ["user"] = 0 --- ["password"] = 0 --- ["email"] = 0 --- ["banreason"] = 0 --- ["bannedby"] = 0 --- ["banexpire"] = 0 --- ["mutedreason"] = 0 --- ["mutedby"] = 0 --- ["muteexpire"] = 0 --- ["warnings"] = 0 --- ["suspect"] = 0 --- ["regdate"] = 0 --- ["updatedate"] = 0 --- ["createdate"] = 0 --- ["session"] -- last used or in use session see table session.id // was client["id"] before! --- ["ip"] = 0 --- ["valid "] -- not used in script only written into db if player enters for real --- ["start"] = 0 --- ["end"] = 0 -- not used in script only written into db --- ["axtime"] = 0 --- ["altime"] = 0 --- ["sptime"] = 0 --- ["lctime"] = 0 --- ["sstime"] = 0 --- ["xp0"] = 0 --- ["xp1"] = 0 --- ["xp2"] = 0 --- ["xp3"] = 0 --- ["xp4"] = 0 --- ["xp5"] = 0 --- ["xp6"] = 0 --- ["xptot"] = 0 --- ["acc"] = 0 --- ["kills"] = 0 --- ["tkills"] = 0 teamkills you did --- ["tkilled"] = 0 the amount you got teamkilled --- ["death"] = 0 --- ["uci"] = 0 --- ["inuse"] = false/true --- Added Fields during ingame session in slot[clientNum] --- --- slot[clientNum]["victim"] = last victim of clientNum(ID) --- slot[clientNum]["killwep"] = Name of the weapon last used to kill --- slot[clientNum]["killer"] = last person who killed clientNum(ID) --- slot[clientNum]["deadwep"] = Name of the weapon by wich he was killed last --- slot[clientNum]["lastTeamChange"] -- in seconds --- slot[clientNum]["selfkills"] Selfkills you did --- ---]] - --- This is above mentioned table -slot = {} - --- Note: Players are ents 0 - (sv_maxclients-1) -maxclients = tonumber(et.trap_Cvar_Get("sv_maxclients"))-1 -- add 1 again if used in view - --- We do this for accessing the table with [][] syntax, dirty but it works -for i=0, maxclients, 1 do - slot[i] = {} - slot[i]["inuse"] = false -end - --- command table, initialised in parseconf -commands = {} - ---[[ ---For testing, the !owned known from ETadmin -commands['cmd'][0]['owned'] = "print ^1Ha^3ha^5ha^3, i owned ^7^3 with my ^7^7!!!" -commands['cmd'][0]['pants'] = "print ^1No^3no^5noooo^7, i was killed by ^3^7 with a ^3^7!!!" -commands['cmd'][0]['parsecmds'] = "$LUA$ parseconf()" -commands['cmd'][0]['pussyfactor'] = "$LUA$ pussyout()" -commands['cmd'][0]['spectime'] = "$LUA$ time = slot[_clientNum]['sptime']; et.trap_SendServerCommand(et.EXEC_APPEND , 'print \"..time.. \" seconds in spec')" -commands['cmd'][0]['axtime'] = "$LUA$ time = slot[_clientNum]['axtime']; et.trap_SendServerCommand(et.EXEC_APPEND , 'print \"..time.. \" seconds in axis')" -commands['cmd'][0]['altime'] = "$LUA$ time = slot[_clientNum]['altime']; et.trap_SendServerCommand(et.EXEC_APPEND , 'print \"..time.. \" seconds in allies')" -commands['cmd'][0]['noqban'] = "$LUA$ ban()" --TODO The BANFUNCTION... --- ^ ^ ^ ^ --- Array | | | --- type | | --- Level | --- Part after Prefix --- Its possible to implement 2 commands with same commandname but different functions for different levels --- --- commands['help'] incorporates the helptexts for each cmd --- commands['listing'][lvl] incorporates a listing of all cmds that level can execute, as strings ready to get printed to console --- ---]] - --- current map -map = "" -mapStartTime = 0 ---Gamestate 1 ,2 , 3 = End of Map -gstate = nil - --- for the evener -evener = 0 -killcount = 0 -lastevener = 0 - --- Poll restriction -lastpoll = 0 - --- vsay disabler -vsaydisabled = false - --- reserved names array -namearray = {} - --- mail setup -if mail == 1 then - smtp = require("socket.smtp") -end - --- irc relay setup -if irchost ~= "" then - socket = require("socket") - client = socket.udp() -end - -team = { [0]="CONN","AXIS" , "ALLIES" , "SPECTATOR" } -teamchars = { ['r']="AXIS" , ['b']="ALLIES" , ['s']="SPECTATOR" } -class = { [0]="SOLDIER" , "MEDIC" , "ENGINEER" , "FIELD OPS" , "COVERT OPS" } - -------------------------------------------------------------------------------- --- load DB functions if needed -------------------------------------------------------------------------------- -if databasecheck == 1 then -require(noqpath .. "noq_db") -DBCon:DoConnect() -end - -------------------------------------------------------------------------------- --- ET functions -------------------------------------------------------------------------------- - -function et_InitGame( _levelTime, _randomSeed, _restart ) - et.RegisterModname( "NOQ version " .. version .. " " .. et.FindSelf() ) - initNOQ() - if databasecheck == 1 then - getDBVersion() - getresNames() - end - mapStartTime = et.trap_Milliseconds() - if usecommands ~= 0 then - parseconf() - end - if irchost ~= "" then - client:setpeername(irchost,ircport) - end - - -- |We allow votes not directly at start, lets wait some time - lastpoll = (et.trap_Milliseconds() / 1000) - (polldist / 2) - - -- IlDuca: TEST for mail function - -- sendMail("", "Test smtp", "Questo è un test, speriamo funzioni!!") -end - -function et_ClientConnect( _clientNum, _firstTime, _isBot ) - initClient( _clientNum, _firstTime, _isBot ) - - local ban = checkBan( _clientNum ) - if ban ~= nil then - return ban - end - -- valid client - slot[_clientNum]["inuse"] = true - - -- personal game start message / server greetings - if firstTime == 0 or isBot == 1 or getConfig("persgamestartmessage") == "" then - return nil - end - userInfo = et.trap_GetUserinfo( _clientNum ) - et.trap_SendServerCommand(_clientNum, string.format("%s \"%s %s", getConfig("persgamestartmessagelocation") , getConfig("persgamestartmessage") , et.Info_ValueForKey( userInfo, "name" ))) - - return nil -end - -function et_ClientUserinfoChanged( _clientNum ) - if databasecheck == 1 then - if lognames == 1 then - local thisGuid = string.upper( et.Info_ValueForKey( et.trap_GetUserinfo( _clientNum ), "cl_guid" )) - if string.sub(thisGuid, 1, 7) ~= "OMNIBOT" then - local thisName = et.Info_ValueForKey( et.trap_GetUserinfo( _clientNum ), "name" ) - DBCon:SetPlayerAlias( thisName, thisGuid ) - end - end - end - - if namearray ~= nil then - checkforResName(_clientNum) - end - -end - --- This function is called - after the connection is over, so when you first join the game world --- --- Before r3493 also: --- - when you change team --- - when you are spectator and switch from "free look mode" to "follow player mode" --- IRATA: check et_ClientSpawn() --- TODO/NOTE: Afaik we only need to check if ClientBegin is called once to keep 1.2.7 compatibility -function et_ClientBegin( _clientNum ) - -- TODO Move this functionality in an own function - -- Get the player name if its not set - if slot[_clientNum]["netname"] == false then - slot[_clientNum]["netname"] = et.gentity_get( _clientNum ,"pers.netname") - slot[_clientNum]["cleanname"] = et.Q_CleanStr(slot[_clientNum]["netname"]) - end - - -- He first connected - so we set his team. - slot[_clientNum]["team"] = tonumber(et.gentity_get(_clientNum,"sess.sessionTeam")) - slot[_clientNum]["lastTeamChange"] = (et.trap_Milliseconds() / 1000) -- Hossa! We needa seconds - - -- greeting functionality after netname is set - if slot[_clientNum]["ntg"] == true then - greetClient(_clientNum) - end - - -- Moved the mute check here - checkMute( _clientNum ) - - - if databasecheck == 1 then - -- If we have db access, then we will create new Playerentry if necessary - -- TODO check for else case of the above if ... why updating Player XP if client is new ? (slot XP is set in createNewPlayer() - - if slot[_clientNum]["new"] == true then - createNewPlayer ( _clientNum ) - slot[_clientNum]["setxp"] = nil - else - -- if we have xprestore, we need to restore now! - if slot[_clientNum]["setxp"] == true then - - -- But only, if xprestore is on! - if xprestore == 1 then - updatePlayerXP( _clientNum ) - end - slot[_clientNum]["setxp"] = nil - end - end - - checkOffMesg(_clientNum) - - -- Reserved Name/Clantag support - if namearray then - checkforResName(_clientNum) - end - - end -- end databasecheck -end - --- TODO: What does this do here? --- Possible values are : --- - slot[_clientNum].team == nil -> the player connected and disconnected without join the gameworld = not-valid session --- - slot[_clientNum].gstate = 0 and gstate = 0 -> we have to update playing time and store all the player infos = valid session --- - slot[_clientNum].gstate = 1 or 2 and gstate = 1 or 2 -> player connected during warmup and disconnected during warmup = store only start and end time + valid session --- - slot[_clientNum].gstate = 3 and gstate = 3 -> player connected during intermission and disconnected during intermission = store only start and end time + valid session --- - slot[_clientNum].gstate = 0 and gstate = 3 -> we have to store all the player infos = valid session - -function et_ClientDisconnect( _clientNum ) - if databasecheck == 1 then - local endtime = timehandle ('N') - -- TODO : check if this works. Is the output from 'D' option in the needed format for the database? - local timediff = timehandle('D','N', slot[_clientNum]["start"]) - - WriteClientDisconnect( _clientNum , endtime, timediff ) - end - slot[_clientNum] = {} - slot[_clientNum]["inuse"] = false -end - --- called for every clientcommand --- return 1 if intercepted, 0 if passthrough --- see Table noq_clientcommands for the available cmds -function et_ClientCommand( _clientNum, _command ) - local arg0 = string.lower(et.trap_Argv(0)) - local arg1 = string.lower(et.trap_Argv(1)) - local arg2 = string.lower(et.trap_Argv(2)) - callershrublvl = 1 -- FIXME !!! et.G_shrubbot_level(_clientNum) - - debugPrint("print","Got a Clientcommand: ".. arg0) - - if vsaydisabled == true and arg0 == "vsay" then - -- No vsays please. - et.trap_SendServerCommand( _clientNum, "cp \"^1Global voicechat disabled\"") - return 1 - end - - if slot[_clientNum]['vsaydisabled'] == true and arg0 == "vsay" then - -- No vsays please. - et.trap_SendServerCommand( _clientNum, "cp \"^1Your global voicechats are disabled\"") - return 1 - end - - -- switch to disable the !commands - if usecommands ~= 0 then - - if arg0 == "say" then - if string.sub( arg1, 1,1) == commandprefix then -- this means normal say - debugPrint("print","Got saycommand: " .. _command) - local returnvalue = gotCmd( _clientNum, _command , false) - return returnvalue - -- return gotCmd( _clientNum, _command , false) - end - elseif arg0 == "vsay" then - if string.sub( arg2 , 1, 1) == commandprefix then -- this means a !command with vsay - gotCmd ( _clientNum, _command, true) - end - elseif arg0 == "readthefile" then -- read in the commandsfile - if et.G_shrubbot_permission( _clientNum, "G" ) == 1 then -- has the right to read the config in.. So he also can read commands - parseconf() - et.trap_SendConsoleCommand(et.EXEC_APPEND, "csay " .. _clientNum .. "\"^3Parsed commands.\n\"\n") - return 1 - end - et.trap_SendConsoleCommand(et.EXEC_APPEND, "csay " .. _clientNum .. "\"^3Not enough rights to use this command.\n\"\n") - return 1 - end - - - if et.G_shrubbot_permission( _clientNum, "3" ) == 1 then -- and finally, a silent !command - if string.sub( arg0 , 1, 1) == commandprefix then - local returnvalue = gotCmd ( _clientNum, _command, nil) - return returnvalue - end - end - - end - - - if noq_clientcommands == nil then - --[[ - The Commands used in et_clientcommand. - use arg0, arg1, arg2 for arguments, callershrublvl as lvl, clientNum for clientNum - --]] - noq_clientcommands = { - - ["noq_alist"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - if arg1 == "" then - nPrint(clientNum, "^3Usage: /noq_alist ") - nPrint(clientNum, "^3noq_alist will print a list of all know aliases for a player") - return 1 - else - local whom = getPlayerId(arg1) - if whom ~= nil then - listAliases(clientNum, whom) - return 1 - else - nPrint(clientNum, "^3No matching player found :/") - end - end - end, - - ["register"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - -- register command - local name = string.gsub(arg1,"\'", "\\\'") - if arg1 ~= "" and arg2 ~= "" then - local testreg = DBCon:GetPlayerbyReg(name) - if testreg ~= nil then - if testreg['pkey'] == slot[clientNum]['pkey'] then - slot[clientNum]["user"] = name - DBCon:DoRegisterUser(name, arg2,slot[clientNum]["pkey"]) - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. clientNum .. "\"^3Successfully reset password\n\"\n") - return 1 - end - - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. clientNum .. "\"^3This nick is already registered\n\"\n") - return 1 - end - - slot[clientNum]["user"] = name - DBCon:DoRegisterUser(name, arg2,slot[clientNum]["pkey"]) - - et.trap_SendServerCommand( clientNum, "print \"^3Successfully registered. To reset password just re-register. \n\"" ) - return 1 - else - - if slot[clientNum]["user"] ~= "" then - et.trap_SendServerCommand( clientNum, "print \"^1You are already registered, under the name '".. slot[clientNum]["user"] .. "'\n\"" ) - end - et.trap_SendServerCommand( clientNum, "print \"^3Syntax for the register Command: /register username password \n\"" ) - et.trap_SendServerCommand( clientNum, "print \"^3Username is your desired username (for web & offlinemessages) \n\"" ) - et.trap_SendServerCommand( clientNum, "print \"^3Password will be your password for your webaccess \n\"" ) - - return 1 - end - end, - - ["callvote"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - -- Voting restriction - - if polldist ~= -1 then - -- restriction is enabled - milliseconds = et.trap_Milliseconds() - seconds = milliseconds / 1000 - - -- checks for shrubbot flag "7" -> check shrubbot wiki for explanation - if et.G_shrubbot_permission( clientNum, "7" ) == 1 then - return 0 - - -- checks time betw. last vote and this one - elseif (seconds - lastpoll) < polldist then - et.trap_SendConsoleCommand (et.EXEC_APPEND , "chat \"".. et.gentity_get(clientNum, "pers.netname") .."^7, please wait ^1".. string.format("%.0f", polldist - (seconds - lastpoll) ) .." ^7seconds for your next poll.\"" ) - return 1 - end - - -- handles nextmap vote restriction - if arg1 == "nextmap" then - - --check the time that the map is running already - mapTime = et.trap_Milliseconds() - mapStartTime - - debugPrint("print","maptime = " .. mapTime) - debugPrint("print","maptime in seconds = " .. mapTime/1000 ) - debugPrint("print","mapstarttime = " .. mapStartTime) - debugPrint("print","mapstarttime in seconds = " .. mapStartTime/1000) - - --compare to the value that is given in config where nextmap votes are allowed - if nextmapVoteTime == 0 then - debugPrint("print","Nextmap vote limiter is disabled!") - return 0 - elseif mapTime / 1000 > nextmapVoteTime then - --if not allowed send error msg and return 1 - et.trap_SendConsoleCommand (et.EXEC_APPEND, "chat \"Nextmap vote is only allowed during the first " .. nextmapVoteTime .." seconds of the map! Current maptime is ".. mapTime/1000 .. " seconds!\"") - return 1 - end - - end - - lastpoll = seconds - end - -- return !!! - end , - - ["kill"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - -- /kill restriction - if maxSelfKills ~= -1 then - if slot[clientNum]["selfkills"] > maxSelfKills then - et.trap_SendServerCommand( clientNum, "cp \"^1You don't have any more selfkills left!") - et.trap_SendServerCommand( clientNum, "cpm \"^1You don't have any more selfkills left!") - return 1 - end - et.trap_SendServerCommand( clientNum, "cp \"^1You have ^2".. (maxSelfKills - slot[clientNum]["selfkills"]) .."^1 selfkills left!") - et.trap_SendServerCommand( clientNum, "cpm \"^1You have ^2".. (maxSelfKills - slot[clientNum]["selfkills"]) .."^1 selfkills left!") - return 0 - end - end, - - ["mail"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - -- check for OfflineMesgs - checkOffMesg (clientNum) - return 1 - end, - - ["om"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - -- send OfflineMesgs - sendOffMesg (clientNum,arg1 , et.ConcatArgs( 2 ) ) - return 1 - end, - - ["rmom"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - --erase OfflineMesgs - arg1 = string.gsub(arg1,"\'", "\\\'") - DBCon:DelOM(arg1, slot[clientNum]['pkey']) - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. clientNum .. "\"^3Erased MessageID ".. arg1 .."\n\"\n") - return 1 - end, - - ["rmmail"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - --erase all OfflineMesgs - DBCon:DelMail(slot[clientNum]['pkey']) - nPrint(clientNum, "^3Cleared your Inbox. ") - return 1 - end, - - ["team"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - -- lock to team - if slot[clientNum]["locktoTeam"] ~= nil then - if arg1 ~= slot[clientNum]["locktoTeam"] then - if slot[clientNum]["lockedTeamTill"] <= (et.trap_Milliseconds() /1000 ) then - slot[clientNum]["locktoTeam"] = nil - slot[clientNum]["lockedTeamTill"] = 0 - -- TODO return! - else - et.trap_SendServerCommand( clientNum, "cp \"^3You are locked to the ^1"..teamchars[slot[clientNum]["locktoTeam"]].. " ^3team by an admin") - et.trap_SendServerCommand( clientNum, "chat \"^3You are locked to the ^1"..teamchars[slot[clientNum]["locktoTeam"]].. " ^3team by an admin") - return 1 - end - end - end - end, - - ["mirc"] = function(arg0,arg1,arg2,clientNum,callershrublvl) - msgtoIRC(clientNum,et.ConcatArgs( 1 )) - return 1 - end - - } -- end for our cmdarray - - end - - if noq_clientcommands[arg0] then - return(noq_clientcommands[arg0](arg0,arg1,arg2,_clientNum,callershrublvl)) - end - -end - --- FIXME: this crashes in legacy mod -function et_ShutdownGame( _restart ) - if databasecheck == 1 then - -- We write only the informations from a session that gone till intermission end - - -- gamestate 2 reached once when !restart used - also when map ends regularly.. - -- this gets called ONCE .. and gamestate is not -1. - --if tonumber(et.trap_Cvar_Get( "gamestate" )) == -1 then - - -- This is when the map ends: we have to close all opened sessions - -- Cycle between all possible clients - local endgametime = timehandle('N') - - if tonumber(et.trap_Cvar_Get( "gamestate" )) == 0 then - -- this is the case if the warmup end - thus we dont save a session here. - else - -- save only in intermission. - for i=0, maxclients, 1 do - -- TODO: check slot[] if its existingreco - if et.gentity_get(i,"classname") == "player" then - -- TODO : check if this works. Is the output from 'D' option in the required format for the database? - local timediff = timehandle('D',endgametime,slot[i]["start"]) - et.G_LogPrint( "Noq: saved player "..i.." to Database\n" ) - WriteClientDisconnect( i , endgametime, timediff ) - slot[i] = nil - end - end - end - - --DBCon:DoDisconnect() - end - - -- delete old sessions if set in config - local deleteSessionsOlderXMonths = tonumber(getConfig("deleteSessionsOlderXMonths")) - if deleteSessionsOlderXMonths > 0 then - DBCon:DoDeleteOldSessions( deleteSessionsOlderXMonths ) - end -end - -function et_RunFrame( _levelTime ) - -- TODO: is this what we want? I suppose yes... - -- This check works only once, when the intermission start: here we have to close sptime, axtime and altime - -- For all players in the LUA table "slot" - if ( gstate == 0 ) and ( tonumber(et.trap_Cvar_Get( "gamestate" )) == 3 ) then - local now = timehandle() - - for i=0, maxclients, 1 do - -- this tests if the playerentity is used! useless to close a entity wich is not in use. - -- @Luborg: Actually it checks if the ent is a player - this is always the case (ent 0 - maxclients) if they are active - -- Did you get errors ? Checking slot[i]["team"] should be enough here since the slot table is a mirror of current players - -- and "team" == -1 means we already closed the team -> slot not in use. closeTeam() should handle the other cases - -- It's worth to sort this out it's RunFrame ... - if et.gentity_get(i,"classname") == "player" then - -- @Ilduca note: client["team"] is set to false somewhere in this code - if slot[i]["team"] ~= -1 then - closeTeam ( i ) - end - end - end - - gstate = tonumber(et.trap_Cvar_Get( "gamestate" )) - - -- Added last kill of the round-- this fails when no kills have been done - if (lastkill ~= nil) then - execCmd(lastkill, "chat \"^2And the last kill of the round goes to: ^7\"" , {[1]=lastkill,[2]=lastkill,[3]=lastkill}) - et.trap_SendConsoleCommand(et.EXEC_APPEND, "chat \"^2A total of ^7" .. killcount .. " ^2Persons died by various reasons during this map\"" ) - end - --TODO: Should we call the save to the DB right here? - end -end - -function et_Obituary( _victim, _killer, _mod ) - debugPrint("cpm", "Victim: ".._victim .. " Killer " .._killer .." MOD: ".. meansofdeath[_mod]) - if _killer == 1022 then - -- this is for a kill by falling or similar trough the world. Mapmortar etc also. - - slot[_victim]["killer"] = _killer - slot[_victim]["deadwep"] = string.sub(meansofdeath[_mod], 5) - - -- update kill vars (victim only) - - else -- all non world kills - pussyFactCheck( _victim, _killer, _mod ) - - slot[_killer]["victim"] = _victim - slot[_killer]["killwep"] = string.sub(meansofdeath[_mod], 5) - - slot[_victim]["killer"] = _killer - slot[_victim]["deadwep"] = string.sub(meansofdeath[_mod], 5) - - lastkiller = _killer - - -- update client vars ... - - -- Self kill (restriction) - if _killer == _victim then - if _mod == mod["MOD_SUICIDE"] then - slot[_killer]["selfkills"] = slot[_killer]["selfkills"] + 1 -- what about if they use nades? - end - -- TODO: wtf? why not just add 1 to the field? Why call an ETfunction if WE could do it faster?? - slot[_victim]["death"] = tonumber(et.gentity_get(_victim,"sess.deaths")) - -- slot[_victim]["tkills"] = tonumber(et.gentity_get(_clientNum,"sess.team_kills")) -- TODO ???? - -- slot[_victim]["tkilled"] = slot[_victim]["tkilled"] + 1 - else -- _killer <> _victim - -- we assume client[team] is always updated - if slot[_killer]["team"] == slot[_victim]["team"] then -- Team kill - -- TODO: check if death/kills need an update here - slot[_killer]["tkills"] = slot[_killer]["tkills"] + 1 - slot[_victim]["tkilled"] = slot[_victim]["tkilled"] + 1 - - if not tkweight[_mod] ~= nil then tk = 1 else tk = tkweight[_mod] end - slot[_killer]["tkpoints"] = slot[_killer]["tkpoints"] + tk - checkTKPoints(_killer) - - else -- cool kill - slot[_victim]["death"] = tonumber(et.gentity_get(_victim,"sess.deaths")) - slot[_killer]["kills"] = tonumber(et.gentity_get(_killer,"sess.kills")) - - slot[_victim]["kspree"] = 0 - slot[_killer]["kspree"] = slot[_killer]["kspree"] + 1 - -- force points - adding half of the killspree value - slot[_killer]["fpoints"] = slot[_killer]["fpoints"] + (slot[_killer]["kspree"] / 2) - -- add 1 point for deaths to .. some haven't the luck of many kills - slot[_victim]["fpoints"] = slot[_victim]["fpoints"] + 1 - - - end - end - - end -- end of 'all not world kills' - - -- uneven teams solution - the evener - if evenerdist ~= -1 then - killcount = killcount +1 - seconds = (et.trap_Milliseconds() / 1000) - if killcount % 2 == 0 and (seconds - lastevener ) >= evenerdist then - checkBalance( true ) - lastevener = seconds - end - end - - -- last kill of the round - lastkill = _killer -end - --- called for every Servercommand --- return 1 if intercepted, 0 if passthrough -function et_ConsoleCommand( _command ) - -- debugPrint("cpm", "ConsoleCommand - command: " .. _command ) - - -- noq cmds ... - -- TODO: What is this !noq cmd good for in here? - -- if string.lower(et.trap_Argv(0)) == commandprefix.."noq" then - -- if (et.trap_Argc() < 2) then - -- et.G_Print("#sql is used to access the db with common sql commands.\n") - -- et.G_Print("usage: ...") - -- return 1 - -- end - - -- noq warn ... - -- TODO: What is this !warn cmd good for in here? - -- elseif string.lower(et.trap_Argv(0)) == commandprefix.."warn" then - -- try first param to cast as int - -- if int check if slot .. ban - -- if not try to get player via part of name ... - - local arg0 = string.lower(et.trap_Argv(0)) - if arg0 == "csay" then - -- csay - say something to clients console .. usefull for EXEC_APPEND! - if (et.trap_Argc() >= 3) then - _targetid = tonumber(et.trap_Argv(1)) - if slot[_targetid] ~= nil then - - et.trap_SendServerCommand( _targetid,"print \"" .. et.trap_Argv(2) .."\n\"") - end - end - elseif arg0 == "plock" then - -- plock - lock a player to a team - if (et.trap_Argc() >= 4) then - _targetid = tonumber(et.trap_Argv(1)) - _targetteam = et.trap_Argv(2) - _locktime = tonumber(et.trap_Argv(3)) - slot[_targetid]["locktoTeam"] = _targetteam - slot[_targetid]["lockedTeamTill"] = _locktime + (et.trap_Milliseconds() /1000 ) - et.trap_SendServerCommand( -1,"chat \"^7"..slot[_targetid]["netname"].." ^3 is now locked to the ^1"..teamchars[_targetteam].."^3 team\"") - end - elseif arg0 == "noq_irc" then - sendtoIRCRelay(et.ConcatArgs( 1 )) - elseif arg0 == "!setlevel" or arg0 == commandprefix .. "setlevel" then - -- we need to set the level to be sure db is up-to-date - if (et.trap_Argc() ~= 3 ) then - et.G_Print("usage: !setlevel id/name level") - else - local plr = getPlayerId(et.trap_Argv(1)) - if plr then - slot[plr]["lvl"] = tonumber(et.trap_Argv(2)) - savePlayer( plr ) - et.G_Print("NOQ: set " .. slot[plr]['netname'] .. " to level " .. tonumber(et.trap_Argv(2)) .. "\n" ) - else - et.G_Print("NOQ: No corresponding player found to set level.") - end - end - end - - -- add more cmds here ... -end - -function et_ClientSpawn( _clientNum, _revived ) - -- TODO: check if this works, works! - -- _revived == 1 means he was revived - if _revived ~= 1 then - updateTeam(_clientNum) - else - et.trap_SendServerCommand(et.gentity_get(_clientNum,"pers.lastrevive_client"),"cpm \"^1You revived ^7" .. slot[_clientNum] .. " \"" ); - end - -end - -------------------------------------------------------------------------------- --- helper functions -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- --- initClient --- Gets DbInfos and checks for Ban and Mute, inits clientfields --- the very first action -------------------------------------------------------------------------------- -function initClient ( _clientNum, _FirstTime, _isBot) - -- note: this script should work w/o db connection - -- greetings functionality: check if connect (1) or reconnect (2) - - --'static' clientfields - slot[_clientNum]["pkey"] = string.upper( et.Info_ValueForKey( et.trap_GetUserinfo( _clientNum ), "cl_guid" )) - slot[_clientNum]["ip"] = et.Info_ValueForKey( et.trap_GetUserinfo( _clientNum ), "ip" ) - local a - local b - a, b, slot[_clientNum]["ip"]= string.find(slot[_clientNum]["ip"],"(%d+%.%d+%.%d+%.%d+)") - slot[_clientNum]["isBot"] = _isBot - slot[_clientNum]["conname"] = et.Info_ValueForKey( et.trap_GetUserinfo( _clientNum ), "name" ) - slot[_clientNum]["level"] = 1 -- FIXME !!! et.G_shrubbot_level(_clientNum) - slot[_clientNum]["flags"] = "" -- TODO - slot[_clientNum]["start"] = timehandle('N') -- Get the start connection time - - -- 'dynamic' clientfields - slot[_clientNum]["team"] = false -- set the team on client begin (don't use nil here, as it deletes the index!) - slot[_clientNum]["axtime"] = 0 - slot[_clientNum]["altime"] = 0 - slot[_clientNum]["sptime"] = 0 - slot[_clientNum]["lctime"] = 0 - slot[_clientNum]["acc"] = 0 - slot[_clientNum]["kills"] = 0 - slot[_clientNum]["tkills"] = 0 - slot[_clientNum]["tkpoints"] = 0 - slot[_clientNum]["kspree"] = 0 -- killingspree - slot[_clientNum]["fpoints"] = 10 -- forcepoints - slot[_clientNum]["netname"] = false - slot[_clientNum]["victim"] = -1 - slot[_clientNum]["killwep"] = "nothing" - slot[_clientNum]["killer"] = -1 - slot[_clientNum]["deadwep"] = "nothing" - slot[_clientNum]["selfkills"] = 0 - slot[_clientNum]["vsaydisabled"] = false - slot[_clientNum]["locktoTeam"] = nil - slot[_clientNum]["lockedTeamTill"] = 0 - - - slot[_clientNum]["death"] = 0 - slot[_clientNum]["uci"] = 0 - slot[_clientNum]["pf"] = 0 - - -- non db client fields - slot[_clientNum]["tkilled"] = 0 - - - if _FirstTime == 1 then - slot[_clientNum]["ntg"] = true - else - slot[_clientNum]["ntg"] = false - end - - debugPrint("cpm", "LUA: INIT CLIENT" ) - - if databasecheck == 1 then - debugPrint("cpm", "LUA: INIT DATABASECHECK EXEC" ) - - updatePlayerInfo(_clientNum) - - slot[_clientNum]["setxp"] = true - slot[_clientNum]["xpset"] = false - - return nil - end - - debugPrint("cpm", "LUA: INIT CLIENT NO DATABASE INTERACTION" ) - - return nil -end - -------------------------------------------------------------------------------- --- updatePlayerInfo --- Updates the Playerinformation out of the Database (IF POSSIBLE!) --- Also called on connect -------------------------------------------------------------------------------- -function updatePlayerInfo ( _clientNum ) - DBCon:GetPlayerInfo( slot[_clientNum]["pkey"] ) - - if DBCon.row then - -- This player is already present in the database - debugPrint("cpm", "LUA: INIT CLIENT ROW EXISTS") - -- Start to collect related information for this player id - -- player - slot[_clientNum]["id"] = DBCon.row.id - slot[_clientNum]["regname"] = DBCon.row.regname - slot[_clientNum]["conname"] = DBCon.row.conname - --slot[_clientNum]["netname"] = DBCon.row.netname --we don't set netname to a invalid old databaseentry - slot[_clientNum]["clan"] = DBCon.row.clan - slot[_clientNum]["user"] = DBCon.row.user -- only for admin info - slot[_clientNum]["banreason"] = DBCon.row.banreason - slot[_clientNum]["bannedby"] = DBCon.row.bannedby - slot[_clientNum]["banexpire"] = DBCon.row.banexpire - slot[_clientNum]["mutedreason"] = DBCon.row.mutedreason - slot[_clientNum]["mutedby"] = DBCon.row.mutedby - slot[_clientNum]["muteexpire"] = DBCon.row.muteexpire - slot[_clientNum]["warnings"] = DBCon.row.warnings - slot[_clientNum]["suspect"] = DBCon.row.suspect - slot[_clientNum]["regdate"] = DBCon.row.regdate - slot[_clientNum]["createdate"] = DBCon.row.createdate -- first seen - slot[_clientNum]["updatedate"] = DBCon.row.updatedate -- last seen - --slot[_clientNum]["level"] = et.G_shrubbot_level( _clientNum ) - --TODO: REAL LEVEL/Who is more important, shrub or database? - -- IRATA: noq - database; - -- ailmanki: changed.. if the user is in db we get in from db, else from shrubbot. - -- luborg: use nq_noq to determine: - local nq_noq = et.trap_Cvar_Get( "nq_noq" ) - if nq_noq ~= 1 or nq_noq ~= 2 then - -- nq_noq is not set, shrub is active - we only save, but dont set. - else - slot[_clientNum]["level"] = DBCon.row.level - -- cmd only available in nq >= 130 - et.G_shrubbot_setlevel(_clientnum, DBCon.row.level) - end - slot[_clientNum]["flags"] = DBCon.row.flags -- TODO: pump it into game - - --Perhaps put into updatePlayerXP - slot[_clientNum]["xp0"] = DBCon.row.xp0 - slot[_clientNum]["xp1"] = DBCon.row.xp1 - slot[_clientNum]["xp2"] = DBCon.row.xp2 - slot[_clientNum]["xp3"] = DBCon.row.xp3 - slot[_clientNum]["xp4"] = DBCon.row.xp4 - slot[_clientNum]["xp5"] = DBCon.row.xp5 - slot[_clientNum]["xp6"] = DBCon.row.xp6 - slot[_clientNum]["xptot"] = DBCon.row.xptot - - debugPrint("cpm", "LUA: INIT CLIENT FROM ROW GOOD" ) - else - debugPrint("cpm", "LUA: INIT CLIENT NO ROW -> NEW" ) - -- Since he is new, he isn't banned or muted: let him pass those check - slot[_clientNum]["banreason"] = "" - slot[_clientNum]["bannedby"] = "" - slot[_clientNum]["banexpire"] = "1000-01-01 00:00:00" - slot[_clientNum]["mutedreason"] = "" - slot[_clientNum]["mutedby"] = "" - slot[_clientNum]["muteexpire"] = "1000-01-01 00:00:00" - - -- Go to Clientbegin and say he's new - slot[_clientNum]["new"] = true - end -end - -------------------------------------------------------------------------------- --- updatePlayerXP --- Update a players xp from the values in his previously set Xptable --- just a g_xp_setfunction for all values -------------------------------------------------------------------------------- -function updatePlayerXP( _clientNum ) - - if tonumber(slot[_clientNum]["xp0"]) < 0 then - slot[_clientNum]["xp0"] = 0 - end - if tonumber(slot[_clientNum]["xp1"]) < 0 then - slot[_clientNum]["xp1"] = 0 - end - if tonumber(slot[_clientNum]["xp2"]) < 0 then - slot[_clientNum]["xp2"] = 0 - end - if tonumber(slot[_clientNum]["xp3"]) < 0 then - slot[_clientNum]["xp3"] = 0 - end - if tonumber(slot[_clientNum]["xp4"]) < 0 then - slot[_clientNum]["xp4"] = 0 - end - if tonumber(slot[_clientNum]["xp5"]) < 0 then - slot[_clientNum]["xp5"] = 0 - end - if tonumber(slot[_clientNum]["xp6"]) < 0 then - slot[_clientNum]["xp6"] = 0 - end - - et.G_XP_Set ( _clientNum , slot[_clientNum]["xp0"], 0, 0 ) -- battle - et.G_XP_Set ( _clientNum , slot[_clientNum]["xp1"], 1, 0 ) -- engi - et.G_XP_Set ( _clientNum , slot[_clientNum]["xp2"], 2, 0 ) -- medic - et.G_XP_Set ( _clientNum , slot[_clientNum]["xp3"], 3, 0 ) -- signals - et.G_XP_Set ( _clientNum , slot[_clientNum]["xp4"], 4, 0 ) -- light - et.G_XP_Set ( _clientNum , slot[_clientNum]["xp5"], 5, 0 ) -- heavy - et.G_XP_Set ( _clientNum , slot[_clientNum]["xp6"], 6, 0 ) -- covert - slot[_clientNum]["xpset"] = true -end - -------------------------------------------------------------------------------- --- checkBan --- Check if player is banned and kick him --- TODO : would be cool to inform admins about bans through mail --- TODO : add something that tracks a just-unbanned player ( for time bans ) --- in order to warn online admins and maybe the player himself --- NOTE : do something like checkMute with an own LUA function? -------------------------------------------------------------------------------- -function checkBan ( _clientNum ) - if slot[_clientNum]["bannedby"] ~= "" then - if slot[_clientNum]["banreason"] ~= "" then - if slot[_clientNum]["banexpire"] ~= "1000-01-01 00:00:00" then - -- Check for expired ban - if timehandle( 'DS', 'N', slot[_clientNum]["banexpire"] ) > 0 then - -- The ban is expired: clear the ban fields and continue - slot[_clientNum]["bannedby"] = "" - slot[_clientNum]["banreason"] = "" - slot[_clientNum]["banexpire"] = "1000-01-01 00:00:00" - - return nil - end - return "You are banned by "..slot[_clientNum]["bannedby"].." until "..slot[_clientNum]["banexpire"]..". Reason: "..slot[_clientNum]["banreason"] - else - return "You are permanently banned by "..slot[_clientNum]["bannedby"]..". Reason: "..slot[_clientNum]["banreason"] - end - else - if slot[_clientNum]["banexpire"] ~= "1000-01-01 00:00:00" then - -- Check for expired ban - if timehandle( 'DS', 'N', slot[_clientNum]["banexpire"] ) > 0 then - -- The ban is expired: clear the ban fields and continue - slot[_clientNum]["bannedby"] = "" - slot[_clientNum]["banexpire"] = "1000-01-01 00:00:00" - - return nil - end - return "You are banned by "..slot[_clientNum]["bannedby"].." until "..slot[_clientNum]["banexpire"] - else - return "You are permanently banned by "..slot[_clientNum]["bannedby"] - end - end - end - - return nil -end - -------------------------------------------------------------------------------- --- checkMute --- Called in clientBegin in order to print the warning message to the player --- The mute is done through ET, calculating the time between NOW and muteexpire --- and setting the seconds to the game's mute system. Expired check is done with --- the field mutedby; muteexpire is cleared in the database when clientDisconnect --- TODO : would be cool to inform admins about mutes through mail --- TODO : add something that tracks a just-unmuted player ( for time mute ) --- in order to warn online admins and maybe the player himself -------------------------------------------------------------------------------- -function checkMute ( _clientNum ) - if slot[_clientNum]["mutedby"] ~= "" then - -- Check permanent mute - if slot[_clientNum]["muteexpire"] == "1000-01-01 00:00:00" then - et.MutePlayer( _clientNum, -1, slot[_clientNum]["mutedreason"] ) - return nil - end - local muteseconds = timehandle( 'DS', 'N', slot[_clientNum]["muteexpire"] ) - -- Check if the mute is still valid - if muteseconds > 0 then - -- The mute is expired: clear the mute fields and continue - slot[_clientNum]["mutedby"] = "" - slot[_clientNum]["mutedreason"] = "" - slot[_clientNum]["muteexpire"] = "" - else - -- The mute is still valid: mute him! - muteseconds = muteseconds * (-1) - et.MutePlayer( _clientNum, muteseconds, slot[_clientNum]["mutedreason"] ) - end - end - - return nil -end - -------------------------------------------------------------------------------- --- createNewPlayer --- Create a new Player: write to Database, set Xp 0 --- maybe could also be used to reset Player, as pkey is unique -------------------------------------------------------------------------------- -function createNewPlayer ( _clientNum ) - local name = string.gsub(slot[_clientNum]["netname"],"\'", "\\\'") - local conname = string.gsub(slot[_clientNum]["conname"],"\'", "\\\'") - -- This player is a new one: create a new database entry with our Infos - DBCon:DoCreateNewPlayer( slot[_clientNum]["pkey"], slot[_clientNum]["isBot"], name, slot[_clientNum]["start"], slot[_clientNum]["start"], conname) - --[[ Commented out - what did that here? - slot[_clientNum]["xp0"] = et.gentity_get(_clientNum,"sess.skillpoints",0) - slot[_clientNum]["xp1"] = et.gentity_get(_clientNum,"sess.skillpoints",1) - slot[_clientNum]["xp2"] = et.gentity_get(_clientNum,"sess.skillpoints",2) - slot[_clientNum]["xp3"] = et.gentity_get(_clientNum,"sess.skillpoints",3) - slot[_clientNum]["xp4"] = et.gentity_get(_clientNum,"sess.skillpoints",4) - slot[_clientNum]["xp5"] = et.gentity_get(_clientNum,"sess.skillpoints",5) - slot[_clientNum]["xp6"] = et.gentity_get(_clientNum,"sess.skillpoints",6) - slot[_clientNum]["xptot"] = slot[_clientNum]["xp0"] + slot[_clientNum]["xp1"] + slot[_clientNum]["xp2"] + slot[_clientNum]["xp3"] + slot[_clientNum]["xp4"] + slot[_clientNum]["xp5"] + slot[_clientNum]["xp6"] - slot[_clientNum]["suspect"] = 0 - --]] - - slot[_clientNum]["new"] = nil - slot[_clientNum]["xpset"] = true - - -- And now we will get all our default values - -- but why? - updatePlayerInfo (_clientNum) -end - -------------------------------------------------------------------------------- --- timehandle --- Function to handle times --- TODO : check if the time returned with option 'D' is in the right format we need --- TODO : actually, 'D' and 'DS' are almost equal: save some lines mergin them!! --- NOTE ABOUT TIME IN LUA: the function os.difftime works only with arguments passed in seconds, so --- before pass anything to that functions we have to convert the date in seconds --- with the function os.time, then convert back the result with os.date -------------------------------------------------------------------------------- -function timehandle ( op, time1, time2) - -- The os.* functions needs a shell to be linked and accessible by the process running LUA - -- TODO : this check should be moved at script start because os.* functions are really - -- "popular" so we may use them in other functions too - if os.execute() == 0 then - error("This process needs an active shell to be executed.") - end - - local timed = nil - - if op == 'N' then - -- N -> return current date ( NOW ) - local timed = os.date("%Y-%m-%d %X") - if timed then - return timed - end - return nil - elseif op == 'D' then - -- D -> compute time difference time1-time2 - if time1==nil or time2==nil then - error("You must to input 2 arguments to use the 'D' option.") - end - - -- Check if time1 is 'N' ( NOW ) - if time1 == 'N' then - -- Check if time2 is in the right format - if string.len(time2) == 19 then - timed = os.difftime(os.time(),os.time{year=tonumber(string.sub(time2,1,4)), month=tonumber(string.sub(time2,6,7)), day=tonumber(string.sub(time2,9,10)), hour=tonumber(string.sub(time2,12,13)), min=tonumber(string.sub(time2,15,16)), sec=tonumber(string.sub(time2,18,19))}) - end - end - -- Check if time1 and time2 are in the right format - if string.len(time1) == 19 and string.len(time2) == 19 then - timed = os.difftime(os.time{year=tonumber(string.sub(time1,1,4)), month=tonumber(string.sub(time1,6,7)), day=tonumber(string.sub(time1,9,10)), hour=tonumber(string.sub(time1,12,13)), min=tonumber(string.sub(time1,15,16)), sec=tonumber(string.sub(time1,18,19))},os.time{year=tonumber(string.sub(time2,1,4)), month=tonumber(string.sub(time2,6,7)), day=tonumber(string.sub(time2,9,10)), hour=tonumber(string.sub(time2,12,13)), min=tonumber(string.sub(time2,15,16)), sec=tonumber(string.sub(time2,18,19))}) - end - elseif op == 'DS' then - -- DS -> compute time difference time1-time2 and return result in seconds - if time1==nil or time2==nil then - error("You must to input 2 arguments to use the 'DS' option.") - end - - -- Check if time1 is 'N' ( NOW ) - if time1 == 'N' then - -- Check if time2 is in the right format - if string.len(time2) == 19 then - timed = os.difftime(os.time(),os.time{year=tonumber(string.sub(time2,1,4)), month=tonumber(string.sub(time2,6,7)), day=tonumber(string.sub(time2,9,10)), hour=tonumber(string.sub(time2,12,13)), min=tonumber(string.sub(time2,15,16)), sec=tonumber(string.sub(time2,18,19))}) - return timed - end - end - -- Check if time1 and time2 are in the right format - if string.len(time1) == 19 and string.len(time2) == 19 then - timed = os.difftime(os.time{year=tonumber(string.sub(time1,1,4)), month=tonumber(string.sub(time1,6,7)), day=tonumber(string.sub(time1,9,10)), hour=tonumber(string.sub(time1,12,13)), min=tonumber(string.sub(time1,15,16)), sec=tonumber(string.sub(time1,18,19))},os.time{year=tonumber(string.sub(time2,1,4)), month=tonumber(string.sub(time2,6,7)), day=tonumber(string.sub(time2,9,10)), hour=tonumber(string.sub(time2,12,13)), min=tonumber(string.sub(time2,15,16)), sec=tonumber(string.sub(time2,18,19))}) - return timed - end - end - - if timed then - if timed < 60 then - if timed < 10 then - return string.format("00:00:0%d",timed) - else - return string.format("00:00:%d",timed) - end - end - - local seconds = timed % 60 - local minutes = (( timed - seconds ) / 60 ) - - if minutes < 60 then - if minutes < 10 and seconds < 10 then - return string.format("00:0%d:0%d",minutes,seconds) - elseif minutes < 10 then - return string.format("00:0%d:%d",minutes,seconds) - elseif seconds < 10 then - return string.format("00:%d:0%d",minutes,seconds) - else - return string.format("00:%d:%d",minutes,seconds) - end - end - - minutes = minutes % 60 - local houres = ((( timed - seconds ) / 60 ) - minutes ) / 60 - - if minutes < 10 and seconds < 10 then - return string.format("%d:0%d:0%d",houres,minutes,seconds) - elseif minutes < 10 then - return string.format("%d:0%d:%d",houres,minutes,seconds) - elseif seconds < 10 then - return string.format("%d:%d:0%d",houres,minutes,seconds) - else - return string.format("%d:%d:%d",houres,minutes,seconds) - end - end - - return nil -end - -------------------------------------------------------------------------------- --- WriteClientDisconnect --- Dumps Client into Dbase at Disconnect or end of round --- This function really dumps everything by calling our two helper functions -------------------------------------------------------------------------------- -function WriteClientDisconnect( _clientNum, _now, _timediff ) - if tonumber(et.trap_Cvar_Get( "gamestate" )) ~= 1 then -- in warmup no db interaction - - if slot[_clientNum]["team"] == false then - slot[_clientNum]["uci"] = et.gentity_get( _clientNum ,"sess.uci") - -- In this case the player never entered the game world, he disconnected during connection time - - -- TODO : check if this works. Is the output from 'D' option in the needed format for the database? - DBCon:SetPlayerSessionWCD( slot[_clientNum]["pkey"], _clientNum, map, slot[_clientNum]["ip"], "0", slot[_clientNum]["start"], timehandle('N'), timehandle('D','N',slot[_clientNum]["start"]), slot[_clientNum]["uci"] ) - - - et.G_LogPrint( "Noq: saved player ".._clientNum.." to Database\n" ) - else - -- The player disconnected during a valid game session. We have to close his playing time - -- If "team" == -1 means we already closed the team time, so we don't have to do it again - -- This is needed to stop team time at map end, when debriefing starts - if slot[_clientNum]["team"] ~= -1 then - closeTeam ( _clientNum ) - end - - -- Write to session if player was in game - saveSession ( _clientNum ) - savePlayer ( _clientNum ) - et.G_LogPrint( "Noq: saved player and session ".._clientNum.." to Database\n" ) - - end - slot[_clientNum]["ntg"] = false - - end -end - -------------------------------------------------------------------------------- --- savePlayer --- Dumps into player table - NO SESSIONDUMPING --- call if you changed something important to secure it in database --- eg Xp, Level, Ban, Mute --- is also called at every Disconnect -------------------------------------------------------------------------------- -function savePlayer ( _clientNum ) - slot[_clientNum]["ip"] = et.Info_ValueForKey( et.trap_GetUserinfo( _clientNum ), "ip" ) - if slot[_clientNum]["ip"] == "localhost" then - -- He is a bot, mark it's ip as "localhost" - slot[_clientNum]["ip"] = "127.0.0.1" - else - s,e,slot[_clientNum]["ip"] = string.find(slot[_clientNum]["ip"],"(%d+%.%d+%.%d+%.%d+)") - end - - if slot[_clientNum]["xpset"] == false and xprestore == 1 then - et.G_LogPrint("NOQ: ERROR while setting xp in database: XP not properly restored!\n") - return - end - - -- We also write to player, for our actual data - -- TODO - -- slot[_clientNum]["user"] - -- slot[_clientNum]["password"] - -- slot[_clientNum]["email"] - -- slot[_clientNum]["netname"] ???? - - local name = string.gsub(slot[_clientNum]["netname"],"\'", "\\\'") - - if slot[_clientNum]["muteexpire"] ~= "1000-01-01 00:00:00" and timehandle( 'DS', 'N', slot[_clientNum]["muteexpire"] ) > 0 then - slot[_clientNum]["mutedby"] = "" - slot[_clientNum]["mutedreason"] = "" - slot[_clientNum]["muteexpire"] = "1000-01-01 00:00:00" - end - slot[_clientNum]["xp0"] = et.gentity_get(_clientNum,"sess.skillpoints",0) - slot[_clientNum]["xp1"] = et.gentity_get(_clientNum,"sess.skillpoints",1) - slot[_clientNum]["xp2"] = et.gentity_get(_clientNum,"sess.skillpoints",2) - slot[_clientNum]["xp3"] = et.gentity_get(_clientNum,"sess.skillpoints",3) - slot[_clientNum]["xp4"] = et.gentity_get(_clientNum,"sess.skillpoints",4) - slot[_clientNum]["xp5"] = et.gentity_get(_clientNum,"sess.skillpoints",5) - slot[_clientNum]["xp6"] = et.gentity_get(_clientNum,"sess.skillpoints",6) - slot[_clientNum]["xptot"] = slot[_clientNum]["xp0"] + slot[_clientNum]["xp1"] + slot[_clientNum]["xp2"] + slot[_clientNum]["xp3"] + slot[_clientNum]["xp4"] + slot[_clientNum]["xp5"] + slot[_clientNum]["xp6"] - - DBCon:SetPlayerInfo( slot[_clientNum] ) - -end - -------------------------------------------------------------------------------- --- saveSession --- Dumps the sessiondata --- should only be used on session-end to not falsify sessions -------------------------------------------------------------------------------- -function saveSession( _clientNum ) - if recordbots == 0 and slot[_clientNum]["isBot"] == 1 then - et.G_LogPrint( "Noq: not saved bot session ".._clientNum.." to Database" ) - return - end - - -- TODO: fixme sqlite only ? - -- TODO: think about moving these vars into client structure earlier ... - slot[_clientNum]["uci"] = et.gentity_get( _clientNum ,"sess.uci") - slot[_clientNum]["ip"] = et.Info_ValueForKey( et.trap_GetUserinfo( _clientNum ), "ip" ) - - if slot[_clientNum]["ip"] == "localhost" then - -- He is a bot, mark it's ip as "localhost" - slot[_clientNum]["ip"] = "127.0.0.1" - else - s,e,slot[_clientNum]["ip"] = string.find(slot[_clientNum]["ip"],"(%d+%.%d+%.%d+%.%d+)") - end - - -- If player was ingame, we really should save his XP to! - -- TODO: think about updating this into client structure at runtime - -- The final questions is: Do we need the XP stuff at runtime in the client structure ? - slot[_clientNum]["xp0"] = et.gentity_get(_clientNum,"sess.skillpoints",0) - slot[_clientNum]["xp1"] = et.gentity_get(_clientNum,"sess.skillpoints",1) - slot[_clientNum]["xp2"] = et.gentity_get(_clientNum,"sess.skillpoints",2) - slot[_clientNum]["xp3"] = et.gentity_get(_clientNum,"sess.skillpoints",3) - slot[_clientNum]["xp4"] = et.gentity_get(_clientNum,"sess.skillpoints",4) - slot[_clientNum]["xp5"] = et.gentity_get(_clientNum,"sess.skillpoints",5) - slot[_clientNum]["xp6"] = et.gentity_get(_clientNum,"sess.skillpoints",6) - slot[_clientNum]["xptot"] = slot[_clientNum]["xp0"] + slot[_clientNum]["xp1"] + slot[_clientNum]["xp2"] + slot[_clientNum]["xp3"] + slot[_clientNum]["xp4"] + slot[_clientNum]["xp5"] + slot[_clientNum]["xp6"] - - DBCon:SetPlayerSession( slot[_clientNum], map, _clientNum ) -end - -------------------------------------------------------------------------------- --- gotCmd --- determines and prepares the arguments for our Shrubcmds -------------------------------------------------------------------------------- -function gotCmd( _clientNum, _command, _vsay) - local argw = {} - local arg0 = string.lower(et.trap_Argv(0)) - local arg1 = string.lower(et.trap_Argv(1)) - local arg2 = string.lower(et.trap_Argv(2)) - local argcount = et.trap_Argc() - - local cmd - -- TODO: we should use level from Lua client model - local lvl = tonumber(et.G_shrubbot_level( _clientNum ) ) - local realcmd - silent = false --to check in subfunctions if its a silent cmd - - if _vsay == nil then -- silent cmd - cmd = string.sub(arg0 ,2) - argw[1] = arg1 - argw[2] = arg2 - argw[3] = et.ConcatArgs( 3 ) - silent = true - elseif _vsay == false then -- normal say - cmd = string.sub(arg1 ,2) - argw[1] = arg2 - argw[2] = et.trap_Argv(3) - argw[3] = et.ConcatArgs( 4 ) - else -- its a vsay! - cmd = string.sub(arg2 ,2) - argw[1] = et.trap_Argv(3) - argw[2] = et.trap_Argv(4) - argw[3] = et.ConcatArgs( 5 ) - end - - -- thats a hack to clearly get the second parameter. - -- NQ-Gui chat uses cvars to pass the say-content - if string.find(cmd, " ") ~= nil then - t = justWords(cmd) - cmd = t[1] - table.remove(t ,1 ) - argw = t - if t[1] == nil then t[1] = "" end - if t[2] == nil then t[2] = "" end - if t[3] == nil then t[3] = "" end - - end - - -- We search trought the commands-array for a suitable command - for i=lvl, 0, -1 do - if commands["cmd"][i][cmd] ~= nil then - if cmd == 'help' then - if argw[1] == "" then - et.trap_SendConsoleCommand(et.EXEC_APPEND, "csay ".. _clientNum .. " \"^FFor NOQ help type !cmdlist.. \"") - else - for i=lvl, 0, -1 do - if commands["hlp"][i][argw[1]] ~= nil then - helpCmd( _clientNum, argw[1], i) - return 1 - end - end - end - else - execCmd(_clientNum, commands["cmd"][i][cmd], argw) - if _vsay == nil then - return 1 - end - end - return - end - end -end - -------------------------------------------------------------------------------- --- justWords --- Splits a string into a table on occurence of Whitespaces -------------------------------------------------------------------------------- -function justWords( _str ) - local t = {} - local function helper(word) table.insert(t, word) return "" end - if not _str:gsub("%S+", helper):find"%S" then return t end -end - -------------------------------------------------------------------------------- --- helpCmd --- prints help from custom commands --- -------------------------------------------------------------------------------- -function helpCmd(_clientNum , cmd, i, fullmsg) - -- Colors same as in NQ - local tc = "^D" -- title color - local nc = "^Y" -- text color - local hc = "^R" -- highlight color - et.trap_SendConsoleCommand(et.EXEC_NOW, "qsay \"".. slot[_clientNum]["netname"] .. "^7: ^2!help " .. cmd .. "\"") - et.trap_SendServerCommand( _clientNum,"print \"" .. tc .. "help: " .. nc .. "NOQ help for '" .. hc .. cmd .. nc .. "':\n\"") - et.trap_SendServerCommand( _clientNum,"print \"" .. tc .. "Function: " .. nc .. commands["hlp"][i][cmd] .. "\n\"") - et.trap_SendServerCommand( _clientNum,"print \"" .. tc .. "Syntax: " .. hc .. commands["syn"][i][cmd] .. "\n\"") -end -------------------------------------------------------------------------------- --- execCmd --- The real work to exec a cmd is done here, all substitutions and the switch for --- Lua and shellcommands are done here -------------------------------------------------------------------------------- -function execCmd(_clientNum , _cmd, _argw) - local str = _cmd - local lastkilled = slot[_clientNum]["victim"] - local lastkiller = slot[_clientNum]["killer"] - - if lastkilled == 1022 then - nlastkilled = "World" - elseif lastkilled == -1 then -- well, fresh player... - lastkilled = _clientNum - nlastkilled = "nobody" - elseif lastkilled == _clientNum then - nlastkilled = "myself" - else - nlastkilled = et.gentity_get(lastkilled, "pers.netname") - end - - if lastkiller == 1022 then - nlastkiller = "World" - if slot[_clientNum]["deadwep"] == 'FALLING' then - nlastkiller = "\'Newton\'s third law\'" - end - elseif lastkiller == -1 then - lastkiller = _clientNum - nlastkiller = "nobody" - elseif lastkiller == _clientNum then - nlastkiller = "myself" - else - nlastkiller = et.gentity_get(lastkiller, "pers.netname") - end - - local otherplayer = _argw[1] - - local assume = false - otherplayer = getPlayerId(otherplayer) - if otherplayer == nil then - otherplayer = _clientNum - assume = true - end - - local t = tonumber(et.gentity_get(_clientNum,"sess.sessionTeam")) - local c = tonumber(et.gentity_get(_clientNum,"sess.latchPlayerType")) - local str = string.gsub(str, "", _clientNum) - local str = string.gsub(str, "", slot[_clientNum]["pkey"]) - local str = string.gsub(str, "", slot[_clientNum]["netname"]) - local str = string.gsub(str, "", slot[_clientNum]["level"] ) - local str = string.gsub(str, "", slot[_clientNum]["cleanname"]) - local str = string.gsub(str, "", class[c]) - local str = string.gsub(str, "", team[t]) - local str = string.gsub(str, "", table.concat(_argw , " ") ) - local str = string.gsub(str, "", _argw[1] ) - local str = string.gsub(str, "", _argw[2] ) - local str = string.gsub(str, "", _argw[3] ) - local str = string.gsub(str, "", lastkiller ) - local str = string.gsub(str, "", et.Q_CleanStr( nlastkiller )) - local str = string.gsub(str, "", nlastkiller ) - local str = string.gsub(str, "", slot[_clientNum]["deadwep"]) - local str = string.gsub(str, "", lastkilled ) - local str = string.gsub(str, "", et.Q_CleanStr( nlastkilled )) - local str = string.gsub(str, "", nlastkilled ) - local str = string.gsub(str, "", slot[_clientNum]["killwep"]) - local str = string.gsub(str, "", serverid ) - - --TODO Implement them (Most of them are from Kmod/EtAdmin) - -- Other possible Variables: - -- local str = string.gsub(str, "", calculate! ) - --local str = string.gsub(str, "", pnameID) - --local str = string.gsub(str, "", PBpnameID) - --local str = string.gsub(str, "", PBID) - --local str = string.gsub(str, "", randomC) - --local str = string.gsub(str, "", randomCName) - --local str = string.gsub(str, "", randomName) - --local str = string.gsub(str, "", randomClass) - --local str = string.gsub(str, "", randomTeam) - --local teamnumber = tonumber(et.gentity_get(PlayerID,"sess.sessionTeam")) - --local classnumber = tonumber(et.gentity_get(PlayerID,"sess.latchPlayerType")) - --- if otherplayer == _clientNum then -- "light security" to not ban or kick yourself (use only ids to ban or kick, then its safe) - if assume == true then - str = string.gsub(str, "", "65" ) - str = string.gsub(str, "", "65" ) - end - - --else - local t = tonumber(et.gentity_get(otherplayer,"sess.sessionTeam")) - local c = tonumber(et.gentity_get(otherplayer,"sess.latchPlayerType")) - str = string.gsub(str, "", class[c]) - str = string.gsub(str, "", team[t]) - str = string.gsub(str, "", et.gentity_get(otherplayer, "pers.netname" )) - str = string.gsub(str, "", otherplayer ) - str = string.gsub(str, "", otherplayer + 1 ) - str = string.gsub(str, "", et.Info_ValueForKey( et.trap_GetUserinfo( otherplayer ), "cl_guid" )) - str = string.gsub(str, "", et.G_shrubbot_level (otherplayer) ) - str = string.gsub(str, "", et.Q_CleanStr(et.gentity_get(otherplayer,"pers.netname"))) - str = string.gsub(str, "", slot[_clientNum]["ip"] ) - - --added for !afk etc, use when assume is ok - str = string.gsub(str, "", otherplayer ) - - -- This allows execution of lua-code in a normal Command. - if string.sub(str, 1,5) == "$LUA$" then - --et.G_Print(string.sub(str,6)) - local tokall = loadstring(string.sub(str,6)) - tokall() - return - elseif string.sub(str, 1,5) == "$SHL$" then - -- This allows Shell commands. WARNING: As long as lua waits for the command to complete, NQ+ET aren't responding to anything, they are HALTED! - -- Response of the Script is piped into NQ-Console(via print, so no commands) - execthis = io.popen(string.sub(str,6)) - myreturn = execthis:read("*a") - execthis:close() - myreturn = string.gsub(myreturn, "\n","\"\nqsay \"") - et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \" ".. myreturn .. " \"") - else - -- well, at the end we send the command to the console - et.trap_SendConsoleCommand( et.EXEC_APPEND, "".. str .. "\n " ) - - end - -end - -------------------------------------------------------------------------------- --- getPlayerId --- helper function to compute the clientid matching a part-string or the clientid -------------------------------------------------------------------------------- -function getPlayerId( _name ) - -- if it's nil, return nil - if (_name == "") or _name == nil then - return nil - end - - -- if it's a number, interpret as slot number - local clientnum = tonumber(_name) - if clientnum then - if (clientnum <= maxclients) and tonumber(et.gentity_get(clientnum,"inuse")) == 1 then - return clientnum - else - return nil - end - end - - local test = et.ClientNumberFromString( _name ) -- Cool NQ function! - if test == -1 then - return nil - else - return test - end -end - -------------------------------------------------------------------------------- --- parseconf --- Parses commandos from commandofile function -------------------------------------------------------------------------------- -function parseconf() - local datei = io.open ( (scriptpath .. "noq_commands.cfg" ) ,"r") - - -- Shrub uses only 31 Levels. at least wiki says - commands["cmd"] = {} - commands["syn"] = {} - commands["hlp"] = {} - commands["listing"] = {} - for i=0, 31, 1 do - commands["cmd"][i] = {} - commands["syn"][i] = {} - commands["hlp"][i] = {} - end - - local nmr = 1 - local nmr2 = 1 - local lasti = nil - local lastcmd = nil - for line in datei:lines() do - local filestr = line - local testcase = string.find(filestr, "^%s*%#") - if testcase == nil then - local testcase = string.find(filestr, "^%s*%w+%s*%=%s*") - if testcase ~= nil then - debugPrint("logprint",filestr) - - for helptype, helptext in string.gfind(filestr, "^*%s*(%w+)%s*%=%s*(.*)[^%\n]*") do - debugPrint("logprint",helptext) - if helptype == "help" then - commands["hlp"][lasti][lastcmd] = helptext - else - commands["syn"][lasti][lastcmd] = helptext - end - end - else - for level,comm,commin in string.gfind(filestr, "^*([0-9]*)%s*%-%s*(%w+)%s*%=%s*(.*)[^%\n]*") do - -- et.G_LogPrint ("Parsing CMD:"..comm .. " Level: "..level.." Content: ".. commin .."\n") - i = tonumber(level) - commands["cmd"][i][comm] = commin - commands["hlp"][i][comm] = "n/a" - commands["syn"][i][comm] = "n/a" - - nmr = nmr +1 - lasti = i - lastcmd = comm - end - end - end - nmr2 = nmr2 +1 - end - - datei:close() - et.G_LogPrint("NOQ: Parsed " ..nmr .." commands from "..nmr2.." lines. \n") -end - -------------------------------------------------------------------------------- --- Init NOQ function -------------------------------------------------------------------------------- -function initNOQ () - -- get all we need at gamestart from game - gstate = tonumber(et.trap_Cvar_Get( "gamestate" )) - map = tostring(et.trap_Cvar_Get("mapname")) -end - -------------------------------------------------------------------------------- --- getDBVersion --- Checks for correct DBVersion --- Disables DBaccess on wrong version! -------------------------------------------------------------------------------- -function getDBVersion() - -- Check the database version - local versiondb = DBCon:GetVersion() - - if versiondb == version then - databasecheck = 1 - et.G_LogPrint("NOQ: Database "..DBCon.dbname.." is up to date. Script version is ".. version .."\n") - else - et.G_LogPrint("NOQ: Database "..DBCon.dbname.." is not up to date: DBMS support disabled! Requested version is ".. version .."\n") - -- We don't need to keep the connection with the database open - DBCon:DoDisconnect() - end -end - -------------------------------------------------------------------------------- --- updateTeam --- set times accordingly when the player changes team -------------------------------------------------------------------------------- -function updateTeam( _clientNum ) - local teamTemp = tonumber(et.gentity_get(_clientNum,"sess.sessionTeam")) - - if teamTemp ~= tonumber(slot[_clientNum]["team"]) then -- now we have teamchange!!! - if debug == 1 then - if tonumber(slot[_clientNum]["team"]) ~= nil and teamTemp ~= nil then - debugPrint("cpm","TEAMCHANGE: " .. team[tonumber(slot[_clientNum]["team"])] .. " to " .. team[teamTemp]) - end - end - - closeTeam ( _clientNum ) - -- Now, we change the teamchangetime & team - slot[_clientNum]["lastTeamChange"] = (et.trap_Milliseconds() / 1000 ) - slot[_clientNum]["team"] = teamTemp - end -end - -------------------------------------------------------------------------------- --- closeTeam --- closes a time session for a player -------------------------------------------------------------------------------- -function closeTeam( _clientNum ) - if tonumber(slot[_clientNum]["team"]) == 1 then -- axis - slot[_clientNum]["axtime"] = slot[_clientNum]["axtime"] +( (et.trap_Milliseconds() / 1000) - slot[_clientNum]["lastTeamChange"] ) - elseif tonumber(slot[_clientNum]["team"]) == 2 then -- allies - slot[_clientNum]["altime"] = slot[_clientNum]["altime"] +( (et.trap_Milliseconds() / 1000) - slot[_clientNum]["lastTeamChange"] ) - elseif tonumber(slot[_clientNum]["team"]) == 3 then -- Spec - slot[_clientNum]["sptime"] = slot[_clientNum]["sptime"] +( (et.trap_Milliseconds() / 1000) - slot[_clientNum]["lastTeamChange"] ) - end - - -- Set the player team to -1 so we know he cannot to change team anymore - slot[_clientNum]["team"] = -1 -end - -------------------------------------------------------------------------------- --- mail functions -------------------------------------------------------------------------------- -function sendMail( _to, _subject, _text ) - if mail == 1 then - -- TODO: clean up - local mailserv = getConfig("mailserv") - local mailport = getConfig("mailport") - local mailfrom = getConfig("mailfrom") - rcpt = _to - -- end clean up - - mesgt = { - headers = { - to = _to, - subject = _subject - }, - body = _text - } - - - r, e = smtp.send { - from = mailfrom, - rcpt = rcpt, - source = smtp.message(mesgt), - --user = "", - --password = "", - server = mailserv, - port = mailport - } - - if (e) then - et.G_LogPrint("NOQ: Could not send email: "..e.. "\n") - end - else - et.G_LogPrint("NOQ: Mails disabled.\n") - end -end - -------------------------------------------------------------------------------- --- checkBalance ( force ) --- Checks for uneven teams and tries to even them --- force is a boolean controlling if there is only an announcement or a real action is taken. --- Action is taken if its true. -------------------------------------------------------------------------------- -function checkBalance( _force ) - -- TODO: Do we need extra tables to store this kind of data ? - local axis = {} -- is this a field required? - local allies = {} -- is this a field required? - local numclients = 0 - - for i=0, et.trap_Cvar_Get( "sv_maxclients" ) -1, 1 do - if slot[i]["inuse"] then - local team = tonumber(et.gentity_get(i,"sess.sessionTeam")) - if team == 1 then - table.insert(axis,i) - end - if team == 2 then - table.insert(allies,i) - end - - numclients = numclients + 1 - end - end - - - local numaxis = # axis - local numallies = # allies - local greaterteam = 3 - local smallerteam = 3 - local gtable = {} - local teamchar = { "r" , "b" , "s" } - - if numaxis > numallies then - greaterteam = 1 - smallerteam = 2 - gtable = axis - end - if numallies > numaxis then - greaterteam = 2 - smallerteam = 1 - gtable = allies - end - - - if math.abs(numaxis - numallies) >= 5 then - evener = evener +1 - if _force == true and evener >= 2 then - et.trap_SendConsoleCommand( et.EXEC_NOW, "!shuffle " ) - et.trap_SendConsoleCommand( et.EXEC_APPEND, "cpm \"^2EVENER: ^1TEAMS SHUFFLED \" " ) - else - et.trap_SendConsoleCommand( et.EXEC_APPEND, "cpm \"^1EVEN TEAMS OR SHUFFLE \" " ) - end - return - end - - if math.abs(numaxis - numallies) >= 3 then - evener = evener +1 - if _force == true and evener >= 3 then - local rand = math.random(# gtable) - local cmd = "!put ".. gtable[rand] .." "..teamchar[smallerteam].." \n" - --et.G_Print( "CMD: ".. cmd .. "\n") - et.trap_SendConsoleCommand( et.EXEC_APPEND, cmd ) - et.trap_SendServerCommand(-1 , "chat \"^2EVENER: ^7Thank you, ".. slot[gtable[rand]]["netname"] .." ^7for helping to even the teams. \" ") - else - et.trap_SendConsoleCommand( et.EXEC_APPEND, "chat \"^2EVENER: ^1Teams seem unfair, would someone from ^2".. team[greaterteam] .."^1 please switch to ^2"..team[smallerteam].."^1? \" " ) - end - - return - else - evener = 0 - end -end - -------------------------------------------------------------------------------- --- greetClient - greets a client after his first clientbegin --- only call after netname is set! -------------------------------------------------------------------------------- -function greetClient( _clientNum ) - local lvl = tonumber(slot[_clientNum]["level"]) - if greetings[lvl] ~= nil then - et.trap_SendConsoleCommand(et.EXEC_APPEND, "cpm " .. string.gsub(greetings[lvl], "", slot[_clientNum]["netname"]) .. "\n") - end -end - -------------------------------------------------------------------------------- --- checkOffMesg - checks for OfflineMessages --- Player needs to be registered to use OM -------------------------------------------------------------------------------- -function checkOffMesg (_clientNum) - if slot[_clientNum]["user"] ~= "" then - -- he is registered - local OM = DBCon:GetLogTypefor("5", slot[_clientNum]["pkey"]) - - if OM ~= nil then - -- he has OMs!!!!!!!!1!!!! - et.trap_SendServerCommand(_clientNum, "print \"\n^3*** ^1NEW OFFLINEMESSAGES ^3***\"") - et.trap_SendServerCommand(_clientNum, "cpm \"^3*** ^1NEW OFFLINEMESSAGES ^3***\"") - et.trap_SendServerCommand(_clientNum, "chat \"^3*** ^1NEW OFFLINEMESSAGES ^3***\"") - - --TODO: fix sound to be only heard by this client. - local sndin = et.G_SoundIndex( "sound/misc/pm.wav" ) - et.G_Sound( _clientNum, sndin ) - - for mesnum = 1, #OM, 1 do - local xml = OM[mesnum].textxml - local posstart , posend = string.find(xml, "", 1) - local msg = string.sub(xml , posstart+5 , (#xml- 12)) - posstart , posend = string.find(xml, ".*", 1) - local from = string.sub(xml, posstart+6, posend-7) - - et.trap_SendServerCommand(_clientNum, "print \"\n^3*** ^1MESSAGE ^R".. mesnum .."^3***\"") - et.trap_SendServerCommand(_clientNum, "print \"\n^3*** ^YFrom: ^R".. from .." ^YMSGID: ^R".. OM[mesnum].id .." ^3***\"") - et.trap_SendServerCommand(_clientNum, "print \"\n^3*** ^YDate: ".. OM[mesnum].createdate .." ^3***\"") - et.trap_SendServerCommand(_clientNum, "print \"\n^3*** ^YMessage: ".. msg .." ^3***\n\"") - end - - et.trap_SendServerCommand(_clientNum, "print \"\n^3*** Erase messages with /rmom MSGID ^3***\n\"") - - else - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. _clientNum .. "\"^3No new offlinemessages\"\n") - end - else - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. _clientNum .. "\"^3To use offlinemessages, please register\"\n") - end - -end - -------------------------------------------------------------------------------- --- sendOffMesg - sends a Offlinemessage --- Player needs to be registered to use OM -------------------------------------------------------------------------------- -function sendOffMesg (_sender,_receiver, _msg) - --TODO: Escape function - _receiver = string.gsub(_receiver,"\'", "\\\'") - _msg = string.gsub(_msg,"\'", "\\\'") - - if slot[_sender]["user"] ~= "" then - -- he is registered - - if _receiver ~= "" and _msg ~= "" then - - player = DBCon:GetPlayerbyReg(_receiver) - if player ~= nil then - -- Reveiver is existing - message = ""..slot[_sender]["user"].."".. player["user"] .."
".._msg.."
" - -- type receiver sender text - DBCon:SetLogEntry( "5", player['pkey'], slot[_sender]['pkey'], message) - - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. _sender .. "\"^3 Following message was sent to '".._receiver.."("..player['cleanname']..")'\"\n") - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. _sender .. "\"^3 '".. _msg .."'\n\"\n") - - else - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. _sender .. "\"^3Nobody registered the name'".. _receiver .."', so i cannot send him a message.\"\n") - end - - else - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. _sender .. "\"^3Check your syntax: ^R'/om receiver message'.\"\n") - end - - else - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay " .. _sender .. "\"^3To use Offlinemessages, please register\"\n") - end - -end - -------------------------------------------------------------------------------- --- getresNames --- get reserved Name patterns from the DB -------------------------------------------------------------------------------- -function getresNames() - - local NMs = DBCon:GetLogTypefor("6", nil, nil) - - if NMs ~= nil then - namearray = {} - for num = 1, #NMs, 1 do - namearray[num] = NMs[num].textxml - end - else - namearray = nil - end -end - -------------------------------------------------------------------------------- --- reserveName --- add a protected string to the Database -------------------------------------------------------------------------------- -function reserveName(_name) - if _name ~= nil and _name ~= "" then - DBCon:SetLogEntry(6, "" , "", _name ) - - if _otherplayer then - et.trap_SendConsoleCommand(et.EXEC_APPEND,"qsay \"^3Added ".._name.." to the protected patterns.\"" ) - et.G_Print("NOQ: Added '".._name.."' to the protected patterns.\"" ) - else - et.G_Print("NOQ: Added '".._name.."' to the protected patterns.\"" ) - end - - end -end - -------------------------------------------------------------------------------- --- checkforResName(clientnum) --- check if the name is reserved -------------------------------------------------------------------------------- -function checkforResName(_clientNum) - if not slot[_clientNum]["netname"] then return end - local cleanname = string.lower(et.Q_CleanStr(slot[_clientNum]["netname"])) - for i,v in ipairs(namearray) do - if string.find( cleanname,v) then - if string.find(slot[_clientNum]["clan"],v) then - -- luck you - you are in the clan/have the name reserved for you - et.G_Print("NOQ: Name for "..slot[_clientNum]["netname"].. " reserved and owned\n") - else - -- oops - rename him - et.trap_SendConsoleCommand(et.EXEC_APPEND, "!rename ".._clientNum.. " ".. string.gsub(cleanname,v, "X") ) - -- TODO: Kick? - et.trap_SendServerCommand( _clientNum, "chat \"^1Your tag/name is reserved or not allowed.\"") - end - end - end -end - -------------------------------------------------------------------------------- --- timeLeft --- Returns rest of time to play -------------------------------------------------------------------------------- -function timeLeft() - return tonumber(et.trap_Cvar_Get("timelimit"))*1000 - ( et.trap_Milliseconds() - mapStartTime) -- TODO: check this! -end - -------------------------------------------------------------------------------- --- pussyFactCheck --- adjusts the Pussyfactor after an kill trough et_obituary --- TODO: Add more cases for ugly teamkills (not only panzer ... knife, poison etc) --- cool weapons get a value < 100 lame weapons/activities > 100 -------------------------------------------------------------------------------- -function pussyFactCheck( _victim, _killer, _mod ) - if pussyfact == 1 then - if slot[_killer]["team"] == slot[_victim]["team"] then -- teamkill - -- here it is teamkill - -- NOTE: teamkill is not counted as a kill, wich means all added here is even stronger in its weight - if _mod == mod["MOD_PANZERFAUST"] or _mod == mod["MOD_BAZOOKA"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 170 - else - slot[_killer]["pf"] = slot[_killer]["pf"] + 110 - end - else -- no teamkill - -- TODO sort this by coolness - if _mod == mod["MOD_KNIFE"] or _mod == mod["MOD_THROWKNIFE"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 70 - elseif _mod == mod["MOD_PANZERFAUST"] or _mod == mod["MOD_BAZOOKA"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 140 - elseif _mod == mod["MOD_FLAMETHROWER"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 115 - elseif _mod == mod["MOD_POISON"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 65 - elseif _mod == mod["MOD_GOOMBA"] or _mod == mod["MOD_DYNAMITE"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 60 - elseif _mod == mod["MOD_KICKED"] or _mod == mod["MOD_BACKSTAB"] or _mod == mod["MOD_SHOVE"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 40 - elseif _mod == mod["MOD_K43_SCOPE"] or _mod == mod["MOD_FG42_SCOPE"] or _mod == mod["MOD_GARAND_SCOPE"] then - slot[_killer]["pf"] = slot[_killer]["pf"] + 90 - else - -- if we count 100 up, nothing changes. at least it should - slot[_killer]["pf"] = slot[_killer]["pf"] + 100 - end - end -- teamkill end - - end -- pussy end -end - -------------------------------------------------------------------------------- --- checkTKPoints --- Check if we need to punish a teamkiller -------------------------------------------------------------------------------- -function checkTKPoints(_clientNum) - - --[[ - TODO - --]] - -end - -------------------------------------------------------------------------------- --- sendtoIRCRelay --- Will send a string to our IRC-Relay -------------------------------------------------------------------------------- -function sendtoIRCRelay(_txt) - - local res = client:send(_txt.."\n") - - if not res then - debugPrint("logprint","send " .. "error") - else - debugPrint("logprint","send " .. _txt) - end - -end - -------------------------------------------------------------------------------- --- nPrint(_whom , _what) --- Will print _what to _whom --- _whom can be: -1 - Console --- 0 - 64 - Player(private) --- 65 - Everyone --- --- _what can be: --- String --- Array of Strings --- --- Note: Please dont use an table of tables - it will fail displaying strange numbers :) -------------------------------------------------------------------------------- -function nPrint(_whom, _what) - -local mytype = type(_what) - if _whom == -1 then - --console - if mytype == "string" then - et.G_LogPrint(_what) - elseif mytype == "table" then - for i,v in ipairs(_what) do - et.G_LogPrint(v) - end - end - - elseif _whom >= 0 and _whom <= 63 then - -- player - if mytype == "table" then - for i,v in ipairs(_what) do - et.trap_SendConsoleCommand(et.EXEC_APPEND,"csay ".. _whom .. " \"".. v .."\"\n " ) - end - elseif mytype == "string" then - et.trap_SendConsoleCommand(et.EXEC_APPEND,"csay ".. _whom .. " \"".. _what .."\"\n " ) - end - else - --everybody - if mytype == "string" then - et.trap_SendConsoleCommand(et.EXEC_APPEND,"qsay \"".. _what .."\"\n " ) - elseif mytype == "table" then - for i,v in ipairs(_what) do - et.trap_SendConsoleCommand(et.EXEC_APPEND,"qsay \"".. v .."\"\n " ) - end - end - - end -end - - ---*************************************************************************** --- Here start the commands usually called trough the new command-system --- they shouldn't change internals, they are more informative or helpfull ---*************************************************************************** --- Currently available: --- printPlyrInfo --- setLevel --- addClan --- cleanSession --- pussyout --- checkBalance --- rm_pbalias --- teamdamage --- showmaps --- listcmds --- msgtoIRC --- forAll --- showTkTable - -------------------------------------------------------------------------------- --- printPlyrInfo(_whom, _about) --- will print Info about player _about to player _whom --- mimics !finger command if called from a silent !cmd -------------------------------------------------------------------------------- -function printPlyrInfo(_whom, _about) - - local mit = {} - - -- silent cmds dont display the !finger from shrub afterwards.... - if silent then - table.insert( mit , "^dInfo about: ^r" .. slot[_about]["netname"] .. " ^r/ ^7" .. slot[_about]["cleanname"] .. "^r:" ) - table.insert( mit , "^dSlot: ^r" .. _about ) - table.insert( mit , "^dAdmin: ^r" .. slot[_about]["level"] ) - table.insert( mit , "^dGuid: ^r" .. slot[_about]["pkey"] ) - table.insert( mit , "^dIP: ^r" .. slot[_about]["ip"] ) - end - - table.insert( mit , "^dNOQ Info: " ) - - if slot[_about]["user"] ~= "" then - table.insert( mit , "^dUsername: ^r" .. slot[_about]["user"] ) - end - - table.insert( mit , "^dFirst seen: ^r" .. slot[_about]["createdate"]) - table.insert( mit , "^dLast seen: ^r" .. slot[_about]["updatedate"]) - table.insert( mit , "^dSpree: ^r" .. slot[_about]["kspree"] ) - - if slot[_about]["locktoTeam"] ~= nil then - table.insert( mit , "^dTeamlock: ^r" .. teamchars[slot[_about]["locktoTeam"]] ) - if slot[_about]["lockedTeamTill"] ~= 0 then - table.insert( mit , "^dSecs remain:^r" .. (slot[_about]["lockedTeamTill"] - (et.trap_Milliseconds() /1000 )) ) - end - end - - if slot[_about]["mutedby"] ~= "" then - table.insert( mit , "^dMuted by: ^7" .. slot[_about]["mutedby"]) - table.insert( mit , "^dReason: ^r" .. slot[_about]["mutereason"]) - table.insert( mit , "^dUntil: ^r" .. slot[_about]["muteexpire"]) - end - - if slot[_about]["vsaydisabled"] then - table.insert( mit , "^dHe is not allowed to use vsays") - end - - nPrint(_whom,mit) - -end - -------------------------------------------------------------------------------- --- setLevel(clientnum, level) --- changes a players level -------------------------------------------------------------------------------- -function setLevel(_clientNum, _level) - - slot[_clientNum]['lvl'] = _level - savePlayer( _clientNum ) -end - -------------------------------------------------------------------------------- --- addClan(clientnum, tag) --- adds a Clantag -------------------------------------------------------------------------------- -function addClan(_clientNum, _tag) - slot[_clientNum]['clan'] = slot[_clientNum]['clan'] .. " " .. _tag - savePlayer( _clientNum ) - - if otherplayer then - et.trap_SendConsoleCommand(et.EXEC_APPEND,"qsay \"^3Added ".._tag.." to the patterns for "..slot[_clientNum]['netname']..".\"" ) - et.G_Print("NOQ: Added '".._tag.."' to the patterns for "..et.Q_CleanStr(slot[_clientNum]['netname'])..".\"" ) - else - et.G_Print("NOQ: Added '".._tag.."' to the patterns for "..et.Q_CleanStr(slot[_clientNum]['netname'])..".\"" ) - end -end - - -------------------------------------------------------------------------------- --- cleanSession --- cleans the sessiontable from values older than X months --- _arg for first call is amount of months, second call OK to confirm -------------------------------------------------------------------------------- -function cleanSession(_callerID, _arg) - if arg == "" then - et.trap_SendServerCommand(_callerID, "print \"\n Argument: first call: months to keep records, second call: OK \n\"") - return - end - - if _arg == "OK" then - if months ~= nil and months >= 1 and months <= 24 then - et.trap_SendServerCommand(_callerID, "print \"\n Now erasing all records older than ".. months .." months \n\"") - - DBCon:DoDeleteOldSessions(months) - - et.trap_SendServerCommand(_callerID, "print \"\n Erased all records older than ".. months .." months \n\"") - et.G_LogPrint( "Noq: Erased data older than "..months.." months from the sessiontable\n" ) - if _callerID ~= -1 then - et.G_LogPrint( "Noq: Deletion was issued by: "..slot[_callerID]['netname'].. " , GUID:"..slot[_callerID]['pkey'].. " \n" ) - end - - else - et.trap_SendServerCommand(_callerID, "print \"\n Please at first specify a value between 1 and 24 \n\"") - et.trap_SendServerCommand(_callerID, "print \"\n Example: 1 erases all sessionrecords older than 1 month\n\"") - return - end - - elseif tonumber(_arg) >= 1 and tonumber(_arg) <= 24 then - local months = tonumber(_arg) - et.trap_SendServerCommand(_callerID, "print \"\n Please confirm the deletion of "..months.." month's data with OK as argument of the same command\n\"") - - else - et.trap_SendServerCommand(_callerID, "print \"\n Please specify a value between 1 and 24 \n\"") - return - end - -end - -------------------------------------------------------------------------------- --- pussyout --- Displays the Pussyfactor for Player _ClientNum -------------------------------------------------------------------------------- ---[[ --- Some Documentation for Pussyfactor: --- For every kill, we add a value to the clients number, and to determine the the Pussyfactor, we --- divide that number trough the number of his kills multiplicated with 100. --- If we add 100 for an mp40/thompsonkill, if makes only those kills , he will stay at pussyfactor 1 --- if we add more or less(as 100) to the number, his pf will rise or decline. --- --- Pussyfactor < 1 means he made "cool kills" = poison, goomba, knive --- Pussyfactor = 1 means he makes normal kills --- Pussyfactor > 1 means he does uncool kills (Panzerfaust, teamkills, arty?) --- --- As we add 100 for every normal kill, the pussyfactor approaches 1 after some time with "normal" kills --- ---]] -function pussyout( _clientNum ) - local pf = slot[tonumber(_clientNum)]["pf"] - -- TODO: use client structure slot[tonumber(_clientNum)]["kills"] -- it should be up to date! - local kills = tonumber(et.gentity_get(_clientNum,"sess.kills")) - local realpf = 1 - - if pf == 0 or kills == 0 then - et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^1Do some kills first...\"") - return - else - realpf = string.format("%.1f", ( pf / (100 * kills) ) ) - end - - -- TODO: do we need to number here = - et.trap_SendConsoleCommand(et.EXEC_APPEND,"qsay \""..slot[tonumber(_clientNum)]["netname"].."^3's pussyfactor is at: ".. realpf ..".Higher is worse. \"" ) - et.G_LogPrint("NOQ: PUSSY: "..slot[tonumber(_clientNum)]["netname"].." at ".. realpf .."\n") -end - -------------------------------------------------------------------------------- --- rm_pbalias --- removes all your aliases from the pbalias.dat --- thks to hose! (yeah, this is cool!) -------------------------------------------------------------------------------- -function rm_pbalias( _myClient, _hisClient ) - et.trap_SendServerCommand(-1, "print \"function pbalias entered\n\"") - - local file_name = "pbalias.dat" - local inFile = pbpath .. file_name - local outFile = pbpath .. file_name - - local hisGuid = slot[_hisClient]["pkey"] - local arg1 = string.lower(hisGuid:sub(25, 32)) - - -- all input is evil! check for length! - et.trap_SendServerCommand(_myClient, "print \"\nSearching for Guid: " .. arg1 .. "\"") - local file = assert(io.open( inFile , "r")) - local lineCounter = 0 - local lineTable = {} - local deletedLines = {} - local loopcounter = 0 - - for line in file:lines() do - lineCounter = lineCounter + 1 - if arg1 ~= line:sub(25, 32) then - table.insert(lineTable, line) - else - table.insert(deletedLines, line) - end - end - - local inserted = table.maxn(lineTable) - local deleted = table.maxn(deletedLines) - file:close() - - if deleted > 0 then - -- writing new pbalias.dat - file = assert(io.open(outFile, "w+")) - for i, v in ipairs(lineTable) do - file:write(v .. "\n") - loopcounter = loopcounter + 1 - end - file:flush() - file:close() - end - - -- some status info printed to stdout - et.trap_SendServerCommand(_myClient, "print \"\nEntries processed: " .. lineCounter .. "\"") - et.trap_SendServerCommand(_myClient, "print \"\nEntries deleted: " .. deleted .. "\"") - et.trap_SendConsoleCommand(et.EXEC_NOW, "pb_sv_restart") - - return 1 -end - -------------------------------------------------------------------------------- --- teamdamage --- Displays information about teamdamage to the caller and a small line for all --- thks to hose! -------------------------------------------------------------------------------- -function teamdamage( myclient, slotnumber ) -- TODO: change this to (_myclient, _slotnumber) - local teamdamage = et.gentity_get (slotnumber, "sess.team_damage") - local damage = et.gentity_get(slotnumber, "sess.damage_given") - - local classnumber = et.gentity_get(slotnumber, "sess.playerType") - - -- TODO: use slottable - local teamnumber = et.gentity_get(slotnumber, "sess.sessionTeam") - local teamname = team[teamnumber] - - et.trap_SendServerCommand( myclient, "print \" ^7:" .. et.gentity_get(slotnumber, "pers.netname") .. "^w | Slot: ".. slotnumber .. - "\n" .. class[classnumber] .. " | " .. teamname .. " | " .. weapons[et.gentity_get(slotnumber, "sess.latchPlayerWeapon")] .. " | " .. weapons[et.gentity_get(slotnumber, "sess.latchPlayerWeapon2")] .. - "\nkills: " .. et.gentity_get(slotnumber, "sess.kills") .. " | damage: " .. damage .. - "\nteamkills: " .. et.gentity_get(slotnumber, "sess.team_kills") .. " | teamdamage: " .. teamdamage .. "\n\"") - - -- notorische teambleeder ab ins cp!!! - if teamdamage == 0 then - et.trap_SendServerCommand( slotnumber, "cp \" ^7You got ^1"..teamdamage.." teamdamage ^7and ^2" .. damage .. " damage given! ^1".. getConfig("teamdamageMessage1") .. "\"") - elseif teamdamage < damage/10 then - et.trap_SendServerCommand( slotnumber, "cp \" ^7You got ^1"..teamdamage.." teamdamage ^7and ^2" .. damage .. " damage given! ^1".. getConfig("teamdamageMessage2").. "\"") - elseif teamdamage < damage/5 then - et.trap_SendServerCommand( slotnumber, "cp \" ^7You got ^1"..teamdamage.." teamdamage ^7and ^2" .. damage .. " damage given! ^1".. getConfig("teamdamageMessage3").. "\"") - elseif teamdamage < damage/2 then - et.trap_SendServerCommand( slotnumber, "cp \" ^7You got ^1"..teamdamage.." teamdamage ^7and ^2" .. damage .. " damage given! ^1".. getConfig("teamdamageMessage4").. "\"") - elseif teamdamage < damage then - et.trap_SendServerCommand( slotnumber, "cp \" ^7You got ^1"..teamdamage.." teamdamage ^7and ^2" .. damage .. " damage given! ^1".. getConfig("teamdamageMessage5").. "\"") - else - et.trap_SendServerCommand( slotnumber, "cp \" ^7You got ^1"..teamdamage.." teamdamage ^7and ^2" .. damage .. " damage given! ^1".. getConfig("teamdamageMessage6").. "\"") - end -end - -------------------------------------------------------------------------------- --- showmaps --- Reads the camapaign-info in, then compares with current map, then --- displays all maps and marks the current one -------------------------------------------------------------------------------- -function showmaps() - local ent = et.trap_Cvar_Get( "campaign_maps" ); -- TODO: create and use global var ? - local tat34 = {} - local sep = "," - - -- helper function - function split(str, pat) - local t = {} -- NOTE: use {n = 0} in Lua-5.0 - local fpat = "(.-)" .. pat - local last_end = 1 - local s, e, cap = str:find(fpat, 1) - while s do - if s ~= 1 or cap ~= "" then - table.insert(t,cap) - end - last_end = e+1 - s, e, cap = str:find(fpat, last_end) - end - if last_end <= #str then - cap = str:sub(last_end) - table.insert(t, cap) - end - return t - end - - tat34 = split (ent, sep) - local ent2 = "^3" - - map = tostring(et.trap_Cvar_Get("mapname")) - - -- helper function - local function addit( i, v) - if v == map then - ent2 = ent2 .. "^1" .. v .. "^3 <> " - else - ent2 = ent2 .. v .. " <> " - end - end - - for i,v in ipairs(tat34) do addit(i,v) end - - et.trap_SendConsoleCommand(et.EXEC_APPEND, "chat \"".. ent2 .. "\"") -end - -------------------------------------------------------------------------------- --- listCMDs --- Returns a list of available Noq CMDs -------------------------------------------------------------------------------- -function listCMDs( _Client ,... ) - local lvl = tonumber(et.G_shrubbot_level( _Client ) ) - local allcmds = "\"^F" - local yaAR = {} - - if commands["listing"][lvl] ~= nil then - - else -- we need to generate the listing first - local CMDs = {} - local mxlength = 7 - - for i=lvl, 0, -1 do - for index, cmd in pairs(commands["cmd"][i]) do - if CMDs.index ~= nil then - else - CMDs[index] = index - if #index > mxlength then - mxlength = #index - end - end - end - end - - local formatter = "%- ".. (mxlength + 2) .."s" - - local i = 0 - - for index, cmd in pairs(CMDs) do - yaAR[i] = string.format(formatter, index) - i = i + 1 - end - - et.G_LogPrint("Parsed ".. i .. " commands for lvl " .. lvl .."\n") - commands["listing"][lvl] = yaAR - end - - - yaAR = commands["listing"][lvl] - number = #yaAR - - if arg[1] ~= "" then - _page = tonumber(arg[1]) - else - _page = 0 - end - - if (_page*20) > number then - et.trap_SendConsoleCommand(et.EXEC_APPEND, "csay ".._Client.."\" ^FPlease specify a page between ^20 ^Fand ^2" .. string.format("%.0f", ( number / 20 -1) ) ) - end - - - for i=(_page*20), (_page*20 + 20),4 do - if number - i < 4 then - if number %4 == 1 then - et.trap_SendConsoleCommand(et.EXEC_NOW , "csay ".._Client.."\"^F".. yaAR[i] .. "\"" ) - break - elseif number %4 == 2 then - et.trap_SendConsoleCommand(et.EXEC_NOW , "csay ".._Client.."\"^F".. yaAR[i] .. yaAR[i+1] .. "\"") - break - elseif number %4 == 3 then - et.trap_SendConsoleCommand(et.EXEC_NOW , "csay ".._Client.."\"^F"..yaAR[i] .. yaAR[i+1] .. yaAR[i+2].. "\"" ) - break - end - else - et.trap_SendConsoleCommand(et.EXEC_NOW , "csay ".._Client.."\"^F".. yaAR[i] .. yaAR[i+1] .. yaAR[i+2] .. yaAR[i+3].. "\"") - end - end - - et.trap_SendConsoleCommand(et.EXEC_NOW, "csay ".._Client.."\"^F I parsed " .. number .." commands for you. Access all by adding a page between ^20 ^Fand ^2" .. string.format("%.0f", ( number / 20 -1) ) .. " ^Fto your listingcommand.\"") - - -- TODO: FIX LUA-OUPUT IN C. There is some serious shit going on. Let that intact, it prevents strange failures: - -- Ok, not all failures: try to do !cmdlist at the last page...... - et.trap_SendConsoleCommand(et.EXEC_APPEND, "csay ".. _Client.. "\" \n \"") - et.trap_SendConsoleCommand(et.EXEC_NOW, "") -end - - -------------------------------------------------------------------------------- --- msgtoIRC(player , message) --- Used in LuaCMDs to send a message from player to IRC --- Player can be a number or the Playername -------------------------------------------------------------------------------- -function msgtoIRC(_client,_msg) - - _msg = string.gsub(_msg,'\\', "") - - if type(_client) == "string" then - -- no direct call, it is string && therefore a name from the !command - sendtoIRCRelay(_client .. " on " .. serverid .. ": " .. _msg ); - et.trap_SendConsoleCommand(et.EXEC_APPEND, "chat \" ^3Sent your msg to IRC\n\"") - return - end - - if type(_client) == "number" and slot[_client]["user"] ~= "" then - - sendtoIRCRelay(slot[_client]["user"] .. " on " .. serverid .. ": " .. _msg ); - et.trap_SendConsoleCommand(et.EXEC_APPEND, "csay ".. _client .. "\" ^1Sent: ^3".._msg.." ^3to IRC\"") - return - else - et.trap_SendConsoleCommand(et.EXEC_APPEND, "csay ".. _client .. "\" ^1You need to be registered to send messages to IRC \"") - return - end - - - -end - -------------------------------------------------------------------------------- --- forAll(whom, what) --- will exec a function with parameter clientnum for all specified players --- whom can be: axis/r, allies/b, specs/s, all --- what is the function -------------------------------------------------------------------------------- -function forAll(_whom,_what) - - if _whom == "players" or _whom == "all" then - _whom = nil - elseif _whom == 1 or _whom == "r" or _whom == "axis" then - _whom = 1 - elseif _whom == 2 or _whom == "b" or _whom == "allies" then - _whom = 2 - elseif _whom == 3 or _whom == "s" or _whom == "specs" then - _whom = 3 - end - -for i=0, maxclients, 1 do - if et.gentity_get(i,"classname") == "player" then - local team = tonumber(et.gentity_get(i,"sess.sessionTeam")) - if _whom == nil or team == _whom then - _what(i) - end - end -end - - -end - -------------------------------------------------------------------------------- --- showTkTable ----- --- prints the current TopTen of teamkillers to the caller's console, --- sorted by teamkills and teamdamage --- @author: hose -------------------------------------------------------------------------------- -function showTkTable(_myClient) - - -- tkTable stores the damage stats of all players - local tkTable = {} - - -- building up the teamkiller table - for i=0, maxclients , 1 do - if et.gentity_get(i, "inuse") == 1 then - table.insert(tkTable, getDamageStats(i)) - end - end --end for loop - - -- sort the table by teamkills and within that by teamdamage - -- TODO: not sure how to handle a nil object there. i guess it s wrong - -- to return false, but it works (does not work without) - table.sort(tkTable, - function(_tk1, _tk2) - if _tk1 == nil then - return false - elseif _tk2 == nil then - return false - elseif _tk1["teamkills"] == _tk2["teamkills"] then - return _tk1["teamdamage"] > _tk2["teamdamage"] - else - return _tk1["teamkills"] > _tk2["teamkills"] - end - end) -- end the sorting function - - -- print the top ten table to the caller's console - nPrint(_myClient, "Slot| Name | Class | Tks | TD given ") - loopcount = 0 - for ind, _tkStats in ipairs(tkTable) do - - nPrint(_myClient, "^w" .. string.format("%-4s", _tkStats["srvslot"]) .."|" ..string.format("%-22s", et.Q_CleanStr(_tkStats["name"])) .. "|" ..string.format("%-10s", class[_tkStats["class"]]) .. "|" ..string.format("%-5s", _tkStats["teamkills"]) .. "|" ..string.format("%-10s", _tkStats["teamdamage"])) - - loopcount = loopcount + 1 - if loopcount >= 10 then - break - end - end -end - - -------------------------------------------------------------------------------- --- some convenience Functions for !commands or mod-use -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- --- heal(ClientNum) --- heal a Player -------------------------------------------------------------------------------- -function heal(_clientNum) - et.gentity_set(_clientNum,"health", et.gentity_get(_clientNum,"ps.stats", 4) ) -end - -------------------------------------------------------------------------------- --- healthboost(ClientNum) --- boost a clients HP by 30, even over the maximum -------------------------------------------------------------------------------- -function healthboost(_clientNum) - -- boost clienthealth +30 - no full heal, but perhaps more than allowed hp :) - et.gentity_set(_clientNum,"health", et.gentity_get(_clientNum,"health" ) + 30 ) -end - -------------------------------------------------------------------------------- --- giveammo(ClientNum) --- Fill a clients mainweapons with ammo -------------------------------------------------------------------------------- -function giveammo(_clientNum) - - if et.gentity_get(_clientNum,"sess.sessionTeam") == 1 then - -- axis - et.gentity_set(_clientNum,"ps.ammo", 2, 64 ) -- luger 16 - et.gentity_set(_clientNum,"ps.ammo", 3, 150 ) -- mp40 60 - et.gentity_set(_clientNum,"ps.ammo", 9, 8 ) --nade 4 - et.gentity_set(_clientNum,"ps.ammo", 36, 64 ) --akimbo luger - else - -- allies - et.gentity_set(_clientNum,"ps.ammo", 35, 64 ) --akimbo colt - et.gentity_set(_clientNum,"ps.ammo", 4, 8 ) --nade 4 - et.gentity_set(_clientNum,"ps.ammo", 7, 64 ) -- colt 16 - et.gentity_set(_clientNum,"ps.ammo", 8, 150 ) -- thompson - - end - -end - - -------------------------------------------------------------------------------- --- force(ClientNum, command, whom/command) --- Starwars themed gimmicks -------------------------------------------------------------------------------- -function force(_clientNum, _what , _arg2) - - if disableforce then return end - - if _what == "heal" then - if FPcheck(_clientNum, 15) then - heal(_clientNum) - et.trap_SendConsoleCommand(et.EXEC_APPEND,"chat\""..slot[_clientNum]['netname'].."^3 uses the force to heal himself.\n\"") - end - elseif _what == "push" then - if _arg2 ~= "" and FPcheck(_clientNum, 15) then - et.trap_SendConsoleCommand(et.EXEC_APPEND,"!fling " .. getPlayerId(_arg2) ) - end - elseif _what == "ammo" then - if FPcheck(_clientNum, 15) then - giveammo(_clientNum) - et.trap_SendConsoleCommand(et.EXEC_APPEND,"chat\""..slot[_clientNum]['netname'].."^3 uses the force to replenish his ammo.\n\"") - end - elseif _what == "boost" then - if FPcheck(_clientNum, 15) then - healthboost(_clientNum) - et.trap_SendConsoleCommand(et.EXEC_APPEND,"chat\""..slot[_clientNum]['netname'].."^3 uses the force to boost his health.\n\"") - end - elseif _what == "team" then - - if _arg2 == "heal" or _arg2 == "ammo" or _arg2 == "boost" then - if FPcheck(_clientNum, 50) then - if _arg2 == "boost" then - forAll( tonumber(et.gentity_get(_clientNum,"sess.sessionTeam")) , healthboost) - elseif _arg2 == "ammo" then - forAll( tonumber(et.gentity_get(_clientNum,"sess.sessionTeam")) , giveammo) - elseif _arg2 == "heal" then - forAll( tonumber(et.gentity_get(_clientNum,"sess.sessionTeam")) , heal) - end - et.trap_SendConsoleCommand(et.EXEC_APPEND,"chat\""..slot[_clientNum]['netname'].."^3 uses the force to help his team with a ^2".._arg2..".\n\"") - end - else - et.trap_SendConsoleCommand(et.EXEC_APPEND,"chat\" ^3 You want to do .. what? heal, ammo, boost or push? \n\"") - end - else - et.trap_SendConsoleCommand(et.EXEC_APPEND,"chat\" ^3 You want to do .. what? ^4heal^3, ^4ammo^3, ^4boost ^3or ^4push^3? \n\"") - end - -end - - -------------------------------------------------------------------------------- --- fpcheck(_clientNum, amountneeded ) --- check: Is the force with you? -------------------------------------------------------------------------------- -function FPcheck(_clientNum, _amount) - - if slot[_clientNum]["fpoints"] >= _amount then - slot[_clientNum]["fpoints"] = slot[_clientNum]["fpoints"] - _amount - return true - else - et.trap_SendConsoleCommand(et.EXEC_APPEND , "chat \" ^2To weak, the force in you is, young padawan .. Yes, hmmm. \n\"") - return false - end -end - -------------------------------------------------------------------------------- --- getDamageStats(_clientNum) --- processes a player's data regarding tk, damage, teamdamage etc --- helper function for showTkTable() --- returns a table of several values for the _clientNum to the caller function -------------------------------------------------------------------------------- -function getDamageStats(_clientNum) - - tkStats = {} - - tkStats["name"] = et.gentity_get(_clientNum, "pers.netname") - tkStats["srvslot"] = _clientNum --- tkStats["team"] = et.gentity_get(_clientNum, "sess.sessionTeam") - tkStats["class"] = et.gentity_get(_clientNum, "sess.playerType") --- tkStats["kills"] = et.gentity_get(_clientNum, "sess.kills") - tkStats["teamkills"] = et.gentity_get(_clientNum, "sess.team_kills") - tkStats["teamdamage"] = et.gentity_get(_clientNum, "sess.team_damage") --- tkStats["damage"] = et.gentity_get(_clientNum, "sess.damage_given") - - return tkStats - -end - -------------------------------------------------------------------------------- --- listAliases(_whom , _from ) --- list _froms aliases to _whom -------------------------------------------------------------------------------- -function listAliases(_whom, _from) - if slot[_from]["pkey"] == nil then - nPrint(_whom, "^3Slot not in use? - try the playername.") - return - end - - local aliases = DBCon:GetPlayerAliases(slot[_from]["pkey"]) - local output = {} - if aliases ~= nil then - local nr = 0 - for i, v in pairs(aliases) do -- holy fcking sh*t dont ever use ipairs here :/ - table.insert( output , "^3NOQ: Alias NR" ..string.format("%2i",nr)..": " .. string.format("%22s",et.Q_CleanStr(v)) .. "^7|" .. v ) - nr = nr + 1 - end - - table.insert(output, 1,"^3Player ^7" .. slot[_from]["netname"] .. " ^3has ^7" .. nr .. " ^3different nicks." ) - else - nPrint( _whom, "^3Got no aliases recorded - is namelogging on?") - return - end - nPrint(_whom, output) -end - -------------------------------------------------------------------------------- --- Here does End, kthxbye -------------------------------------------------------------------------------- diff --git a/noq/noq_c.lua b/noq/noq_c.lua deleted file mode 100644 index 88e33ef..0000000 --- a/noq/noq_c.lua +++ /dev/null @@ -1,177 +0,0 @@ --- --- ET Lua SQL console - console.lua (p) 2010 IRATA [*] --- --- --- Execute SQL via the ET server console like --- [commandprefix]sql "select * from players" --- --- Enables faster debugging for SQL based Lua scripts, adds some new options and is nice to have ... --- --- Notes: --- There are limits by the buffer of ET. Avoid very long statements and don't expect you always get the full result printed. --- Keep resultsets short --- --- TODO --- get configurations from noq_config --- test all - --------------------------------------------------------------------------------- -color = "^5" -version = 1 -commandprefix = "!" -debug = 0 -- debug 0/1 -tablespacer = " " -- use something like " " or "|" --------------------------------------------------------------------------------- --- db connection data -dbms = "SQLite" -- possible values "mySQL", "postgreSQL" and "SQLite" -dbname = "noquarter.sqlite" -- also filename for SQLite file -dbuser = "myuser" -dbpassword = "mypassword" --------------------------------------------------------------------------------- -env = nil -con = nil - --- Connect & handle different dbms -if dbms == "mySQL" then - require "luasql.mysql" - env = assert (luasql.mysql()) - con = assert (env:connect( dbname, dbuser, dbpassword, dbhostname, dbport )) -elseif dbms == "SQLite" then - require "luasql.sqlite3" - env = assert (luasql.sqlite3()) - con = assert (env:connect( dbname )) -- this opens OR creates a sqlite db - if this Lua is loaded db is created -fix this? -else - -- stop script - error("DBMS not supported.") -end - -cur = {} -res = {} -row = {} --------------------------------------------------------------------------------- - -function et_InitGame( levelTime, randomSeed, restart ) - - et.RegisterModname( "ET SQL console " .. version .. " " .. et.FindSelf() ) - - if debug == 1 then - et.trap_SendServerCommand( -1 ,"chat \"" .. color .. "ET Lua SQL console " .. version ) - end -end - -function et_ConsoleCommand( command ) - - if debug == 1 then - et.trap_SendServerCommand( -1 ,"chat \"" .. color .. "ConsoleCommand - command: " .. command ) - end - - -- TODO should be used by admins only - if string.lower(et.trap_Argv(0)) == commandprefix.."sql" then - - -- TODO sanity checks - help output - -- 2 ? - if (et.trap_Argc() < 1) then - et.G_Print(color..commandprefix.."sql is used to access the db with common sql commands.\n" .. "usage: ...\n") - return 1 - end - - -- we have some cases now - get the sql command ... insert, update - local cmd = string.lower( string.sub(et.trap_Argv(1), 0 , 6) ) - - if debug == 1 then - et.G_Print(color .. commandprefix.."sql: " .. et.trap_Argv(1) .. "\n") - end - - -- ok, does work - if cmd == "select" then - - cur = assert (con:execute(et.trap_Argv(1))) - row = cur:fetch ({}, "a") -- the rows will be indexed by field names - - local collect = "" - for i,v in pairs(cur:getcolnames()) do collect = collect .. v .. tablespacer end - et.G_Print(collect .. "\n") -- fix this order is not in sync with following output - - -- add a limit to 20 rows ? - while row do - collect = "" - for i,v in pairs(row) do collect = collect .. v .. tablespacer end - -- send more rows each print ? (depends on table size) - et.G_Print(collect .. "\n") - row = cur:fetch (row, "a") -- reusing the table of results - end - cur:close() - - elseif cmd == "insert" or "create" or "delete" then - -- exec cmd - res = assert (con:execute(et.trap_Argv(1))) - et.G_Print(res .. "\n") - - elseif cmd == "vacuum" then - -- only sqlite defrag the database - if dbms == "SQLite" then - res = assert (con:execute(et.trap_Argv(1))) - et.G_Print(res .. "\n") - else - et.G_Print(color..commandprefix.."sql: Command unknown for this dbms\n") - end - else - -- cmd is 5 char based ? - cmd = string.lower( string.sub(et.trap_Argv(1), 0 , 5) ) - - -- alter - if cmd == "alter" then - res = assert (con:execute(et.trap_Argv(1))) - et.G_Print(res .. "\n") - else - -- cmd is 4 char based - cmd = string.lower( string.sub(et.trap_Argv(1), 0 , 4) ) - - -- drop - if cmd == "drop" then - -- create a row of data - res = assert (con:execute(et.trap_Argv(1))) - cur:close() - - -- untested (only mysql atm) - elseif cmd == "show" then - cur = assert (con:execute(et.trap_Argv(1))) - row = cur:fetch ({}, "a") -- the rows will be indexed by field names - local collect = "" - for i,v in pairs(cur:getcolnames()) do collect = collect .. v .. tablespacer end - et.G_Print(collect .. "\n") - - -- add a limit to 20 rows ? - while row do - collect = "" - for i,v in pairs(row) do collect = collect .. v .. tablespacer end - -- send more rows each print ? (depends on table size - et.G_Print(collect .. "\n") - row = cur:fetch (row, "a") -- reusing the table of results - end - cur:close() - - else - et.G_Print(color..commandprefix.."sql: Command unknown\n") - end - end - end - end - -- add more cmds here ... - -end - -function shuttdownDBMS() - - if dbms == "mySQL" or dbms == "SQLite" then - con:close() - env:close() - else - -- should never happen ;) - error("DBMS not supported.") - end -end - -function et_ShutdownGame( restart ) - shuttdownDBMS() -end diff --git a/noq/noq_commands.cfg b/noq/noq_commands.cfg deleted file mode 100644 index e6d71c7..0000000 --- a/noq/noq_commands.cfg +++ /dev/null @@ -1,136 +0,0 @@ -# = text followed by the command. (Can be used to enter multiple values. -# For example: pb_sv_kick can be used to enter slot number, length of kick, and reason.) -# = the client id of the calling player. -# = last player, you killed -# = last player, that killed you -# = class of calling player -# = side / team of calling player -# = Name of the calling player (without color codes) -# = Name of the calling player (with color codes) -# = Guid of the calling player (without color codes) -# parallel: all attributes for the second player(specified via part of name or slotnumber): -# = class -# = team -# = colored name -# = id -# = punkbuster slotnumber -# = guid -# = adminlevel -# = name without color - - 0 - help = - -#Level - command = rcon command -#command Examples: -#0 - ref = ref referee -#2 - vkick = clientkick - -#A bad example would be -#0 - kick player = clientkick -#This is a bad example because you cannot have spaces in your command. But you can have underscores. -# PLEASE NOTE: PARAMETER IS UNSAFE - -# Rcon Shortcuts (Work with all mods / etmain) - 2 - start = start_match -help = Starts the match -syntax = !start - 2 - swap = swap_teams - 2 - reset = reset_match - 2 - ref = ref referee - 2 - unref = ref unReferee - 2 - shuffle = shuffle_teams - 2 - map_restart = map_restart - 2 - pbkick = pb_sv_kick - 3 - cancelvote = cancelvote - 3 - passvote = passvote - 3 - cp = cp - 3 - qsay = qsay - 3 - devmap = devmap - 3 - exec = exec - -# Referee Commands (only ETPRO) -#2 - putallies = ref putallies -#2 - putspec = ref remove -#2 - putaxis = ref putaxis -#3 - pause = ref pause -#3 - unpause = ref unpause -#2 - allready = ref allready -#2 - lock = ref lock -#2 - unlock = ref unlock -#2 - speclock = ref speclock -#2 - specunlock = ref specunlock -#2 - nextmap = ref nextmap -#2 - mutespecs = ref mutespecs -#2 - unmutespecs = ref unmutespecs -#3 - map = ref map -#3 - campaign = ref campaign -#3 - gametype = ref gametype -#3 - config = ref config -#3 - pub = ref pub -#3 - comp = ref comp -#1 - cointoss = ref cointoss - -# Shuffle without restart - 2 - shuffle_norestart = ref shuffleteamsxp_norestart - 2 - shuffleteamsxp_norestart = ref shuffleteamsxp_norestart - -# campaign functions - 3 - campaign = campaign - -# To kick a player without temporary ban. Change the message, if you like. - 2 - fkick = pb_sv_kick 0 Come back in, if you want - -# Shortcut to make the called a shoutcaster / remove his statua - 3 - ms = makeShoutcaster - 0 - rs = removeShoutcaster - -# Moves the calling person into the specific team -#2 - putmeaxis = ref putaxis -#2 - putmeallies = ref putallies -#2 - putmespec = ref remove - -#FUN -#0 - moo = qsay ^1MOO!!!!!!!!!!!!!! ; qsay ^2MOO 2!!!!!!!!!!!!!!!! - 0 - drunk = qsay ^3DONT TELL ME ^1WHEN I'VE HAD ENOUGH! - 0 - stup = qsay ^2It's better to lose than to win - 0 - croyt = qsay ^2HOW DO YOU NOT DIE!!!! - 0 - aim = qsay ^2*Get some glasses for pete's sake* - 0 - beer = qsay A nice sexy waitress brings ^7^7 a nice cup of beer! -help = Gives the target a beer -syntax = !beer playername/slot - 0 - pizza = qsay Someone calls Mario, and he brings ^7^7 a hot pepperoni pizza! - 0 - coke = qsay ^3Ah... A delicious glass of cold Coca Cola[tm] (*thinks ^7^3 while he drinks*) - 0 - pfstinkt = qsay ^3Uh, that smell of the panzer is pretty strong today ... ^3(^7^3's opinion) - 0 - bye = qsay ^7^3 waves his hand to say ^1GOOD BYE^3. We surely meet later! ; playsound -1 sound/misc/bye.wav - 0 - backrage = qsay ^3Wow, ^3has backrage skills with his uber ^1 - 0 - porn = qsay ^3Press F7 to download! - 0 - aimbot = qsay ^3!execute aimbot.cfg - 0 - dean = qsay ^1Warning, med pile sited! - 0 - pack = qsay ^3Run and heal! Come back when you're ready to get pwnd! - 0 - tk = qsay Wait! Don't shoot! My teammates will kill me for you! - 1 - holyshit = playsound sound/misc/holyshit.wav - 1 - denied = playsound sound/misc/Denied.wav - 1 - headshot1 = playsound sound/misc/boomheadshot.wav - 1 - headshot2 = playsound sound/misc/Headshot.wav - 1 - prick = playsound sound/misc/prick.wav - 2 - respect = playsound sound/misc/respect_x.wav - 1 - victory = playsound sound/misc/victory.wav - 1 - jackass = playsound sound/misc/DONKEY.wav - 1 - looser = playsound sound/misc/ae821.wav - 1 - goodnews = playsound sound/misc/goodnews.wav - 1 - nogodno = playsound sound/misc/nogodno.wav -#0 - random = qsay ^3is on the team as a ! - -#for spamming - 0 - owned = qsay ^1Ha^3ha^5ha^3, I owned ^7^3 with my ^7^3!!! - 0 - pants = qsay ^1No^3no^5noooo^3, I was killed by ^7^3 with a ^7^3!!! - 0 - whoami = qsay I am ^7. I play ^3^7 on the ^3^7 side. - 0 - victimized = qsay ^1, You've just been victimized by ^1's !!! - -#other -#2 - vkick = clientkick -#2 - vmute = ref mute -#3 - bluerespawn = forcecvar g_bluelimbotime -#3 - redrespawn = forcecvar g_redlimbotime - -#2 - showtk = $LUA$ showTkTable() diff --git a/noq/noq_config.cfg.sample b/noq/noq_config.cfg.sample deleted file mode 100644 index a215453..0000000 --- a/noq/noq_config.cfg.sample +++ /dev/null @@ -1,42 +0,0 @@ --- Make this file your own ... -return { --- Table: {1} -{ - ["dbms"]="mySQL", - ["dbname"]="dbname", - ["dbuser"]="dbuser", - ["dbpassword"]="dbpass", - ["dbhostname"]="dbhost", - ["dbport"]="3306", - ["useDB"]="1", - ["mail"] = "0", - ["mailserv"] = "XXX", - ["mailport"] = "25", - ["mailfrom"] = "", - ["recordbots"] = "0", - ["color"] = "^3", - ["commandprefix"] = "!", - ["debug"] = "0", - ["debugquerries"] = "0", - ["persgamestartmessage"] = "Welcome to the server", - ["persgamestartmessagelocation"] = "cpm", - ["xprestore"] = "1", - ["pussyfactor"] = "1", - ["usecommands"] = "0", - ["polldistance"] = "120", - ["maxSelfKills"] = "3", - ["evenerCheckallSec"] = "40", - ["nextmapVoteSec"] = "0", - ["lognames"]="1", - ["irchost"]="", - ["ircport"]="1337", - ["teamdamageMessage1"] = "You do love your mates!", - ["teamdamageMessage2"] = "you hit your mates from time to time!", - ["teamdamageMessage3"] = "you don't care about teambleeding very much!", - ["teamdamageMessage4"] = "your nickname is a synonym of collateral damage!", - ["teamdamageMessage5"] = "you don't care about teams - everybody is your enemy!", - ["teamdamageMessage6"] = "you are a counteragent killing more of your own team. Get paid by enemy?", - ["deleteSessionsOlderXMonths"] = "0", -}, -} - diff --git a/noq/noq_db.lua b/noq/noq_db.lua deleted file mode 100644 index 34e1fd8..0000000 --- a/noq/noq_db.lua +++ /dev/null @@ -1,331 +0,0 @@ --- The NOQ - No Quarter Lua next generation game manager --- --- A Shrubbot replacement and also kind of new game manager and tracking system based on mysql or sqlite3. --- Both are supported and in case of sqlite there is no extra sqlite installation needed. --- --- NQ Lua team 2009-2011 - No warranty :) - --- NQ Lua team is: --- ailmanki --- BubbaG1 --- Hose --- IlDuca --- IRATA [*] --- Luborg - - -------------------------------------------------------------------------------- --- DBMS -------------------------------------------------------------------------------- - --- --- We could allocate this each time, but since are used lot of times is better to make them global --- TODO: cur and res are exactly the same things, so we could save memory using only one of them --- cur = {} -- Will handle the SQL commands returning informations ( es: SELECT ) --- res = {} -- Will handle SQL commands without outputs ( es: INSERT ) --- row = {} -- To manipulate the outputs of SQL command --- --row1 = {} -- To manipulate the outputs of SQL command in case we need more than one request --- TODO: does this apply here also? how to do then? ['cur'] and reference it each time? --- --- TODO: Check for various injections possibilities, create a function to sanitize input! --- TODO: Merge double code.. - -DBCon = { - -- Database managment system to use - ['dbms'] = getConfig("dbms"), -- possible values mySQL, SQLite - ['dbname'] = getConfig("dbname"), - ['debugquerries'] = tonumber(getConfig("debugquerries")), - ['con'] = nil, - ['env'] = nil, - ['cur'] = {}, - ['row'] = {}, - - ['DoConnect'] = function( self ) - -- Handle different dbms - if self.dbms == "mySQL" then - require "luasql.mysql" - self.env = assert( luasql.mysql() ) - self.con = assert( self.env:connect(self.dbname, getConfig("dbuser"), getConfig("dbpassword"), getConfig("dbhostname"), getConfig("dbport")) ) - elseif self.dbms == "SQLite" then - require "luasql.sqlite3" - self.env = assert( luasql.sqlite3() ) - -- this opens OR creates a sqlite db - if this file is loaded db is created -fix this? - self.con = assert( self.env:connect( self.dbname ) ) - elseif self.dbms == "postgreSQL" then - require "luasql.postgresql" - self.env = assert( luasql.postgresql() ) - self.con = assert( self.env:connect(self.dbname, getConfig("dbuser"), getConfig("dbpassword"), getConfig("dbhostname"), getConfig("dbport")) ) - else - -- stop script - error("DBMS not supported.") - end - end, - - ------------------------------------------------------------------------------- - -- DoDisconnect - -- Does close connection to the DBMS - ------------------------------------------------------------------------------- - ['DoDisconnect'] = function ( self ) - self.con:close() - self.env:close() - end, - - ------------------------------------------------------------------------------- - -- GetVersion - -- Returns DB Version - ------------------------------------------------------------------------------- - ['GetVersion'] = function( self ) - -- Check the database version - self.cur = assert( self.con:execute("SELECT version FROM version ORDER BY id DESC LIMIT 1") ) - self.row = self.cur:fetch ({}, "a") - self.cur:close() - return self.row.version -- FIXME: tonumber(self.row.version) - end, - - ------------------------------------------------------------------------------- - -- SetPlayerAlias - -- Adds an Alias if not existing - ------------------------------------------------------------------------------- - ['SetPlayerAlias'] = function( self, thisName, thisGuid ) - -- search alias based on guid and name - local thisName = string.gsub(thisName,"\'", "\\\'") - self.cur = assert (self.con:execute("SELECT * FROM log WHERE guid1='".. thisGuid .."' AND type='3' AND textxml='".. thisName .."' LIMIT 1")) - self.row = self.cur:fetch ({}, "a") - self.cur:close() - if self.row then - --nothing to do, player name (alias) exists - else - self.cur = assert (self.con:execute("INSERT INTO log (guid1, type, textxml) \ - VALUES ('".. thisGuid .."', 3, '".. thisName .."')")) - end - end, - - - ------------------------------------------------------------------------------- - -- GetLogTypefor - -- Searches your type to guid out of the DB - ------------------------------------------------------------------------------- - ['GetLogTypefor'] = function( self, thisType, thisGuid , thisGuid2 ) - local query = "SELECT * FROM log WHERE type='" .. thisType .. "'" - - if thisGuid ~= nil then - query = query .. " AND guid1='" .. thisGuid .. "'" - end - if thisGuid2 ~= nil then - query = query .. " AND guid2='" .. thisGuid2 .. "'" - end - - --Search the in the database - self.cur = assert (self.con:execute(query)) - local numrows = self.cur:numrows() - local pms = {} - if numrows ~= 0 then - for i=1, numrows +1, 1 do - pms[i] = self.cur:fetch ({}, "a") - end - self.cur:close() - return pms - else - return nil - end - end, - - ------------------------------------------------------------------------------- - -- SetLogEntry - -- Searches your type to guid out of the DB - ------------------------------------------------------------------------------- - ['SetLogEntry'] = function( self, thisType, thisGuid , thisGuid2, thisXmltext ) - - self.cur = assert (self.con:execute("INSERT INTO log (guid1, guid2, type, textxml) \ - VALUES ('".. thisGuid .."','".. thisGuid2 .."', '".. thisType .."', '".. thisXmltext .."')")) - - end, - - ------------------------------------------------------------------------------- - -- GetPlayerAliases - -- Gives back a table with all aliases know from this player - ------------------------------------------------------------------------------- - ['GetPlayerAliases'] = function( self, _guid) - - local db = self:GetLogTypefor(3,_guid) - aliases = {} - if db ~= nil then - for i,v in ipairs(db) do - v = string.sub(v.textxml, 7, -8) -- FOOBAR cut the tag - aliases[v] = v - end - return aliases - else - return nil - end - end, - - - ------------------------------------------------------------------------------- - -- DelOM - -- Deletes a entry by its id and guid2(used for offlinemsgs) - ------------------------------------------------------------------------------- - ['DelOM'] = function( self, thisid, thisguid) - - self.cur = assert (self.con:execute("DELETE FROM log WHERE id='"..thisid.."' AND guid1='"..thisguid.."'")) - - end, - - ------------------------------------------------------------------------------- - -- DelMail - -- Deletes all entrys for guid with id 5(used for offlinemsgs) - ------------------------------------------------------------------------------- - ['DelMail'] = function( self, thisguid) - - self.cur = assert (self.con:execute("DELETE FROM log WHERE type=5 and guid1='"..thisguid.."'")) - - end, - - ------------------------------------------------------------------------------- - -- GetPlayerbyReg - -- Searches Player by registered Name - ------------------------------------------------------------------------------- - ['GetPlayerbyReg'] = function( self, name ) - self.cur = assert (self.con:execute("SELECT * FROM player WHERE user='".. name .."' LIMIT 1")) - player = self.cur:fetch ({}, "a") - self.cur:close() - return player - end, - - ------------------------------------------------------------------------------- - -- DoCreateNewPlayer - -- Create a new Player: write to Database, set Xp 0 - -- maybe could also be used to reset Player, as pkey is unique - ------------------------------------------------------------------------------- - ['DoCreateNewPlayer'] = function( self, pkey, isBot, netname, updatedate, createdate, conname ) - self.cur = assert( self.con:execute("INSERT INTO player (pkey, isBot, netname, cleanname, updatedate, createdate, conname) VALUES ('" - ..pkey.."', " - ..isBot..", '" - ..netname.."', '" - ..et.Q_CleanStr(netname).."', '" - ..updatedate .."', '" - ..createdate .."', '" - ..conname.."')")) - end, - - ------------------------------------------------------------------------------- - -- SetPlayerSession - -- This is the regular sessions ave of a player - ------------------------------------------------------------------------------- - ['SetPlayerSession'] = function ( self, player, map, slot) - -- TODO: Think about using this earlier, is this the injection check ? - -- Yes, its an escape function for ' (wich should be the only character allowed by et and with a special meaning for SQL) - -- TODO: What about ET clients which are modified? - - local name = string.gsub(player["netname"],"\'", "\\\'") - - local sessquery = "INSERT INTO session (pkey, slot, map, ip, netname, cleanname, valid, start, end, sstime, axtime, altime, sptime, xp0, xp1, xp2, xp3, xp4, xp5, xp6, xptot, acc, kills, tkills, death) VALUES ('" - ..player["pkey"].."', '" - ..slot.."', '" - ..map.."', '" - ..player["ip"].."', '" - ..name.."', '" - ..et.Q_CleanStr(name).."', " - .."1"..", '" - ..player["start"].."','" - ..timehandle('N').. "', '" - -- TODO : check if this works. Is the output from 'D' option in the needed format for the database? - ..timehandle('D','N',player["start"]).."' , '" - ..player["axtime"].."', '" - ..player["altime"].."', '" - ..player["sptime"].."', '" - ..player["xp0"].."', '" - ..player["xp1"].."', '" - ..player["xp2"].."', '" - ..player["xp3"].."', '" - ..player["xp4"].."', '" - ..player["xp5"].."', '" - ..player["xp6"].."', '" - ..player["xptot"].."', '" - .."0".."', '" - ..player["kills"].."', '" - ..player["tkills"].."', '" - ..player["death"].. "')" - - if self.debugquerries == 1 then - et.G_LogPrint( "\n\n".. sessquery .. "\n\n" ) - end - self.cur = assert (self.con:execute(sessquery)) - end, - - ------------------------------------------------------------------------------- - -- SetPlayerSession_WCD - -- This is called when a player disconnects while connecting - ------------------------------------------------------------------------------- - ['SetPlayerSessionWCD'] = function ( self, pkey, slot, map, ip, valid, start, ende, sstime, uci ) - local query = "INSERT INTO session (pkey, slot, map, ip, valid, start, end, sstime, uci) VALUES ('" - ..pkey.."', '" - ..slot.."', '" - ..map.."', '" - ..ip.."', '" - ..valid.."', '" - ..start.."', '" - ..ende.."' , '" - -- TODO : check if this works. Is the output from 'D' option in the needed format for the database? - ..sstime.."' , '" - ..uci.."')" - - if self.debugquerries == 1 then - et.G_LogPrint( "\n\n".. query .. "\n\n" ) - end - self.cur = assert (self.con:execute( query )) - end, - - ------------------------------------------------------------------------------- - -- SetPlayerInfo - -- Sets PlayerInfos - ------------------------------------------------------------------------------- - ['SetPlayerInfo'] = function (self, player) - local name = string.gsub(player["netname"],"\'", "\\\'") - self.cur = assert (self.con:execute("UPDATE player SET clan='".. player["clan"] .."', \ - netname='".. name .."',\ - cleanname='"..et.Q_CleanStr(name).."',\ - xp0='".. player["xp0"] .."', \ - xp1='".. player["xp1"] .."', \ - xp2='".. player["xp2"] .."', \ - xp3='".. player["xp3"] .."', \ - xp4='".. player["xp4"] .."', \ - xp5='".. player["xp5"] .."', \ - xp6='".. player["xp6"] .."', \ - xptot='"..player["xptot"] .. "',\ - level='".. player["level"] .."', \ - banreason='".. player["banreason"] .."', \ - bannedby='".. player["bannedby"] .."', \ - banexpire='".. player["banexpire"] .."', \ - mutedreason='".. player["mutedreason"] .."', \ - mutedby='".. player["mutedby"] .."', \ - muteexpire='".. player["muteexpire"] .."', \ - warnings='".. player["warnings"] .."', \ - suspect='".. player["suspect"] .."' \ - WHERE pkey='".. player["pkey"] .."'")) - end, - - ------------------------------------------------------------------------------- - -- GetPlayerInfo - -- Returns PlayerInfo table - ------------------------------------------------------------------------------- - ['GetPlayerInfo'] = function( self, thisGuid ) - --Search the GUID in the database ( GUID is UNIQUE, so we just have 1 result, stop searching when we have it ) - self.cur = assert (self.con:execute("SELECT * FROM player WHERE pkey='".. thisGuid .."' LIMIT 1")) - self.row = self.cur:fetch ({}, "a") - self.cur:close() - return self.row - end, - - ['DoRegisterUser'] = function ( self, user, password, pkey ) - self.cur = assert (self.con:execute("UPDATE player SET user='"..user.."', password=MD5('"..password.."') WHERE pkey='"..pkey.."'")) - end, - - -- TODO delete old session if (based on config setting), used in function et_ShutdownGame and cleanSessionCMD - ['DoDeleteOldSessions'] = function ( self, months ) - -- TODO @luborg this DATE_SUB() is mysql only - self.cur = assert (self.con:execute("DELETE FROM session WHERE `end` < DATE_SUB(CURDATE(), INTERVAL "..months.." MONTH)")) - end - -} -return 1 diff --git a/noq/noq_greetings.cfg b/noq/noq_greetings.cfg deleted file mode 100644 index 4f24826..0000000 --- a/noq/noq_greetings.cfg +++ /dev/null @@ -1,10 +0,0 @@ -return { --- Table: {1} -{ - [0]=nil, -- this means no greeting for that level - "^1Welcome Level 1 player ", -- this is level 1 greeting - "^1Welcome Level 2 player ", -- this is level 2 greeting - "^1Welcome Level .. argh, you get it....", - [4]= nil, -- no greeting for level 4 -}, -} \ No newline at end of file diff --git a/noq/noq_i.lua b/noq/noq_i.lua deleted file mode 100644 index 4c48c54..0000000 --- a/noq/noq_i.lua +++ /dev/null @@ -1,409 +0,0 @@ --- --- NOQ installer noq_i.lua - as part of the NOQ --- - --- --- Remove this script from game server path after installation --- - --------------------------------------------------------------------------------- -color = "^5" -version = "1" -commandprefix = "!" -debug = 1 -- debug 0/1 -tablespacer = " " -- use something like " " or "|" --------------------------------------------------------------------------------- -env = nil -con = nil - -res = {} - -fs_game = et.trap_Cvar_Get("fs_game") -homepath = et.trap_Cvar_Get("fs_homepath") -scriptpath = homepath .. "/" .. fs_game .. "/noq/" -- full qualified path for the NOQ scripts - -------------------------------------------------------------------------------- --- table functions - don't move down or edit! -------------------------------------------------------------------------------- - --- TODO: we use same functions in the noq.lua --- Find a way to use more centralized - --- The table load -function table.load( sfile ) - -- catch marker for stringtable - if string.sub( sfile,-3,-1 ) == "--|" then - tables,err = loadstring( sfile ) - else - tables,err = loadfile( sfile ) - end - if err then return _,err - end - tables = tables() - for idx = 1,#tables do - local tolinkv,tolinki = {},{} - for i,v in pairs( tables[idx] ) do - if type( v ) == "table" and tables[v[1]] then - table.insert( tolinkv,{ i,tables[v[1]] } ) - end - if type( i ) == "table" and tables[i[1]] then - table.insert( tolinki,{ i,tables[i[1]] } ) - end - end - -- link values, first due to possible changes of indices - for _,v in ipairs( tolinkv ) do - tables[idx][v[1]] = v[2] - end - -- link indices - for _,v in ipairs( tolinki ) do - tables[idx][v[2]],tables[idx][v[1]] = tables[idx][v[1]],nil - end - end - return tables[1] -end - --- Gets varvalue else null -function getConfig( varname ) - local value = noqvartable[varname] - - if value then - return value - else - et.G_Print("warning, invalid config value for " .. varname .. "\n") - return "null" - end -end - -et.G_LogPrint("Loading NOQ config from ".. scriptpath.."\n") -noqvartable = assert(table.load( scriptpath .. "noq_config.cfg")) - --------------------------------------------------------------------------------- - --- Handle different dbms -if getConfig("dbms") == "mySQL" then - require "luasql.mysql" - env = assert( luasql.mysql() ) - con = assert( env:connect(getConfig("dbname"), getConfig("dbuser"), getConfig("dbpassword"), getConfig("dbhostname"), getConfig("dbport")) ) -elseif getConfig("dbms") == "SQLite" then - require "luasql.sqlite3" - env = assert( luasql.sqlite3() ) - -- this opens OR creates a sqlite db - if this file is loaded db is created -fix this? - con = assert( env:connect( getConfig("dbname") ) ) -else - -- stop script - error("DBMS not supported.") -end - - --------------------------------------------------------------------------------- - -function et_InitGame( levelTime, randomSeed, restart ) - et.trap_SendServerCommand( -1 ,"chat \"" .. color .. "NOQ install " .. version ) -- keep this message so admins know the script is up & running - et.RegisterModname( "NOQ install " .. version .. " " .. et.FindSelf() ) -end - -function et_ConsoleCommand( command ) - if debug == 1 then - et.trap_SendServerCommand( -1 ,"chat \"" .. color .. "ConsoleCommand - command: " .. command ) - end - - if string.lower(et.trap_Argv(0)) == commandprefix.."sqlcreate" then - createTablesDBMS() - elseif string.lower(et.trap_Argv(0)) == commandprefix.."sqlupdate" then - updateTablesDBMS() - elseif string.lower(et.trap_Argv(0)) == commandprefix.."sqldrop" then - dropTablesDBMS() - elseif string.lower(et.trap_Argv(0)) == commandprefix.."sqlclean" then - -- drop all tables - cleanTablesDBMS() - end - -- add more cmds here ... -end - --- -function cleanTablesDBMS() - res = assert(con:execute"delete from player") - et.G_Print(res .. "\n") - res = assert(con:execute"delete from session") - et.G_Print(res .. "\n") - res = assert(con:execute"delete from log") - et.G_Print(res .. "\n") -end - --- For future versions if the db structure does exist -function updateTablesDBMS() - -- alter tables ... -end - -function dropTablesDBMS() - res = assert(con:execute"DROP TABLE session") - et.G_Print(res .. "\n") - res = assert(con:execute"DROP TABLE player") - et.G_Print(res .. "\n") - res = assert(con:execute"DROP TABLE log") - et.G_Print(res .. "\n") - res = assert(con:execute"DROP TABLE level") - et.G_Print(res .. "\n") - res = assert(con:execute"DROP TABLE version") - et.G_Print(res .. "\n") -end - -function createTablesDBMS() - -- IMPORTANT NOTES for default field values: - -- Mandatory fields to create a table are set as NOT NULL - -- A non existing time is NULL - -- If you add more fields create usefull default values ... - - et.G_Print(color .. commandprefix.."sqlcreate for ".. getConfig("dbms") .." started\n") - - -- SQLite - if getConfig("dbms") == "SQLite" then - - -- Notes: - -- We store timestamps as INTEGER - Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC. - - res = assert(con:execute"CREATE TABLE IF NOT EXISTS player ( \ - id INTEGER PRIMARY KEY, \ - pkey TEXT UNIQUE NOT NULL, \ - conname TEXT NOT NULL, \ - regname TEXT DEFAULT '', \ - netname TEXT DEFAULT '', \ - cleanname TEXT DEFAULT '', \ - isBot INTEGER DEFAULT 0, \ - clan TEXT DEFAULT '', \ - level INTEGER DEFAULT 0, \ - flags TEXT DEFAULT '', \ - user TEXT DEFAULT '', \ - password TEXT DEFAULT '', \ - email TEXT DEFAULT '', \ - xp0 INTEGER DEFAULT 0, \ - xp1 INTEGER DEFAULT 0, \ - xp2 INTEGER DEFAULT 0, \ - xp3 INTEGER DEFAULT 0, \ - xp4 INTEGER DEFAULT 0, \ - xp5 INTEGER DEFAULT 0, \ - xp6 INTEGER DEFAULT 0, \ - xptot INTEGER DEFAULT 0, \ - banreason TEXT DEFAULT '', \ - bannedby TEXT DEFAULT '', \ - banexpire DATE DEFAULT '1000-01-01 00:00:00', \ - mutedreason TEXT DEFAULT '', \ - mutedby TEXT DEFAULT '', \ - muteexpire DATE DEFAULT '1000-01-01 00:00:00', \ - warnings INTEGER DEFAULT 0, \ - suspect INTEGER DEFAULT 0, \ - regdate DATE DEFAULT NULL, \ - updatedate DATE DEFAULT CURRENT_DATE, \ - createdate DATE DEFAULT CURRENT_DATE)" ) - et.G_Print("CREATE TABLE IF NOT EXISTS player res: " .. res .. "\n") - - res = assert(con:execute"CREATE TABLE IF NOT EXISTS log ( \ - id INTEGER PRIMARY KEY, \ - guid1 TEXT NOT NULL, \ - guid2 TEXT DEFAULT NULL, \ - type INTEGER DEFAULT NULL, \ - textxml TEXT DEFAULT NULL, \ - createdate DATE DEFAULT CURRENT_DATE)") - et.G_Print("CREATE TABLE IF NOT EXISTS log res: " .. res .. "\n") - - res = assert(con:execute"CREATE TABLE IF NOT EXISTS session ( \ - id INTEGER PRIMARY KEY, \ - pkey INTEGER NOT NULL, \ - slot INTEGER NOT NULL, \ - map TEXT NOT NULL, \ - ip TEXT DEFAULT '', \ - netname TEXT DEFAULT '', \ - cleanname TEXT DEFAULT '', \ - valid INTEGER DEFAULT NULL, \ - start DATE DEFAULT CURRENT_DATE, \ - end DATE DEFAULT NULL, \ - sptime INTEGER DEFAULT NULL, \ - axtime INTEGER DEFAULT NULL, \ - altime INTEGER DEFAULT NULL, \ - lctime INTEGER DEFAULT NULL, \ - sstime INTEGER DEFAULT NULL, \ - xp0 INTEGER DEFAULT 0, \ - xp1 INTEGER DEFAULT 0, \ - xp2 INTEGER DEFAULT 0, \ - xp3 INTEGER DEFAULT 0, \ - xp4 INTEGER DEFAULT 0, \ - xp5 INTEGER DEFAULT 0, \ - xp6 INTEGER DEFAULT 0, \ - xptot INTEGER DEFAULT 0, \ - acc REAL DEFAULT 0.0, \ - kills INTEGER DEFAULT 0, \ - tkills INTEGER DEFAULT 0, \ - death INTEGER DEFAULT 0, \ - revives INTEGER DEFAULT 0, \ - uci INTEGER DEFAULT 0)" ) - et.G_Print("CREATE TABLE IF NOT EXISTS session res: " .. res .. "\n") - - res = assert(con:execute"CREATE TABLE IF NOT EXISTS level ( \ - id INTEGER PRIMARY KEY, \ - pseudo TEXT UNIQUE NOT NULL, \ - name TEXT NOT NULL, \ - greetings TEXT DEFAULT '', \ - flags TEXT NOT NULL)" ) - et.G_Print("CREATE TABLE IF NOT EXISTS level res: " .. res .. "\n") - - res = assert(con:execute"CREATE TABLE IF NOT EXISTS version ( \ - id INTEGER PRIMARY KEY, \ - version INTEGER NOT NULL UNIQUE )" ) - et.G_Print("CREATE TABLE IF NOT EXISTS version res: " .. res .. "\n") - - -- SQLite needs exra cmds for setting up an index (anybody knows syntax for create table stmd?) - -- player - res = assert(con:execute"CREATE INDEX p_regname ON player(regname)" ) - et.G_Print("CREATE INDEX p_regname ON player(regname) res: " .. res .. "\n") - res = assert(con:execute"CREATE INDEX p_netname ON player(netname)" ) - et.G_Print("CREATE INDEX p_netname ON player(netname) res: " .. res .. "\n") - --log - res = assert(con:execute"CREATE INDEX l_guid ON log(guid1, guid2)" ) - et.G_Print("CREATE INDEX l_guid ON log(guid1, guid2) res: " .. res .. "\n") - -- session - res = assert(con:execute"CREATE INDEX s_pkey ON session(pkey)" ) - et.G_Print("CREATE INDEX s_pkey ON session(pkey) res: " .. res .. "\n") - res = assert(con:execute"CREATE INDEX s_ip ON session(ip)" ) - et.G_Print("CREATE INDEX s_ip ON session(ip) res: " .. res .. "\n") - res = assert(con:execute"CREATE INDEX s_end ON session(end)" ) - et.G_Print("CREATE INDEX s_end ON session(end) res: " .. res .. "\n") - - -- insert data - res = assert(con:execute("INSERT INTO version VALUES ( '1', '" .. version .. "' )")) - et.G_Print("Version res: " .. res .. " - Database version is " .. version .. "\n") - - -- TODO: create level entries - - -- mySQL - elseif getConfig("dbms") == "mySQL" then - - res = assert(con:execute"CREATE TABLE player ( \ - id INT PRIMARY KEY AUTO_INCREMENT, \ - pkey VARCHAR(32) UNIQUE NOT NULL, \ - conname VARCHAR(36) NOT NULL, \ - regname VARCHAR(36) DEFAULT '', \ - netname VARCHAR(36) DEFAULT '', \ - cleanname VARCHAR(36) DEFAULT '', \ - isBot BOOLEAN DEFAULT 0, \ - clan VARCHAR(20) DEFAULT '', \ - level INT DEFAULT 0, \ - flags VARCHAR(50) DEFAULT '', \ - user VARCHAR(20) DEFAULT '', \ - password VARCHAR(32) DEFAULT '', \ - email VARCHAR(50) DEFAULT '', \ - xp0 INT DEFAULT 0, \ - xp1 INT DEFAULT 0, \ - xp2 INT DEFAULT 0, \ - xp3 INT DEFAULT 0, \ - xp4 INT DEFAULT 0, \ - xp5 INT DEFAULT 0, \ - xp6 INT DEFAULT 0, \ - xptot INT DEFAULT 0, \ - banreason VARCHAR(1024) DEFAULT '', \ - bannedby VARCHAR(36) DEFAULT '', \ - banexpire DATETIME DEFAULT '1000-01-01 00:00:00', \ - mutedreason VARCHAR(1024) DEFAULT '', \ - mutedby VARCHAR(36) DEFAULT '', \ - muteexpire DATETIME DEFAULT '1000-01-01 00:00:00', \ - warnings SMALLINT DEFAULT 0, \ - suspect TINYINT DEFAULT 0, \ - regdate DATETIME DEFAULT NULL, \ - updatedate TIMESTAMP DEFAULT '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP, \ - createdate DATETIME NOT NULL, \ - INDEX(`regname`), \ - INDEX(`netname`) \ - ) ENGINE=InnoDB" ) - et.G_Print(res .. "\n") - - res = assert(con:execute"CREATE TABLE IF NOT EXISTS log ( \ - id INT PRIMARY KEY AUTO_INCREMENT, \ - guid1 VARCHAR(32) NOT NULL, \ - guid2 VARCHAR(32) DEFAULT NULL, \ - type INT DEFAULT NULL, \ - textxml VARCHAR(2056) DEFAULT NULL, \ - createdate DATETIME NOT NULL, \ - INDEX(`guid1`), \ - INDEX(`guid2`) \ - ) ENGINE=InnoDB" ) - et.G_Print(res .. "\n") - - res = assert(con:execute"CREATE TABLE session ( \ - id INT PRIMARY KEY AUTO_INCREMENT, \ - pkey VARCHAR(32) NOT NULL, \ - slot SMALLINT NOT NULL, \ - map VARCHAR(36) NOT NULL, \ - ip VARCHAR(25) DEFAULT '', \ - netname VARCHAR(36) DEFAULT '', \ - cleanname VARCHAR(36) DEFAULT '', \ - valid BOOLEAN DEFAULT NULL, \ - start DATETIME NOT NULL, \ - end DATETIME DEFAULT NULL, \ - sptime TIME DEFAULT NULL, \ - axtime TIME DEFAULT NULL, \ - altime TIME DEFAULT NULL, \ - lctime TIME DEFAULT NULL, \ - sstime TIME DEFAULT NULL, \ - xp0 INT DEFAULT 0, \ - xp1 INT DEFAULT 0, \ - xp2 INT DEFAULT 0, \ - xp3 INT DEFAULT 0, \ - xp4 INT DEFAULT 0, \ - xp5 INT DEFAULT 0, \ - xp6 INT DEFAULT 0, \ - xptot INT DEFAULT 0, \ - acc DOUBLE (10,2) DEFAULT 0.0, \ - kills SMALLINT DEFAULT 0, \ - tkills SMALLINT DEFAULT 0, \ - death SMALLINT DEFAULT 0, \ - revives SMALLINT DEFAULT 0, \ - uci TINYINT DEFAULT 0, \ - INDEX(`pkey`), \ - INDEX(`ip`), \ - INDEX(`end`) \ - ) ENGINE=InnoDB" ) - et.G_Print(res .. "\n") - - res = assert(con:execute"CREATE TABLE IF NOT EXISTS level ( \ - id INT PRIMARY KEY AUTO_INCREMENT, \ - pseudo VARCHAR(15) UNIQUE NOT NULL, \ - name VARCHAR(36) NOT NULL, \ - greetings VARCHAR(150) DEFAULT '', \ - flags VARCHAR(50) NOT NULL)" ) - et.G_Print(res .. "\n") - - res = assert(con:execute"CREATE TABLE version ( \ - id INT PRIMARY KEY AUTO_INCREMENT, \ - version INT NOT NULL UNIQUE \ - ) ENGINE=InnoDB" ) - et.G_Print(res .. "\n") - - -- mySQL needs a trigger to add the current date/time to a datetime field - res = assert(con:execute"CREATE TRIGGER trigger_player_insert \ - BEFORE INSERT ON `player` FOR EACH ROW SET NEW.createdate = NOW();" ) - et.G_Print(res .. "\n") - - res = assert(con:execute"CREATE TRIGGER trigger_log_insert \ - BEFORE INSERT ON `log` FOR EACH ROW SET NEW.createdate = NOW();" ) - et.G_Print(res .. "\n") - - -- insert data - res = assert(con:execute(string.format("INSERT INTO version VALUES ( 1, %s )",version))) - et.G_Print(res .. "\n") - end - - et.G_Print(color .. commandprefix.."sqlcreate database created version: "..version .."\n") -end - -function shuttdownDBMS() - if getConfig("dbms") == "mySQL" or getConfig("dbms") == "SQLite" then - con:close() - env:close() - else - -- should never happen - error("DBMS not supported.") - end -end - -function et_ShutdownGame( restart ) - shuttdownDBMS() -end diff --git a/noq/noq_mods.cfg b/noq/noq_mods.cfg deleted file mode 100644 index 99e47c0..0000000 --- a/noq/noq_mods.cfg +++ /dev/null @@ -1,83 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - [0]="MOD_UNKNOWN", - "MOD_MACHINEGUN", - "MOD_BROWNING", - "MOD_MG42", - "MOD_GRENADE", - "MOD_KNIFE", - "MOD_LUGER", - "MOD_COLT", - "MOD_MP40", - "MOD_THOMPSON", - "MOD_STEN", - "MOD_GARAND", - "MOD_SILENCER", - "MOD_FG42", - "MOD_FG42_SCOPE", - "MOD_PANZERFAUST", - "MOD_GRENADE_LAUNCHER", - "MOD_FLAMETHROWER", - "MOD_GRENADE_PINEAPPLE", - "MOD_MAPMORTAR", - "MOD_MAPMORTAR_SPLASH", - "MOD_KICKED", - "MOD_DYNAMITE", - "MOD_AIRSTRIKE", - "MOD_SYRINGE", - "MOD_AMMO", - "MOD_ARTY", - "MOD_WATER", - "MOD_SLIME", - "MOD_LAVA", - "MOD_CRUSH", - "MOD_TELEFRAG", - "MOD_FALLING", - "MOD_SUICIDE", - "MOD_TARGET_LASER", - "MOD_TRIGGER_HURT", - "MOD_EXPLOSIVE", - "MOD_CARBINE", - "MOD_KAR98", - "MOD_GPG40", - "MOD_M7", - "MOD_LANDMINE", - "MOD_SATCHEL", - "MOD_SMOKEBOMB", - "MOD_MOBILE_MG42", - "MOD_SILENCED_COLT", - "MOD_GARAND_SCOPE", - "MOD_CRUSH_CONSTRUCTION", - "MOD_CRUSH_CONSTRUCTIONDEATH", - "MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER", - "MOD_K43", - "MOD_K43_SCOPE", - "MOD_MORTAR", - "MOD_AKIMBO_COLT", - "MOD_AKIMBO_LUGER", - "MOD_AKIMBO_SILENCEDCOLT", - "MOD_AKIMBO_SILENCEDLUGER", - "MOD_SMOKEGRENADE", - "MOD_SWAP_PLACES", - "MOD_SWITCHTEAM", - "MOD_GOOMBA", - "MOD_POISON", - "MOD_FEAR", - "MOD_CENSORED", - "MOD_SHOTGUN", - "MOD_BACKSTAB", - "MOD_MOBILE_BROWNING", - "MOD_BAR", - "MOD_STG44", - "MOD_BAZOOKA", - "MOD_STEN_MKII", - "MOD_MP34", - "MOD_VENOM", - "MOD_SHOVE", - "MOD_THROWKNIFE", - "MOD_NUM_MODS", -}, -} diff --git a/noq/noq_mods_130.cfg b/noq/noq_mods_130.cfg deleted file mode 100644 index 9998a8e..0000000 --- a/noq/noq_mods_130.cfg +++ /dev/null @@ -1,84 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - [0]="MOD_UNKNOWN", - "MOD_MACHINEGUN", - "MOD_BROWNING", - "MOD_MG42", - "MOD_GRENADE", - "MOD_KNIFE", - "MOD_LUGER", - "MOD_COLT", - "MOD_MP40", - "MOD_THOMPSON", - "MOD_STEN", - "MOD_GARAND", - "MOD_SILENCER", - "MOD_FG42", - "MOD_FG42_SCOPE", - "MOD_PANZERFAUST", - "MOD_GRENADE_LAUNCHER", - "MOD_FLAMETHROWER", - "MOD_GRENADE_PINEAPPLE", - "MOD_MAPMORTAR", - "MOD_MAPMORTAR_SPLASH", - "MOD_KICKED", - "MOD_DYNAMITE", - "MOD_AIRSTRIKE", - "MOD_SYRINGE", - "MOD_AMMO", - "MOD_ARTY", - "MOD_WATER", - "MOD_SLIME", - "MOD_LAVA", - "MOD_CRUSH", - "MOD_TELEFRAG", - "MOD_FALLING", - "MOD_SUICIDE", - "MOD_TARGET_LASER", - "MOD_TRIGGER_HURT", - "MOD_EXPLOSIVE", - "MOD_CARBINE", - "MOD_KAR98", - "MOD_GPG40", - "MOD_M7", - "MOD_LANDMINE", - "MOD_SATCHEL", - "MOD_SMOKEBOMB", - "MOD_MOBILE_MG42", - "MOD_SILENCED_COLT", - "MOD_GARAND_SCOPE", - "MOD_CRUSH_CONSTRUCTION", - "MOD_CRUSH_CONSTRUCTIONDEATH", - "MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER", - "MOD_K43", - "MOD_K43_SCOPE", - "MOD_MORTAR", - "MOD_AKIMBO_COLT", - "MOD_AKIMBO_LUGER", - "MOD_AKIMBO_SILENCEDCOLT", - "MOD_AKIMBO_SILENCEDLUGER", - "MOD_SMOKEGRENADE", - "MOD_SWAP_PLACES", - "MOD_SWITCHTEAM", - "MOD_GOOMBA", - "MOD_POISON", - "MOD_FEAR", - "MOD_CENSORED", - "MOD_SHOTGUN", - "MOD_BACKSTAB", - "MOD_MOBILE_BROWNING", - "MOD_BAR", - "MOD_STG44", - "MOD_BAZOOKA", - "MOD_JOHNSON", - "MOD_MP34", - "MOD_VENOM", - "MOD_SHOVE", - "MOD_THROWKNIFE", - "MOD_JOHNSON_SCOPE", - "MOD_NUM_MODS", -}, -} diff --git a/noq/noq_mods_names.cfg b/noq/noq_mods_names.cfg deleted file mode 100644 index c6516ee..0000000 --- a/noq/noq_mods_names.cfg +++ /dev/null @@ -1,83 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - MOD_UNKNOWN=0, - MOD_MACHINEGUN=1, - MOD_BROWNING=2, - MOD_MG42=3, - MOD_GRENADE=4, - MOD_KNIFE=5, - MOD_LUGER=6, - MOD_COLT=7, - MOD_MP40=8, - MOD_THOMPSON=9, - MOD_STEN=10, - MOD_GARAND=11, - MOD_SILENCER=12, - MOD_FG42=13, - MOD_FG42_SCOPE=14, - MOD_PANZERFAUST=15, - MOD_GRENADE_LAUNCHER=16, - MOD_FLAMETHROWER=17, - MOD_GRENADE_PINEAPPLE=18, - MOD_MAPMORTAR=19, - MOD_MAPMORTAR_SPLASH=20, - MOD_KICKED=21, - MOD_DYNAMITE=22, - MOD_AIRSTRIKE=23, - MOD_SYRINGE=24, - MOD_AMMO=25, - MOD_ARTY=26, - MOD_WATER=27, - MOD_SLIME=28, - MOD_LAVA=29, - MOD_CRUSH=30, - MOD_TELEFRAG=31, - MOD_FALLING=32, - MOD_SUICIDE=33, - MOD_TARGET_LASER=34, - MOD_TRIGGER_HURT=35, - MOD_EXPLOSIVE=36, - MOD_CARBINE=37, - MOD_KAR98=38, - MOD_GPG40=39, - MOD_M7=40, - MOD_LANDMINE=41, - MOD_SATCHEL=42, - MOD_SMOKEBOMB=43, - MOD_MOBILE_MG42=44, - MOD_SILENCED_COLT=45, - MOD_GARAND_SCOPE=46, - MOD_CRUSH_CONSTRUCTION=47, - MOD_CRUSH_CONSTRUCTIONDEATH=48, - MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER=49, - MOD_K43=50, - MOD_K43_SCOPE=51, - MOD_MORTAR=52, - MOD_AKIMBO_COLT=53, - MOD_AKIMBO_LUGER=54, - MOD_AKIMBO_SILENCEDCOLT=55, - MOD_AKIMBO_SILENCEDLUGER=56, - MOD_SMOKEGRENADE=57, - MOD_SWAP_PLACES=58, - MOD_SWITCHTEAM=59, - MOD_GOOMBA=60, - MOD_POISON=61, - MOD_FEAR=62, - MOD_CENSORED=63, - MOD_SHOTGUN=64, - MOD_BACKSTAB=65, - MOD_MOBILE_BROWNING=66, - MOD_BAR=67, - MOD_STG44=68, - MOD_BAZOOKA=69, - MOD_STEN_MKII=70, - MOD_MP34=71, - MOD_VENOM=72, - MOD_SHOVE=73, - MOD_THROWKNIFE=74, - MOD_NUM_MODS=75, -}, -} diff --git a/noq/noq_mods_names_130.cfg b/noq/noq_mods_names_130.cfg deleted file mode 100644 index 71796bb..0000000 --- a/noq/noq_mods_names_130.cfg +++ /dev/null @@ -1,84 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - MOD_UNKNOWN=0, - MOD_MACHINEGUN=1, - MOD_BROWNING=2, - MOD_MG42=3, - MOD_GRENADE=4, - MOD_KNIFE=5, - MOD_LUGER=6, - MOD_COLT=7, - MOD_MP40=8, - MOD_THOMPSON=9, - MOD_STEN=10, - MOD_GARAND=11, - MOD_SILENCER=12, - MOD_FG42=13, - MOD_FG42_SCOPE=14, - MOD_PANZERFAUST=15, - MOD_GRENADE_LAUNCHER=16, - MOD_FLAMETHROWER=17, - MOD_GRENADE_PINEAPPLE=18, - MOD_MAPMORTAR=19, - MOD_MAPMORTAR_SPLASH=20, - MOD_KICKED=21, - MOD_DYNAMITE=22, - MOD_AIRSTRIKE=23, - MOD_SYRINGE=24, - MOD_AMMO=25, - MOD_ARTY=26, - MOD_WATER=27, - MOD_SLIME=28, - MOD_LAVA=29, - MOD_CRUSH=30, - MOD_TELEFRAG=31, - MOD_FALLING=32, - MOD_SUICIDE=33, - MOD_TARGET_LASER=34, - MOD_TRIGGER_HURT=35, - MOD_EXPLOSIVE=36, - MOD_CARBINE=37, - MOD_KAR98=38, - MOD_GPG40=39, - MOD_M7=40, - MOD_LANDMINE=41, - MOD_SATCHEL=42, - MOD_SMOKEBOMB=43, - MOD_MOBILE_MG42=44, - MOD_SILENCED_COLT=45, - MOD_GARAND_SCOPE=46, - MOD_CRUSH_CONSTRUCTION=47, - MOD_CRUSH_CONSTRUCTIONDEATH=48, - MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER=49, - MOD_K43=50, - MOD_K43_SCOPE=51, - MOD_MORTAR=52, - MOD_AKIMBO_COLT=53, - MOD_AKIMBO_LUGER=54, - MOD_AKIMBO_SILENCEDCOLT=55, - MOD_AKIMBO_SILENCEDLUGER=56, - MOD_SMOKEGRENADE=57, - MOD_SWAP_PLACES=58, - MOD_SWITCHTEAM=59, - MOD_GOOMBA=60, - MOD_POISON=61, - MOD_FEAR=62, - MOD_CENSORED=63, - MOD_SHOTGUN=64, - MOD_BACKSTAB=65, - MOD_MOBILE_BROWNING=66, - MOD_BAR=67, - MOD_STG44=68, - MOD_BAZOOKA=69, - MOD_JOHNSON=70, - MOD_MP34=71, - MOD_VENOM=72, - MOD_SHOVE=73, - MOD_THROWKNIFE=74, - MOD_JOHNSON_SCOPE=75 - MOD_NUM_MODS=76, -}, -} diff --git a/noq/noq_weapons.cfg b/noq/noq_weapons.cfg deleted file mode 100644 index 026815d..0000000 --- a/noq/noq_weapons.cfg +++ /dev/null @@ -1,74 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing - --- TODO: We can use better names here - -return { --- Table: {1} -{ - [0]="WP_NONE", - "WP_KNIFE", - "WP_LUGER", - "WP_MP40", - "WP_GRENADE_LAUNCHER", - "WP_PANZERFAUST", - "WP_FLAMETHROWER", - "WP_COLT", - "WP_THOMPSON", - "WP_GRENADE_PINEAPPLE", - "WP_STEN", - "WP_MEDIC_SYRINGE", - "WP_AMMO", - "WP_ARTY", - "WP_SILENCER", - "WP_DYNAMITE", - "WP_SMOKETRAIL", - "VERYBIGEXPLOSION", - "WP_MEDKIT", - "WP_BINOCULARS", - "WP_PLIERS", - "WP_SMOKE_MARKER", - "WP_KAR98", - "WP_CARBINE", - "WP_GARAND", - "WP_LANDMINE", - "WP_SATCHEL", - "WP_SATCHEL_DET", - "WP_SMOKE_BOMB", - "WP_MOBILE_MG42", - "WP_K43", - "WP_FG42", - "WP_DUMMY_MG42", - "WP_MORTAR", - "WP_AKIMBO_COLT", - "WP_AKIMBO_LUGER", - "WP_GPG40", - "WP_M7", - "WP_SILENCED_COLT", - "WP_GARAND_SCOPE", - "WP_K43_SCOPE", - "WP_FG42SCOPE", - "WP_MORTAR_SET", - "WP_MEDIC_ADRENALINE", - "WP_AKIMBO_SILENCEDCOLT", - "WP_AKIMBO_SILENCEDLUGER", - "WP_MOBILE_MG42_SET", - "WP_SHOTGUN", - "WP_KNIFE_KABAR", - "WP_MOBILE_BROWNING", - "WP_MOBILE_BROWNING_SET", - "WP_BAR", - "WP_BAR_SET", - "WP_STG44", - "WP_STEN_MKII", - "WP_BAZOOKA", - "WP_MP34", - "WP_MORTAR2", - "WP_MORTAR2_SET", - "WP_VENOM", - "WP_POISON_SYRINGE", - "WP_FOOTKICK", - "WP_NUM_WEAPONS", - -}, -} \ No newline at end of file diff --git a/noq/noq_weapons_130.cfg b/noq/noq_weapons_130.cfg deleted file mode 100644 index bd12859..0000000 --- a/noq/noq_weapons_130.cfg +++ /dev/null @@ -1,75 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing - --- TODO: We can use better names here - -return { --- Table: {1} -{ - [0]="WP_NONE", - "WP_KNIFE", - "WP_LUGER", - "WP_MP40", - "WP_GRENADE_LAUNCHER", - "WP_PANZERFAUST", - "WP_FLAMETHROWER", - "WP_COLT", - "WP_THOMPSON", - "WP_GRENADE_PINEAPPLE", - "WP_STEN", - "WP_MEDIC_SYRINGE", - "WP_AMMO", - "WP_ARTY", - "WP_SILENCER", - "WP_DYNAMITE", - "WP_SMOKETRAIL", - "VERYBIGEXPLOSION", - "WP_MEDKIT", - "WP_BINOCULARS", - "WP_PLIERS", - "WP_SMOKE_MARKER", - "WP_KAR98", - "WP_CARBINE", - "WP_GARAND", - "WP_LANDMINE", - "WP_SATCHEL", - "WP_SATCHEL_DET", - "WP_SMOKE_BOMB", - "WP_MOBILE_MG42", - "WP_K43", - "WP_FG42", - "WP_DUMMY_MG42", - "WP_MORTAR", - "WP_AKIMBO_COLT", - "WP_AKIMBO_LUGER", - "WP_GPG40", - "WP_M7", - "WP_SILENCED_COLT", - "WP_GARAND_SCOPE", - "WP_K43_SCOPE", - "WP_FG42SCOPE", - "WP_MORTAR_SET", - "WP_MEDIC_ADRENALINE", - "WP_AKIMBO_SILENCEDCOLT", - "WP_AKIMBO_SILENCEDLUGER", - "WP_MOBILE_MG42_SET", - "WP_SHOTGUN", - "WP_KNIFE_KABAR", - "WP_MOBILE_BROWNING", - "WP_MOBILE_BROWNING_SET", - "WP_BAR", - "WP_BAR_SET", - "WP_STG44", - "WP_JOHNSON", - "WP_BAZOOKA", - "WP_MP34", - "WP_MORTAR2", - "WP_MORTAR2_SET", - "WP_VENOM", - "WP_POISON_SYRINGE", - "WP_FOOTKICK", - "WP_JOHNSON_SCOPE", - "WP_NUM_WEAPONS", - -}, -} \ No newline at end of file diff --git a/noq/noq_weapons_names.cfg b/noq/noq_weapons_names.cfg deleted file mode 100644 index 60824dd..0000000 --- a/noq/noq_weapons_names.cfg +++ /dev/null @@ -1,71 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - WP_NONE=0, - WP_KNIFE=1, - WP_LUGER=2, - WP_MP40=3, - WP_GRENADE_LAUNCHER=4, - WP_PANZERFAUST=5, - WP_FLAMETHROWER=6, - WP_COLT=7, - WP_THOMPSON=8, - WP_GRENADE_PINEAPPLE=9, - WP_STEN=10, - WP_MEDIC_SYRINGE=11, - WP_AMMO=12, - WP_ARTY=13, - WP_SILENCER=14, - WP_DYNAMITE=15, - WP_SMOKETRAIL=16, - VERYBIGEXPLOSION=17, - WP_MEDKIT=18, - WP_BINOCULARS=19, - WP_PLIERS=20, - WP_SMOKE_MARKER=21, - WP_KAR98=22, - WP_CARBINE=23, - WP_GARAND=24, - WP_LANDMINE=25, - WP_SATCHEL=26, - WP_SATCHEL_DET=27, - WP_SMOKE_BOMB=28, - WP_MOBILE_MG42=29, - WP_K43=30, - WP_FG42=31, - WP_DUMMY_MG42=32, - WP_MORTAR=33, - WP_AKIMBO_COLT=34, - WP_AKIMBO_LUGER=35, - WP_GPG40=36, - WP_M7=37, - WP_SILENCED_COLT=38, - WP_GARAND_SCOPE=39, - WP_K43_SCOPE=40, - WP_FG42SCOPE=41, - WP_MORTAR_SET=42, - WP_MEDIC_ADRENALINE=43, - WP_AKIMBO_SILENCEDCOLT=44, - WP_AKIMBO_SILENCEDLUGER=45, - WP_MOBILE_MG42_SET=46, - WP_SHOTGUN=47, - WP_KNIFE_KABAR=48, - WP_MOBILE_BROWNING=49, - WP_MOBILE_BROWNING_SET=50, - WP_BAR=51, - WP_BAR_SET=52, - WP_STG44=53, - WP_STEN_MKII=54, - WP_BAZOOKA=55, - WP_MP34=56, - WP_MORTAR2=57, - WP_MORTAR2_SET=58, - WP_VENOM=59, - WP_POISON_SYRINGE=60, - WP_FOOTKICK=61, - WP_NUM_WEAPONS=62, - -}, -} \ No newline at end of file diff --git a/noq/noq_weapons_names_130.cfg b/noq/noq_weapons_names_130.cfg deleted file mode 100644 index b1880fd..0000000 --- a/noq/noq_weapons_names_130.cfg +++ /dev/null @@ -1,72 +0,0 @@ --- put this file into your noquarter path (fs_homepath) --- never change values here unless you exactly know what you are doing -return { --- Table: {1} -{ - WP_NONE=0, - WP_KNIFE=1, - WP_LUGER=2, - WP_MP40=3, - WP_GRENADE_LAUNCHER=4, - WP_PANZERFAUST=5, - WP_FLAMETHROWER=6, - WP_COLT=7, - WP_THOMPSON=8, - WP_GRENADE_PINEAPPLE=9, - WP_STEN=10, - WP_MEDIC_SYRINGE=11, - WP_AMMO=12, - WP_ARTY=13, - WP_SILENCER=14, - WP_DYNAMITE=15, - WP_SMOKETRAIL=16, - VERYBIGEXPLOSION=17, - WP_MEDKIT=18, - WP_BINOCULARS=19, - WP_PLIERS=20, - WP_SMOKE_MARKER=21, - WP_KAR98=22, - WP_CARBINE=23, - WP_GARAND=24, - WP_LANDMINE=25, - WP_SATCHEL=26, - WP_SATCHEL_DET=27, - WP_SMOKE_BOMB=28, - WP_MOBILE_MG42=29, - WP_K43=30, - WP_FG42=31, - WP_DUMMY_MG42=32, - WP_MORTAR=33, - WP_AKIMBO_COLT=34, - WP_AKIMBO_LUGER=35, - WP_GPG40=36, - WP_M7=37, - WP_SILENCED_COLT=38, - WP_GARAND_SCOPE=39, - WP_K43_SCOPE=40, - WP_FG42SCOPE=41, - WP_MORTAR_SET=42, - WP_MEDIC_ADRENALINE=43, - WP_AKIMBO_SILENCEDCOLT=44, - WP_AKIMBO_SILENCEDLUGER=45, - WP_MOBILE_MG42_SET=46, - WP_SHOTGUN=47, - WP_KNIFE_KABAR=48, - WP_MOBILE_BROWNING=49, - WP_MOBILE_BROWNING_SET=50, - WP_BAR=51, - WP_BAR_SET=52, - WP_STG44=53, - WP_JOHNSON=54, - WP_BAZOOKA=55, - WP_MP34=56, - WP_MORTAR2=57, - WP_MORTAR2_SET=58, - WP_VENOM=59, - WP_POISON_SYRINGE=60, - WP_FOOTKICK=61, - WP_JOHNSON_SCOPE=62, - WP_NUM_WEAPONS=63, - -}, -} \ No newline at end of file diff --git a/noq/nqconst.lua b/noq/nqconst.lua deleted file mode 100644 index 225df5d..0000000 --- a/noq/nqconst.lua +++ /dev/null @@ -1,86 +0,0 @@ --- IRATA [*] - based on etconst.lua from ETPro but slightly modified to fit for NQ --- never change values here unless you exactly know what you are doing - --- misc q_shared.h -et.MAX_CLIENTS = 64 -et.MAX_MODELS = 256 -et.MAX_SOUNDS = 256 -et.MAX_CS_SKINS = 64 -et.MAX_CSSTRINGS = 32 -et.MAX_CS_SHADERS = 32 -et.MAX_SERVER_TAGS = 256 -et.MAX_TAG_FILES = 64 -et.MAX_MULTI_SPAWNTARGETS = 16 -et.MAX_DLIGHT_CONFIGSTRINGS = 16 -et.MAX_SPLINE_CONFIGSTRINGS = 8 --- misc bg_public.h -et.MAX_OID_TRIGGERS = 18 -et.MAX_CHARACTERS = 16 -et.MAX_TAGCONNECTS = 64 -et.MAX_FIRETEAMS = 12 -et.MAX_MOTDLINES = 6 - --- Config string: --- q_shared.h -et.CS_SERVERINFO = 0 -- an info string with all the serverinfo cvars -et.CS_SYSTEMINFO = 1 -- an info string for server system to client system configuration (timescale, etc) --- bg_public.h -et.CS_MUSIC = 2 -et.CS_WARMUP = 5 -- server time when the match will be restarted -et.CS_VOTE_TIME = 6 -et.CS_VOTE_STRING = 7 -et.CS_VOTE_YES = 8 -et.CS_VOTE_NO = 9 -et.CS_GAME_VERSION = 10 -et.CS_LEVEL_START_TIME = 11 -- so the timer only shows the current level -et.CS_INTERMISSION = 12 -- when 1, intermission will start in a second or two -et.CS_MULTI_INFO = 13 -et.CS_MULTI_MAPWINNER = 14 -et.CS_MULTI_OBJECTIVE = 15 - -et.CS_SCREENFADE = 17 -- Ridah, used to tell clients to fade their screen to black/normal -et.CS_FOGVARS = 18 -- (SA) used for saving the current state/settings of the fog -et.CS_SKYBOXORG = 19 -- this is where we should view the skybox from -et.CS_TARGETEFFECT = 20 -et.CS_WOLFINFO = 21 -et.CS_FIRSTBLOOD = 22 -- Team that has first blood -et.CS_ROUNDSCORES1 = 23 -- Axis round wins -et.CS_ROUNDSCORES2 = 24 -- Allied round wins -et.CS_MUSIC_QUEUE = 25 -et.CS_SCRIPT_MOVER_NAMES = 26 -et.CS_CONSTRUCTION_NAMES = 27 -et.CS_REINFSEEDS = 28 -- Reinforcement seeds -et.CS_SERVERTOGGLES = 29 -- Shows current enable/disabled settings (for voting UI) -et.CS_GLOBALFOGVARS = 30 -et.CS_AXIS_MAPS_XP = 31 -et.CS_ALLIED_MAPS_XP = 32 -et.CS_INTERMISSION_START_TIME = 33 -et.CS_ENDGAME_STATS = 34 -et.CS_CHARGETIMES = 35 -et.CS_FILTERCAMS = 36 -et.CS_NOQUARTERINFO = 37 -et.CS_SKILLLEVELS = 38 -et.CS_FORCECVAR = 39 -et.CS_SVCVAR = 40 -et.CS_CONFIGNAME = 41 -et.CS_CSMETHODINFO = 42 - -et.CS_MODELS = 64 -et.CS_SOUNDS = ( et.CS_MODELS + et.MAX_MODELS ) -et.CS_SHADERS = ( et.CS_SOUNDS + et.MAX_SOUNDS ) -et.CS_SHADERSTATE = ( et.CS_SHADERS + et.MAX_CS_SHADERS ) -et.CS_SKINS = ( et.CS_SHADERSTATE + 1 ) -et.CS_CHARACTERS = ( et.CS_SKINS + et.MAX_CS_SKINS ) -et.CS_PLAYERS = ( et.CS_CHARACTERS + et.MAX_CHARACTERS ) -et.CS_MULTI_SPAWNTARGETS = ( et.CS_PLAYERS + et.MAX_CLIENTS ) -et.CS_OID_TRIGGERS = ( et.CS_MULTI_SPAWNTARGETS + et.MAX_MULTI_SPAWNTARGETS ) -et.CS_OID_DATA = ( et.CS_OID_TRIGGERS + et.MAX_OID_TRIGGERS ) -et.CS_DLIGHTS = ( et.CS_OID_DATA + et.MAX_OID_TRIGGERS ) -et.CS_SPLINES = ( et.CS_DLIGHTS + et.MAX_DLIGHT_CONFIGSTRINGS ) -et.CS_TAGCONNECTS = ( et.CS_SPLINES + et.MAX_SPLINE_CONFIGSTRINGS ) -et.CS_FIRETEAMS = ( et.CS_TAGCONNECTS + et.MAX_TAGCONNECTS ) -et.CS_CUSTMOTD = ( et.CS_FIRETEAMS + et.MAX_FIRETEAMS ) -et.CS_STRINGS = ( et.CS_CUSTMOTD + et.MAX_MOTDLINES ) -et.CS_MAX = ( et.CS_STRINGS + et.MAX_CSSTRINGS ) - -return 1 diff --git a/noq/readme.txt b/noq/readme.txt deleted file mode 100644 index 1668f7a..0000000 --- a/noq/readme.txt +++ /dev/null @@ -1,18 +0,0 @@ -The NOQ - No Quarter Lua next generation game manager -A Shrubbot replacement and also kind of new game manager and tracking system based on mysql or sqlite3. -Both are supported and in case of sqlite there is no extra sqlite installation needed. -NQ Lua team 2009-2011 - No warranty :) - -NQ Lua team is: -ailmanki -BubbaG1 -Hose -IlDuca -IRATA [*] -Luborg - -For Information about install/config look in the noq.lua file, or get fresh info at: -http://dev.kernwaffe.de/projects/noq/wiki - -The NOQ Team - have fun! - diff --git a/pm/pm.lua b/pm/pm.lua deleted file mode 100644 index 49bb04b..0000000 --- a/pm/pm.lua +++ /dev/null @@ -1,33 +0,0 @@ - --- Private message -function et_ClientCommand(id, command) - if string.lower( et.trap_Argv(0) ) == "pm" then - - if tonumber( et.trap_Argc ) < 3 then - et.trap_SendServerCommand( id, "chat \"Usage: pm name message\"" ) - return(1) - end - - local recipient_name = string.lower( et.Q_CleanStr( et.trap_Argv(1) ) ) - - if recipient_name then - for i=0, tonumber( et.trap_Cvar_Get( "sv_maxclients" ) )-1 do - local player_name = et.gentity_get( i, "pers.netname" ) - - if recipient_name then - local sender_name = et.gentity_get( id, "pers.netname" ) - s, e = string.find( string.lower( et.Q_CleanStr( player_name ) ), recipient_name ) - if s and e then - if i ~= id then -- PMing yourself? - et.trap_SendServerCommand( i, "chat \"" .. sender_name .. "^7 -> " .. player_name .. "^7: ^5" .. et.ConcatArgs(2) .. "\"" ) - end - et.trap_SendServerCommand( id, "chat \"" .. sender_name .. "^7 -> " .. player_name .. "^7: ^5" .. et.ConcatArgs(2) .. "\"" ) - return(1) -- send only to the first player matched - end - end - end - et.trap_SendServerCommand( id, "chat \"No player whose name matches the pattern \'" .. recipient_name .. "\' was found.\"" ) - return(1) - end - end -end diff --git a/rating/rating.lua b/rating/rating.lua deleted file mode 100755 index 43da3e0..0000000 --- a/rating/rating.lua +++ /dev/null @@ -1,370 +0,0 @@ ---[[ - Author: [Spyhawk] - License: ISC - Website: http://www.etlegacy.com - Mod: compatible with Legacy mod only - - Description: Skill Rating (aka TrueSkill) data management - Use in conjunction with g_skillRating cvar -]]-- - ---[[ - TODO: - * 0.1: handle basic rating update functionality - * 0.2: handle disconnected then reconnected clients - * 0.3: handle clients that left - * 0.4: handle map bias parameter - * 0.5: add useful commands -]]-- - --- Lua module version -local version = "0.2" - --- load sqlite driver (or mysql..) -local luasql = require "luasql.sqlite3" - -local env -- environment object -local con -- database connection -local cur -- cursor - --- database path -local dbpath = string.gsub(et.trap_Cvar_Get("fs_homepath"), "\\", "/").."/"..et.trap_Cvar_Get("fs_game").."/" - --- check feature -local g_skillRating = tonumber(et.trap_Cvar_Get("g_skillRating")) - ---[[ - Functions -]]-- - --- 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 - --- con:prepare with bind_names should be used to prevent SQL injections --- but it isn't currently implemented in LuaSQL -function validateGUID(clientNum, guid) - -- allow only alphanumeric characters in guid - if(string.match(guid, "%W")) then - -- Invalid characters detected. We should probably drop this client - et.G_Print("^1[Skill Rating]:^7 User with ID " .. clientNum .. " has an invalid GUID: " .. guid .. "\n") - et.trap_SendServerCommand (clientNum, "cpm \"^2Your Skill Rating won't be saved because you have an invalid GUID!\n\"") - return false - end - - return true -end - --- saves SR values of a player with id 'clientNum' into database -function saveSR(clientNum) - local name = et.Info_ValueForKey(et.trap_GetUserinfo(clientNum), "name") - local guid = et.Info_ValueForKey(et.trap_GetUserinfo(clientNum), "cl_guid") - - if not validateGUID(clientNum, 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 - -- should not happen - et.G_Print("^1[Skill Rating]:^7 User not found in database!\n") - -- cur:close() - return - else - -- save data - cur = assert(con:execute(string.format([[UPDATE users SET - last_seen='%s', - mu='%f', - sigma='%f' - WHERE guid='%s']], - os.date("%Y-%m-%d %H:%M:%S"), - et.gentity_get(clientNum, "sess.mu"), - et.gentity_get(clientNum, "sess.sigma"), - guid - ))) - end - -- cur:close() -end - ---[[ - Callbacks -]]-- - --- called when game initializes -function et_InitGame(levelTime, randomSeed, restart) - -- register name of this module - et.RegisterModname("Skill Rating " .. version) - - -- check status - if tonumber(et.trap_Cvar_Get("g_skillRating")) < 1 then return end - - -- create environement object - env = assert(luasql.sqlite3()) - - -- connect to database - con = assert(env:connect(dbpath .. "rating.sqlite")) - - -- drop database - -- cur = assert(con:execute("DROP TABLE users")) - cur = assert(con:execute("DROP TABLE IF EXISTS match")) - - -- create database - cur = assert(con:execute[[ - CREATE TABLE IF NOT EXISTS users( - guid VARCHAR(64), - last_seen VARCHAR(64), - mu REAL, - sigma REAL, - UNIQUE (guid) - ) - ]]) - - cur = assert(con:execute[[ - CREATE TABLE match( - guid VARCHAR(64), - time_axis INT, - time_allies INT, - UNIQUE (guid) - ) - ]]) - --cur:close() -end - --- called when game shuts down -function et_ShutdownGame(restart) - -- check status - if g_skillRating < 1 then return end - -- clean up - cur:close() - con:close() - env:close() -end - --- called every server frame -function et_RunFrame(levelTime) - -- check status - if g_skillRating < 1 then return end - - -- check gamestate changes - gamestate = tonumber(et.trap_Cvar_Get("gamestate")) - - if oldgamestate ~= gamestate then - oldgamestate = tonumber(et.trap_Cvar_Get("gamestate")) - - -- GS_WARMUP - -- if gamestate == 1 then - -- et.G_Print("^1[Skill Rating]:^7 GS_WARMUP\n") - -- end - - -- GS_PLAYING - -- if gamestate == 0 then - -- et.G_Print("^1[Skill Rating]:^7 GS_PLAYING\n") - -- end - - -- GS_INTERMISSION - if gamestate == 3 then - -- et.G_Print("^1[Skill Rating]:^7 GS_INTERMISSION\n") - - local clientNum = 0 - local maxclients = tonumber(et.trap_Cvar_Get("sv_maxclients")) - - -- iterate through clients - while clientNum < maxclients do - local cs = et.trap_GetConfigstring(tonumber(et.CS_PLAYERS) + clientNum) - -- save new ratings - if cs ~= nil and cs ~= "" then - saveSR(clientNum) - end - clientNum = clientNum + 1 - end - end - end -end - --- called for every ClientConnect -function et_ClientConnect(clientNum, firstTime, isBot) - -- check status - if g_skillRating < 1 then return end -end - --- called for every ClientDisconnect -function et_ClientDisconnect(clientNum) - -- check status - if g_skillRating < 1 then return end - - local guid = et.Info_ValueForKey(et.trap_GetUserinfo(clientNum), "cl_guid") - local name = et.Info_ValueForKey(et.trap_GetUserinfo(clientNum), "name") - - if not validateGUID(clientNum, guid) then return end - - cur = assert(con:execute(string.format("SELECT * FROM users WHERE guid='%s' LIMIT 1", guid))) - local user = cur:fetch({}, 'a') - - if not user then - -- should not happen - et.G_Print("^1[Skill Rating]:^7 User not found in database!\n") - -- cur:close() - return - else - cur = assert(con:execute(string.format([[UPDATE users SET - last_seen='%s' - WHERE guid='%s']], - os.date("%Y-%m-%d %H:%M:%S"), - guid - ))) - - cur = assert(con:execute(string.format([[UPDATE match SET - time_axis='%i', - time_allies='%i' - WHERE guid='%s']], - et.gentity_get(clientNum, "sess.time_axis"), - et.gentity_get(clientNum, "sess.time_allies"), - guid - ))) - -- cur:close() - end - -- cur:close() -end - --- called for every ClientBegin -function et_ClientBegin(clientNum) - -- check status - if g_skillRating < 1 then return end - - local guid = et.Info_ValueForKey(et.trap_GetUserinfo(clientNum), "cl_guid") - local name = et.Info_ValueForKey(et.trap_GetUserinfo(clientNum), "name") - - if not validateGUID(clientNum, guid) then return end - - cur = assert(con:execute(string.format("SELECT * FROM users WHERE guid='%s'", guid))) - local user = cur:fetch({}, 'a') - - if not user then - -- first time this user is seen - et.trap_SendServerCommand(clientNum, "cpm \"^2[Skill Rating]:^7 Welcome, " .. name .. "^7! You are playing on an Skill Rating enabled server\n\"") - - -- use default values - cur = assert(con:execute(string.format("INSERT INTO users VALUES ('%s', '%s', '%f', '%f')", - guid, - os.date("%Y-%m-%d %H:%M:%S"), - 25, - 25/3 - ))) - - cur = assert(con:execute(string.format("INSERT INTO match VALUES ('%s', '%i', '%i')", - guid, - 0, - 0 - ))) - -- cur:close() - else - -- load current rating - et.gentity_set(clientNum, "sess.mu", tonumber(user.mu)) - et.gentity_set(clientNum, "sess.sigma", tonumber(user.sigma)) - -- create copy for delta rating - et.gentity_set(clientNum, "sess.oldmu", tonumber(user.mu)) - et.gentity_set(clientNum, "sess.oldsigma", tonumber(user.sigma)) - - et.trap_SendServerCommand(clientNum, string.format("cpm \"^2[Skill Rating]:^7 Welcome back, %s^7! Your rating is ^3%.2f\n\"", - name, math.max(user.mu - 3 * user.sigma, 0)) - ) - - -- load current play time, if reconnecting to the same match - cur = assert(con:execute(string.format("SELECT * FROM match WHERE guid='%s'", guid))) - local player = cur:fetch({}, 'a') - - if player then - et.gentity_set(clientNum, "sess.time_axis", tonumber(player.time_axis)) - et.gentity_set(clientNum, "sess.time_allies", tonumber(player.time_allies)) - end - - end - -- cur:close() -end - --- called for every client command --- return 1 if intercepted, 0 if passthrough -function et_ClientCommand(clientNum, cmd) - -- check status - if g_skillRating < 1 then return 0 end - - -- local cmd = et.trap_Argv(0) - cmd = string.lower(cmd) - - -- display current rating - if cmd == "!sr" then - local mu = et.gentity_get(clientNum, "sess.mu") - local sigma = et.gentity_get(clientNum, "sess.sigma") - - et.trap_SendServerCommand(clientNum, string.format("cpm \"^2[Skill Rating]:^7 Your rating is ^3%.2f\n\"", - math.max(mu - 3 * sigma, 0)) - ) - return 1 - end - - return 0 -end - --- called for every console command --- return 1 if intercepted, 0 if passthrough -function et_ConsoleCommand() - -- check status - if g_skillRating < 1 then return 0 end - - local cmd = et.trap_Argv(0) - cmd = string.lower(cmd) - - -- drop users - if cmd == "!srdbdrop" then - -- FIXME: LuaSQL: database table is locked - cur = assert(con:execute("DROP TABLE users")) - et.G_Print("^2[Skill Rating]:^7 Dropped users table\n") - -- cur:close() - return 1 - end - - -- drop match players time - if cmd == "!srmatchdrop" then - -- FIXME: LuaSQL: database table is locked - cur = assert(con:execute("DROP TABLE match")) - et.G_Print("^2[Skill Rating]:^7 Dropped match table\n") - -- cur:close() - return 1 - end - - -- list all users - if cmd == "!srdblist" then - cur = assert(con:execute("SELECT COUNT(*) FROM users")) - et.G_Print("^2[Skill Rating]:^3 " .. tonumber(cur:fetch(row, 'a')) .. "^7 users in database\n") - local guid, lastseen, mu, sigma - for guid, lastseen, mu, sigma in rows(con, "SELECT * FROM users") do - et.G_Print(string.format("\tGUID %s\tLast seen: %s mu: ^1%.2f^: sigma: ^4%.2f^: Rating: ^3%.2f\n", - guid, lastseen, mu, sigma, math.max(mu - 3 * sigma, 0)) - ) - end - -- cur:close() - return 1 - end - - -- list all match players - if cmd == "!srmatchlist" then - cur = assert(con:execute("SELECT COUNT(*) FROM match")) - et.G_Print("^2[Skill Rating]:^3 " .. tonumber(cur:fetch(row, 'a')) .. "^7 players in match\n") - local guid, time_axis, time_allies - for guid, time_axis, time_allies in rows(con, "SELECT * FROM match") do - et.G_Print(string.format("\tGUID %s\tTime Axis: %i\tTime Allies: %i\n", - guid, time_axis, time_allies) - ) - end - -- cur:close() - return 1 - end - - return 0 -end -