removed obsolete scripts

This commit is contained in:
Remy Marquis 2017-03-04 20:01:56 +01:00
parent de1cbb4813
commit a172ad86c3
30 changed files with 1 additions and 5856 deletions

View File

@ -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
```

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

Binary file not shown.

View File

@ -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",
},
}

View File

@ -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,
},
}

View File

@ -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",
},
}

View File

@ -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,
},
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -1,136 +0,0 @@
# <PARAMETER> = text followed by the command. (Can be used to enter multiple values.
# For example: pb_sv_kick <PARAMETER> can be used to enter slot number, length of kick, and reason.)
# <CLIENT_ID> = the client id of the calling player.
# <PLAYER_LAST_VICTIM_(ID|NAME|CNAME|WEAPON)> = last player, you killed
# <PLAYER_LAST_KILLER_(ID|NAME|CNAME|WEAPON)> = last player, that killed you
# <PLAYER_CLASS> = class of calling player
# <PLAYER_TEAM> = side / team of calling player
# <PLAYER> = Name of the calling player (without color codes)
# <COLOR_PLAYER> = Name of the calling player (with color codes)
# <GUID> = Guid of the calling player (without color codes)
# parallel: all attributes for the second player(specified via part of name or slotnumber):
#<PART2_CLASS> = class
#<PART2_TEAM> = team
#<PART2CNAME> = colored name
#<PART2ID> = id
#<PART2PBID> = punkbuster slotnumber
#<PART2GUID> = guid
#<PART2LEVEL> = adminlevel
#<PART2NAME> = name without color
0 - help =
#Level - command = rcon command
#command Examples:
#0 - ref = ref referee <CLIENT_ID>
#2 - vkick = clientkick <PLAYER_LAST_KILLER_ID>
#A bad example would be
#0 - kick player = clientkick <PARAMETER>
#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 <CLIENT_ID>
2 - unref = ref unReferee <CLIENT_ID>
2 - shuffle = shuffle_teams
2 - map_restart = map_restart
2 - pbkick = pb_sv_kick <PART2ID>
3 - cancelvote = cancelvote
3 - passvote = passvote
3 - cp = cp <PARAMETER>
3 - qsay = qsay <PARAMETER>
3 - devmap = devmap <PARAMETER>
3 - exec = exec <PARAMETER>
# Referee Commands (only ETPRO)
#2 - putallies = ref putallies <PART2ID>
#2 - putspec = ref remove <PART2ID>
#2 - putaxis = ref putaxis <PART2ID>
#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 <PARAMETER>
#3 - campaign = ref campaign <PARAMETER>
#3 - gametype = ref gametype <PARAMETER>
#3 - config = ref config <PARAMETER>
#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 <PARAMETER>
# To kick a player without temporary ban. Change the message, if you like.
2 - fkick = pb_sv_kick <PART2PBID> 0 Come back in, if you want
# Shortcut to make the called a shoutcaster / remove his statua
3 - ms = makeShoutcaster <CLIENT_ID>
0 - rs = removeShoutcaster <CLIENT_ID>
# Moves the calling person into the specific team
#2 - putmeaxis = ref putaxis <CLIENT_ID>
#2 - putmeallies = ref putallies <CLIENT_ID>
#2 - putmespec = ref remove <CLIENT_ID>
#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<COLOR_PLAYER>^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<COLOR_PLAYER>^7 a hot pepperoni pizza!
0 - coke = qsay ^3Ah... A delicious glass of cold Coca Cola[tm] (*thinks ^7<COLOR_PLAYER>^3 while he drinks*)
0 - pfstinkt = qsay ^3Uh, that smell of the panzer is pretty strong today ... ^3(^7<COLOR_PLAYER>^3's opinion)
0 - bye = qsay ^7<COLOR_PLAYER>^3 waves his hand to say ^1GOOD BYE^3. We surely meet later! ; playsound -1 sound/misc/bye.wav
0 - backrage = qsay ^3Wow, <PLAYER_LAST_KILLER_CNAME> ^3has backrage skills with his uber ^1<PLAYER_LAST_KILLER_WEAPON>
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 <RANDOM_CNAME> ^3is on the <RANDOM_TEAM> team as a <RANDOM_CLASS>!
#for spamming
0 - owned = qsay ^1Ha^3ha^5ha^3, I owned ^7<PLAYER_LAST_VICTIM_CNAME>^3 with my ^7<PLAYER_LAST_VICTIM_WEAPON>^3!!!
0 - pants = qsay ^1No^3no^5noooo^3, I was killed by ^7<PLAYER_LAST_KILLER_CNAME>^3 with a ^7<PLAYER_LAST_KILLER_WEAPON>^3!!!
0 - whoami = qsay I am <COLOR_PLAYER>^7. I play ^3<PLAYER_CLASS>^7 on the ^3<PLAYER_TEAM>^7 side.
0 - victimized = qsay <PLAYER_LAST_VICTIM_CNAME>^1, You've just been victimized by <COLOR_PLAYER>^1's <PLAYER_LAST_VICTIM_WEAPON>!!!
#other
#2 - vkick = clientkick <PLAYER_LAST_KILLER_ID>
#2 - vmute = ref mute <PLAYER_LAST_KILLER_ID>
#3 - bluerespawn = forcecvar g_bluelimbotime <PARAMETER>
#3 - redrespawn = forcecvar g_redlimbotime <PARAMETER>
#2 - showtk = $LUA$ showTkTable(<CLIENT_ID>)

View File

@ -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"] = "<XXX>",
["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",
},
}

View File

@ -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='<name>".. thisName .."</name>' 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, '<name>".. thisName .."</name>')"))
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) -- <name>FOOBAR</name> 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

View File

@ -1,10 +0,0 @@
return {
-- Table: {1}
{
[0]=nil, -- this means no greeting for that level
"^1Welcome Level 1 player <COLOR_PLAYER>", -- this is level 1 greeting
"^1Welcome Level 2 player <COLOR_PLAYER>", -- this is level 2 greeting
"^1Welcome Level .. argh, you get it....",
[4]= nil, -- no greeting for level 4
},
}

View File

@ -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

View File

@ -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",
},
}

View File

@ -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",
},
}

View File

@ -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,
},
}

View File

@ -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,
},
}

View File

@ -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",
},
}

View File

@ -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",
},
}

View File

@ -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,
},
}

View File

@ -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,
},
}

View File

@ -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

View File

@ -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!

View File

@ -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

View File

@ -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