Last active
February 18, 2023 14:28
-
-
Save x0rnn/f4e10d5af7ee761fb6e1593dc5749b54 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- full server kick (fsk) script by "a domestic cat" | |
local events = wolfa_requireModule("util.events") | |
local auth = wolfa_requireModule("auth.auth") | |
-------------------- Configuration -------------------- | |
-- Defines delay before issuing a warning [seconds]. | |
-- Default: 180 (3 minutes) | |
WarnTime = 180 | |
-- Defines interval between warning and kick [seconds]. | |
-- Default: 60 (1 minute) | |
KickTime = 60 | |
-- Warning message text. | |
WarningMessage = "^7Server is full, please join a team or you might get kicked." | |
-- Starting level which from players are excluded from kicking. | |
AdminLevel = 2 | |
-- Kick duration [minutes]. | |
KickDuration = 0 | |
-- Kick message. | |
KickMessage = "^7When server is full, you're supposed to join a team or leave." | |
-- Log file name. | |
LogFile = "fsk.log" | |
-- Warn/kick regardless if player chats as spectator? | |
ChatKick = 1 | |
------------------------------------------------------- | |
players = {} | |
runFrameLast = 0 | |
maxClients = 64 | |
privateClients = 0 | |
serverFull = false | |
fsk = {} | |
function fsk.onGameInit(levelTime, randomSeed, restartMap) | |
runFrameLast = 0 | |
maxClients = tonumber(et.trap_Cvar_Get("sv_maxclients")) | |
privateClients = tonumber(et.trap_Cvar_Get("sv_privateclients")) | |
for clientNum = 0, maxClients - 1 do | |
players[clientNum] = nil | |
end | |
end | |
events.handle("onGameInit", fsk.onGameInit) | |
function fsk.onClientInfoChange(clientNum) | |
local team = tonumber(et.gentity_get(clientNum, "sess.sessionTeam")) | |
local level = auth.getPlayerLevel(clientNum) | |
if players[clientNum] == nil or players[clientNum].team ~= team then | |
local userinfo = et.trap_GetUserinfo(clientNum) | |
local password = et.Info_ValueForKey(userinfo, "password") | |
local private = false | |
local protected = false | |
if password ~= "" and password == et.trap_Cvar_Get("sv_privatepassword") then | |
private = true | |
protected = true | |
elseif level ~= nil and level >= AdminLevel then | |
protected = true | |
end | |
players[clientNum] = {team = team, joined = et.trap_Milliseconds(), warned = nil, protected = protected, private = private} | |
end | |
updateServerFull() | |
end | |
events.handle("onClientInfoChange", fsk.onClientInfoChange) | |
function fsk.onClientDisconnect(clientNum) | |
players[clientNum] = nil | |
local wasFull = serverFull | |
updateServerFull() | |
if wasFull and not serverFull then | |
for clientNum = 0, maxClients - 1 do | |
if players[clientNum] ~= nil and players[clientNum].warned ~= nil then | |
players[clientNum].warned = nil | |
end | |
end | |
end | |
end | |
events.handle("onClientDisconnect", fsk.onClientDisconnect) | |
function fsk.onGameFrame(levelTime) | |
if serverFull and runFrameLast + 5000 < levelTime then | |
runFrameLast = levelTime | |
local milliseconds = et.trap_Milliseconds() | |
local kickClientNum = nil | |
local kickMin = milliseconds | |
for clientNum = 0, maxClients - 1 do | |
if players[clientNum] ~= nil and players[clientNum].team == 3 and not players[clientNum].protected then | |
if players[clientNum].warned == nil and players[clientNum].joined + WarnTime * 1000 < milliseconds then | |
et.trap_SendServerCommand(clientNum, "cpm \"" .. WarningMessage .. "\n\"") | |
players[clientNum].warned = milliseconds | |
elseif players[clientNum].warned ~= nil and players[clientNum].warned + KickTime * 1000 < milliseconds then | |
if kickMin > players[clientNum].joined then | |
kickMin = players[clientNum].joined | |
kickClientNum = clientNum | |
end | |
end | |
end | |
end | |
if kickClientNum ~= nil then | |
local kName = et.gentity_get(kickClientNum, "pers.netname") | |
local userinfo = et.trap_GetUserinfo(kickClientNum) | |
local x, y, ip = string.find(string.upper(et.Info_ValueForKey(userinfo, "ip")), "(%d+%.%d+%.%d+%.%d+)") | |
local guid = et.Info_ValueForKey(userinfo, "cl_guid") | |
local time = os.date("%Y-%m-%d %H:%M:%S") | |
local line = "[" .. time .. "] [" .. ip .. "] [" .. guid .. "] [" .. kName .. "]\n" | |
local fd, len = et.trap_FS_FOpenFile(LogFile, et.FS_APPEND) | |
et.trap_FS_Write(line, string.len(line), fd) | |
et.trap_FS_FCloseFile(fd) | |
et.trap_DropClient(kickClientNum, KickMessage, KickDuration) | |
end | |
end | |
end | |
events.handle("onGameFrame", fsk.onGameFrame) | |
function updateServerFull() | |
local count = 0 | |
for clientNum = 0, maxClients - 1 do | |
if players[clientNum] ~= nil and not players[clientNum].private then | |
count = count + 1 | |
end | |
end | |
if count >= maxClients - privateClients then | |
serverFull = true | |
else | |
serverFull = false | |
end | |
end | |
function fsk.onClientCommand(clientNum, cmd) | |
if ChatKick == 0 then | |
if serverFull then | |
if et.trap_Argv(0) == "say" or et.trap_Argv(0) == "say_team" or et.trap_Argv(0) == "say_teamnl" or et.trap_Argv(0) == "pm" or et.trap_Argv(0) == "m" then | |
local team = tonumber(et.gentity_get(clientNum, "sess.sessionTeam")) | |
local level = auth.getPlayerLevel(clientNum) | |
if team == 3 then | |
local userinfo = et.trap_GetUserinfo(clientNum) | |
local password = et.Info_ValueForKey(userinfo, "password") | |
local private = false | |
local protected = false | |
if password ~= "" and password == et.trap_Cvar_Get("sv_privatepassword") then | |
private = true | |
protected = true | |
elseif level ~= nil and level >= AdminLevel then | |
protected = true | |
end | |
players[clientNum] = {team = team, joined = et.trap_Milliseconds(), warned = nil, protected = protected, private = private} | |
end | |
end | |
end | |
end | |
return(0) | |
end | |
events.handle("onClientCommand", fsk.onClientCommand) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment