--------------------------------------------- -- KNOWNGUIDSV2.LUA --------------------------------------------- -- PURPOSE: -- This script prevents clients with a pbguid never before seen by the server from joining a team until they have served -- a wait-time (defined by "wait_time_mins" below). It is intended to prevent clients who have been kicked/banned from -- the server from being able to reconnect and play again immediately if they have simply obtained a new pbguid. -- DESCRIPTION: -- This script captures the pbguids (from Userinfo: cl_guid) of clients as they connect to the server and checks them -- against a serverside list (knownguids.txt). If the pbguid is present on the list the client is allowed to play -- immediately. If the pbguid is not present then the client is forced to wait in spectator mode for the designated -- time, and their pbguid is added to the list. In addition, this script performs a basic length and hex char test on -- the pbguid that will immediately kick obviously spoofed examples. -- INSTALLATION: -- 1. Save the "knownguidsv2.lua" script in the server's etpro folder. -- 2. Add the line: set lua_modules "knownguidsv2.lua" to your server.cfg. -- 3. Restart your server. -- 4. It is recommended to set "force_wait" to 0 for a short while (e.g. 1 week) after installation to allow the pbguids -- of your regular players to be collected to minimise inconvenience. -- GhosT:McSteve -- www.ghostworks.co.uk -- Version 2, 4/2/08 ----------------------------------------------------------------------------------- -- ADMIN - SET THE OPTIONS HERE -- switch the wait-time on/off by setting force_wait = 1/0 force_wait = 1 --wait time in minutes wait_time_mins = 1 ----------------------------------------------------------------------------------- ---------------------- DO NOT MODIFY BELOW THIS LINE ---------------------------- ----------------------------------------------------------------------------------- --convert the wait time to milliseconds wait_time_ms = wait_time_mins * 60 * 1000 -- on game initialise, get the maxclients and initialise the arrays function et_InitGame( levelTime, randomSeed, restart ) maxclients = tonumber(et.trap_Cvar_Get( "sv_maxClients" )) enter_time = {} for i = 0, (maxclients - 1) do enter_time[i] = 0 end end function et_ClientBegin( cno ) --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3clientbegin called\"\n") local cl_guid = string.upper(et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "cl_guid" )) --guidvaliditytest() -- check the guid is 32 chars and hex if guidvaliditycheck(cl_guid) == 1 then knownguidcheck(cno, cl_guid) --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3guidvaliditycheck = 1\"\n") elseif guidvaliditycheck(cl_guid) == 0 then --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3guidvaliditycheck = 0\"\n") et.trap_DropClient(cno, "The instruction at 0x00000000 referenced memory at 0x00000000. The memory could not be read.") end --guidcheck(cno, cl_guid) -- check to see if guid is in the list end -- called on client command function et_ClientCommand(cno, cmd) if force_wait ~= 1 then return 0 end if enter_time[cno] == 0 then return 0 end if et.gentity_get(cno, "sess.sessionTeam") == 3 then -- check for a team join if string.lower(cmd) == "team" then --if connect_time < wait_time then deny team join local time_connected = (et.trap_Milliseconds() - enter_time[cno]) if time_connected < wait_time_ms then et.trap_SendServerCommand(cno, "cp \"^3Sorry, you must wait^5 " .. wait_time_mins .. " ^3minutes before joining a team. This is an anti-cheat measure. Thanks for your patience.\n\" " ) return 1 else -- if time_connected is NOT < wait_time, AND enter_time[cno] is non-zero, then a client -- with a new guid has served his wait time, so we can add the guid to file local cl_guid = string.upper(et.Info_ValueForKey( et.trap_GetUserinfo( cno ), "cl_guid" )) local fd,len = et.trap_FS_FOpenFile( "knownguids.txt", et.FS_APPEND ) local info = cl_guid .. "\n" local count = et.trap_FS_Write(info, string.len(info), fd) et.trap_FS_FCloseFile( fd ) -- set enter_time for this client to 0 so the client is not subjected to testing again enter_time[cno] = 0 end end end return 0 end function knownguidcheck(temp_cno, temp_cl_guid) --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3knownguidcheck called\"\n") --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^2temp_cl_guid:^7 " .. temp_cl_guid .. "\"\n") local fd,len = et.trap_FS_FOpenFile( "knownguids.txt", et.FS_READ ) if len == -1 then et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3WARNING: File does not exist!\"\n") else local filestr = et.trap_FS_Read(fd, len) guidsearch = string.find(filestr, temp_cl_guid) et.trap_FS_FCloseFile( fd ) --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3file read and closed\"\n") --if guidsearch ~= nil then --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^2guidsearch:^7 " .. guidsearch .. "\"\n") --end if guidsearch then -- if guid is found, we dont need to do anything --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3if guidsearch then\"\n") --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^2enter_time[temp_cno]:^7 " .. enter_time[temp_cno] .. "\"\n") else --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3else guidsearch \"\n") -- if guid is not found, flag up the client as new (set enter_time to non-zero) and then add the guid enter_time[temp_cno] = et.trap_Milliseconds() --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^2enter_time[temp_cno]:^7 " .. enter_time[temp_cno] .. "\"\n") --[[ -- v2 - want to move the adding of the guid to sometime later, after the waittime has been served local fd,len = et.trap_FS_FOpenFile( "knownguids.txt", et.FS_APPEND ) info = temp_cl_guid .. "\n" count = et.trap_FS_Write(info, string.len(info), fd) et.trap_FS_FCloseFile( fd ) ]] end end end -- method 1, sloppy but works function guidvaliditycheck(temp_cl_guid) --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^5guidvaliditycheck entered\"\n") if string.len(temp_cl_guid) ~= 32 then -- kick the client return 0 elseif string.len(temp_cl_guid) == 32 then for i = 1, 32 do hex_test = string.find(temp_cl_guid, "%x", i) --et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^5hex test " .. i .. "\"\n") if hex_test == nil then -- kick the client return 0 end end return 1 end return 1 end