-- Module: reyalp_autoref -- Version: 0.2.1 -- Author: reyalp (at) gmail.com + various bits stolen from bani examples -- Description: -- automatically give ref to certain players on connect, -- by GUID or IP -- Not only does this save them remembering the password, it also -- keeps them from sharing it, or accidentally typing it in open chat. -- They can of course still ref other players or share their etkey file -- (and thus GUID) -- Configuration: -- two files named autorefips and autorefguids -- each file should contain a whitespace or newline delimited list, -- and be located in your ET search path (either etmain or your fs_game) -- autorefguids lists PB guids, as printed by pb_sv_plist or in userinfo cl_guid -- autorefips lists IPs in dotted decimal notation, e.g. 127.0.0.1 -- if either file is missing a warning is printed and processing continues. -- Note that autorefing is done in ClientBegin (when a client connects, -- or on map change/restart), so loading the list does not by itself change -- anyones ref status. -- The lists are automatically loaded in initgame. They can also -- be manually re-loaded from the server console. -- Server console Commands: -- autoref -- where is -- load - load list files, discarding any in-memory lists -- list - list autoref IPs and GUIDs -- clear - clear in memory list, files are not changed -- help - list these commands -- -- Changelog -- 0.2.1 -- support etpro-lua-2 and above, which restart lua modules on each game restart -- load tables in initgame again -- 0.2 -- don't try to ref people who are already ref'd -- load tables on module start -- many other improvments -- 0.1 -- initial version -- Global autoref lists AutoRefIPs = {} AutoRefGUIDs = {} AutoRefVersion = "0.2.1" -- printf wrapper function et.G_Printf(...) et.G_Print(string.format(unpack(arg))) end -- load the lists function AutoRefLoad() local fd,len = et.trap_FS_FOpenFile( "autorefips", et.FS_READ ) -- et.G_Printf( "AutoRefLoad: %d %d\n",fd,len) if len == -1 then et.G_Printf( "WARNING: trap_FS_FOpenFile failed for autorefips\n") else local filestr = et.trap_FS_Read( fd, len ) for ip in string.gfind(filestr, "(%d+%.%d+%.%d+%.%d+)%s") do et.G_Printf( "AutoRefLoad: ip '%s'\n",ip) AutoRefIPs[ip] = true end et.trap_FS_FCloseFile( fd ) end fd,len = et.trap_FS_FOpenFile( "autorefguids", et.FS_READ ) if len == -1 then et.G_Printf( "WARNING: trap_FS_FOpenFile failed for autorefguids\n") else local filestr = et.trap_FS_Read( fd, len ) for guid in string.gfind(filestr, "(%x+)%s") do -- upcase for exact matches guid = string.upper(guid) et.G_Printf( "AutoRefLoad: guid '%s'\n",guid) AutoRefGUIDs[guid] = true end et.trap_FS_FCloseFile( fd ) end end -- TODO show which are connected function AutoRefList() et.G_Print("autoref IPs\n") for k in pairs(AutoRefIPs) do et.G_Printf(" %s\n",k); end et.G_Print("autoref GUIDs\n") for k in pairs(AutoRefGUIDs) do et.G_Printf(" %s\n",k); end end -- called when game inits function et_InitGame( levelTime, randomSeed, restart ) -- et.G_Printf( "et_InitGame [%d] [%d] [%d]\n", levelTime, randomSeed, restart ) et.G_Printf( "reyalP autoref version %s\n",AutoRefVersion ) et.RegisterModname( "reyalp_autoref-" .. AutoRefVersion .. " " .. et.FindSelf() ) -- load autoref tables AutoRefLoad() end function AutoRefClient( clientNum ) local isref = et.Info_ValueForKey( et.trap_GetConfigstring( et.CS_PLAYERS + clientNum ), "ref" ) if isref ~= "0" then -- temp test -- et.G_Printf("already ref '%s'\n",isref) return end local userinfo = et.trap_GetUserinfo( clientNum ) local ip = et.Info_ValueForKey( userinfo, "ip" ) -- strip port ip = string.sub(ip,string.find(ip,"(%d+%.%d+%.%d+%.%d+)")) local guid = et.Info_ValueForKey( userinfo, "cl_guid" ) -- upcase for exact matches guid = string.upper(guid) et.G_Printf( "client %d ip %s guid '%s'\n", clientNum, ip, guid ) if ( AutoRefIPs[ip] or AutoRefGUIDs[guid] ) then et.G_Printf( "autoref client %d\n", clientNum, ip, guid) et.trap_SendConsoleCommand( et.EXEC_APPEND, "ref referee " .. clientNum .. "\n" ) end end --[[ this would be nice, but it crashes function et_ClientConnect( clientNum, firstTime, isBot ) et.G_Printf( "et_ClientConnect: [%d]\n", clientNum ) if firstTime then AutoRefClient(clientNum) end end --]] -- called for every ClientBegin -- this tries to autoref on every map change. We catch that later to avoid console spam function et_ClientBegin( clientNum ) AutoRefClient(clientNum) end function AutoRefClear() et.G_Print("clearing autoref lists...\n"); AutoRefIPs = {} AutoRefGUIDs = {} end function AutoRefHelp() et.G_Print("autoref commands\n"); for k in pairs(AutoRefCommands) do et.G_Printf(" %s\n",k); end end -- lookup table of console commands AutoRefCommands = { ["load"] = AutoRefLoad, ["list"] = AutoRefList, ["help"] = AutoRefHelp, ["clear"] = AutoRefClear } -- called for every consolecommand -- return 1 if intercepted, 0 if passthrough function et_ConsoleCommand() -- et.G_Printf( "et_ConsoleCommand: [%s] [%s]\n", et.trap_Argc(), et.trap_Argv(0) ) if et.trap_Argv(0) == "autoref" then if et.trap_Argc() == 1 then AutoRefHelp() elseif not AutoRefCommands[et.trap_Argv(1)] then et.G_Printf( "unknown autoref command '%s' try autoref help\n",et.trap_Argv(1)) else AutoRefCommands[et.trap_Argv(1)](); end return 1 end return 0 end -- called for every clientcommand -- return 1 if intercepted, 0 if passthrough --[[ function et_ClientCommand( clientNum, cmd ) et.G_Printf( "et_ClientCommand: [%d] [%s]\n", et.trap_Argc(), cmd ) return 0 end function et_ClientSay( clientNum, mode, text ) et.G_Printf( "et_ClientSay [%d] [%d] [%s]\n", clientNum, mode, text ) if text == "!pwn" then et.gentity_set( clientNum, "health", 0) end return 0 end --]] -- for CS_PLAYERs require("etconst")