This is a little prototype with a ingame easy setup. I still need to test it further to make it bulletproof i just thought before i invest more time in this if that would make sense.
I hope this is displayed correct.
Code: Select all
-- AutoAdmin
-- ET 2.60b / N!tmod
--
-- Commands:
-- aa help
-- aa antirush
-- aa antirush [ID]
-- aa trickplant
-- aa trickplant [ID]
-- aa list
-- aa remove [NUMBER]
-- aa edit [NUMBER] [DISTANCE]
--
-- Authorization:
-- Commands only work for client slot 0
-- and only if the player's n_guid is listed in:
-- luas/autoadmin/guid.cfg
--
-- File format:
-- luas/autoadmin/protected_maps/[mapname].cfg
--
-- [antirush]
-- "Shortname" X Y Z Distance
--
-- [trickplant]
-- X Y Z Distance
--
-- Behavior:
-- Antirush:
-- During the first 30% of the map timelimit, rushing protected objectives
-- is blocked. Player is killed, planted dynamite is removed.
--
-- Trickplant:
-- If a player plants dynamite inside a protected trickplant area,
-- the planted dynamite is removed, but the player is not killed.
local MODNAME = "AutoAdmin"
local VERSION = "2.0"
local MAX_GENTITIES = 1024
local ANTIRUSH_SCAN_RANGE = 1000
local TRICKPLANT_SCAN_RANGE = 650
local PROTECT_PERCENT = 0.30
local GUID_FILE = "luas/autoadmin/guid.cfg"
local MAP_DIR = "luas/autoadmin/protected_maps/"
local antirushEntries = {}
local trickplantEntries = {}
local currentLevelTime = 0
local protectionStartLevelTime = 0
local announceDone = false
local announceAtLevelTime = 0
local protectionExpiredAnnounced = false
local DYNAMITE_PLANT_PATTERN = '^Dynamite_Plant:%s*(%d+)%s*$'
local function printToClient(clientNum, text)
et.trap_SendServerCommand(clientNum, 'print "' .. text .. '\n"')
end
local function chatAll(text)
et.trap_SendServerCommand(-1, 'chat "' .. text .. '\n"')
end
local function appendLine(fd, line)
local text = tostring(line) .. "\n"
et.trap_FS_Write(text, string.len(text), fd)
end
local function trim(s)
if not s then
return ""
end
return string.gsub(string.gsub(s, "^%s+", ""), "%s+$", "")
end
local function sanitizeMapname(name)
if not name or name == "" then
return "unknownmap"
end
return string.gsub(name, "[^%w_%-%+]", "_")
end
local function sanitizeText(value)
if not value or value == "" then
return "-"
end
value = tostring(value)
value = string.gsub(value, '"', "'")
value = string.gsub(value, "[\r\n]", " ")
return value
end
local function tryGetField(entNum, fieldName)
local ok, value = pcall(et.gentity_get, entNum, fieldName)
if ok and value ~= nil then
return value
end
return nil
end
local function vectorToXYZ(v)
if type(v) ~= "table" then
return nil, nil, nil
end
if v[1] ~= nil and v[2] ~= nil and v[3] ~= nil then
return tonumber(v[1]), tonumber(v[2]), tonumber(v[3])
end
return nil, nil, nil
end
local function parseOriginString(origin)
if not origin or origin == "" then
return nil, nil, nil
end
local x, y, z = string.match(
tostring(origin),
"([%-%.%d]+)%s+([%-%.%d]+)%s+([%-%.%d]+)"
)
if x and y and z then
return tonumber(x), tonumber(y), tonumber(z)
end
return nil, nil, nil
end
local function distance3d(x1, y1, z1, x2, y2, z2)
local dx = x2 - x1
local dy = y2 - y1
local dz = z2 - z1
return math.sqrt(dx * dx + dy * dy + dz * dz)
end
local function getSpawnVar(entNum, key)
local ok, value = pcall(et.G_GetSpawnVar, entNum, key)
if ok and value and value ~= "" then
return tostring(value)
end
return nil
end
local function getMapName()
local mapname = et.trap_Cvar_Get("mapname")
if not mapname or mapname == "" then
mapname = "unknownmap"
end
return sanitizeMapname(mapname)
end
local function getMapFilePath()
return MAP_DIR .. getMapName() .. ".cfg"
end
local function getMapTimeLimitMinutes()
local timelimit = et.trap_Cvar_Get("timelimit")
local n = tonumber(timelimit)
if not n or n < 0 then
return 0
end
return n
end
local function getProtectMinutes()
return getMapTimeLimitMinutes() * PROTECT_PERCENT
end
local function getProtectMilliseconds()
return getProtectMinutes() * 60000.0
end
local function isProtectionActive()
return currentLevelTime < (protectionStartLevelTime + getProtectMilliseconds())
end
local function readWholeFile(path)
local fd, len = et.trap_FS_FOpenFile(path, et.FS_READ)
if not fd or fd < 0 then
return nil
end
if not len or len <= 0 then
et.trap_FS_FCloseFile(fd)
return ""
end
local content = et.trap_FS_Read(fd, len)
et.trap_FS_FCloseFile(fd)
return content
end
local function getPlayerOrigin(clientNum)
local vec = tryGetField(clientNum, "ps.origin")
if vec then
local x, y, z = vectorToXYZ(vec)
if x and y and z then
return x, y, z
end
end
vec = tryGetField(clientNum, "r.currentOrigin")
if vec then
local x, y, z = vectorToXYZ(vec)
if x and y and z then
return x, y, z
end
end
return nil, nil, nil
end
local function getPlayerName(clientNum)
local userinfo = et.trap_GetUserinfo(clientNum)
if not userinfo or userinfo == "" then
return tostring(clientNum)
end
local name = et.Info_ValueForKey(userinfo, "name")
if not name or name == "" then
return tostring(clientNum)
end
return name
end
local function getPlayerNGuid(clientNum)
local userinfo = et.trap_GetUserinfo(clientNum)
if not userinfo or userinfo == "" then
return nil
end
local nguid = et.Info_ValueForKey(userinfo, "n_guid")
if not nguid or nguid == "" then
return nil
end
return nguid
end
local allowedGuids = {}
local function loadAllowedGuids()
allowedGuids = {}
local content = readWholeFile(GUID_FILE)
if not content then
et.G_Print(MODNAME .. ": no guid file found at " .. GUID_FILE .. "\n")
return
end
for line in string.gmatch(content, "[^\r\n]+") do
local guid = trim(line)
if guid ~= "" then
allowedGuids[guid] = true
end
end
et.G_Print(MODNAME .. ": loaded allowed GUIDs from " .. GUID_FILE .. "\n")
end
local function isAuthorized(clientNum)
if clientNum ~= 0 then
return false
end
local nguid = getPlayerNGuid(clientNum)
if not nguid then
return false
end
return allowedGuids[nguid] == true
end
local function requireAuthorization(clientNum)
if isAuthorized(clientNum) then
return true
end
printToClient(clientNum, "^1AUTOADMIN:^7 command not authorized")
return false
end
local function getEntityClassname(entNum)
local classname = tryGetField(entNum, "classname")
if classname then
return tostring(classname)
end
classname = getSpawnVar(entNum, "classname")
if classname then
return classname
end
return nil
end
local function isAntirushClass(classname)
return classname == "team_WOLF_objective"
or classname == "team_CTF_redflag"
or classname == "team_CTF_blueflag"
or classname == "trigger_objective_info"
end
local function isDynamiteClass(classname)
if not classname then
return false
end
return string.find(string.lower(classname), "dynamite", 1, true) ~= nil
end
local function getEntityShortname(entNum)
local shortname = getSpawnVar(entNum, "shortname")
if shortname and shortname ~= "" then
return shortname
end
local message = getSpawnVar(entNum, "message")
if message and message ~= "" then
return message
end
local targetname = getSpawnVar(entNum, "targetname")
if targetname and targetname ~= "" then
return targetname
end
return "unknown"
end
local function getEntityOrigin(entNum)
local origin = getSpawnVar(entNum, "origin")
if origin then
local x, y, z = parseOriginString(origin)
if x and y and z then
return x, y, z
end
end
local vec = tryGetField(entNum, "r.currentOrigin")
if vec then
local x, y, z = vectorToXYZ(vec)
if x and y and z then
return x, y, z
end
end
return nil, nil, nil
end
local function isWithinBoxRange(px, py, pz, ex, ey, ez, range)
return math.abs(ex - px) <= range
and math.abs(ey - py) <= range
and math.abs(ez - pz) <= range
end
local function writeProtectedFile()
local path = getMapFilePath()
local fd, len = et.trap_FS_FOpenFile(path, et.FS_WRITE)
if not fd or fd < 0 then
return false, path
end
appendLine(fd, "[antirush]")
for i = 1, #antirushEntries do
local e = antirushEntries[i]
appendLine(fd, string.format('"%s" %.3f %.3f %.3f %.3f',
sanitizeText(e.shortname), e.x, e.y, e.z, e.distance))
end
appendLine(fd, "")
appendLine(fd, "[trickplant]")
for i = 1, #trickplantEntries do
local e = trickplantEntries[i]
appendLine(fd, string.format('%.3f %.3f %.3f %.3f',
e.x, e.y, e.z, e.distance))
end
et.trap_FS_FCloseFile(fd)
return true, path
end
local function loadProtectedFile()
antirushEntries = {}
trickplantEntries = {}
local content = readWholeFile(getMapFilePath())
if not content then
et.G_Print(MODNAME .. ": no protected map cfg found for " .. getMapName() .. "\n")
return
end
local section = ""
for line in string.gmatch(content, "[^\r\n]+") do
line = trim(line)
if line ~= "" then
if line == "[antirush]" then
section = "antirush"
elseif line == "[trickplant]" then
section = "trickplant"
elseif section == "antirush" then
local shortname, x, y, z, distance = string.match(
line,
'^"(.-)"%s+([%-%.%d]+)%s+([%-%.%d]+)%s+([%-%.%d]+)%s+([%-%.%d]+)%s*$'
)
if shortname and x and y and z and distance then
antirushEntries[#antirushEntries + 1] = {
shortname = shortname,
x = tonumber(x),
y = tonumber(y),
z = tonumber(z),
distance = tonumber(distance)
}
end
elseif section == "trickplant" then
local x, y, z, distance = string.match(
line,
'^([%-%.%d]+)%s+([%-%.%d]+)%s+([%-%.%d]+)%s+([%-%.%d]+)%s*$'
)
if x and y and z and distance then
trickplantEntries[#trickplantEntries + 1] = {
x = tonumber(x),
y = tonumber(y),
z = tonumber(z),
distance = tonumber(distance)
}
end
end
end
end
et.G_Print(MODNAME .. ": loaded " .. tostring(#antirushEntries) .. " antirush entries and "
.. tostring(#trickplantEntries) .. " trickplant entries\n")
end
local function getAntirushNamesString()
local names = {}
for i = 1, #antirushEntries do
names[#names + 1] = antirushEntries[i].shortname
end
return table.concat(names, ", ")
end
local function announceProtectedObjectives()
if #antirushEntries == 0 then
return
end
chatAll(string.format(
'^3AUTOADMIN:^7 Rushing the following objectives is prohibited for the first ^3%.1f ^7minutes: ^3%s',
getProtectMinutes(),
getAntirushNamesString()
))
end
local function announceProtectionEnded()
if #antirushEntries == 0 then
return
end
chatAll(string.format(
'^3AUTOADMIN:^7 The following objectives are no longer protected: ^3%s',
getAntirushNamesString()
))
end
local function buildCombinedList()
local combined = {}
for i = 1, #antirushEntries do
combined[#combined + 1] = {
type = "antirush",
index = i
}
end
for i = 1, #trickplantEntries do
combined[#combined + 1] = {
type = "trickplant",
index = i
}
end
return combined
end
local function listSavedEntries(clientNum)
local combined = buildCombinedList()
printToClient(clientNum, "^3AUTOADMIN")
if #combined == 0 then
printToClient(clientNum, "^1No saved entries.")
return
end
for i = 1, #combined do
local ref = combined[i]
if ref.type == "antirush" then
local e = antirushEntries[ref.index]
printToClient(clientNum,
string.format("%d - ANTIRUSH - %s - %.0f", i, sanitizeText(e.shortname), e.distance))
else
local e = trickplantEntries[ref.index]
printToClient(clientNum,
string.format("%d - TRICKPLANT - %.3f %.3f %.3f - %.0f", i, e.x, e.y, e.z, e.distance))
end
end
printToClient(clientNum, "^3aa remove [NUMBER]^7 removes an entry.")
printToClient(clientNum, "^3aa edit [NUMBER] [DISTANCE]^7 changes the distance.")
end
local function removeSavedEntry(clientNum, wantedIndex)
local idx = tonumber(wantedIndex)
if not idx then
printToClient(clientNum, "^1aa remove:^7 invalid number")
return
end
local combined = buildCombinedList()
if idx < 1 or idx > #combined then
printToClient(clientNum, "^1aa remove:^7 number out of range")
return
end
local ref = combined[idx]
local removedText
if ref.type == "antirush" then
removedText = sanitizeText(antirushEntries[ref.index].shortname)
table.remove(antirushEntries, ref.index)
else
local e = trickplantEntries[ref.index]
removedText = string.format("%.3f %.3f %.3f", e.x, e.y, e.z)
table.remove(trickplantEntries, ref.index)
end
local ok, path = writeProtectedFile()
if not ok then
printToClient(clientNum, "^1aa remove:^7 failed to write " .. path)
return
end
printToClient(clientNum, string.format('^3aa remove:^7 removed %s', removedText))
end
local function editSavedEntryDistance(clientNum, wantedIndex, wantedDistance)
local idx = tonumber(wantedIndex)
local distance = tonumber(wantedDistance)
if not idx then
printToClient(clientNum, "^1aa edit:^7 invalid number")
return
end
if not distance or distance <= 0 then
printToClient(clientNum, "^1aa edit:^7 invalid distance")
return
end
local combined = buildCombinedList()
if idx < 1 or idx > #combined then
printToClient(clientNum, "^1aa edit:^7 number out of range")
return
end
local ref = combined[idx]
if ref.type == "antirush" then
antirushEntries[ref.index].distance = distance
else
trickplantEntries[ref.index].distance = distance
end
local ok, path = writeProtectedFile()
if not ok then
printToClient(clientNum, "^1aa edit:^7 failed to write " .. path)
return
end
printToClient(clientNum, string.format("^3aa edit:^7 entry %d distance changed to %.0f", idx, distance))
end
local function findAntirushEntitiesNearPlayer(clientNum)
local px, py, pz = getPlayerOrigin(clientNum)
if not px then
return nil, "could not read your position"
end
local results = {}
for entNum = 0, MAX_GENTITIES - 1 do
local classname = getEntityClassname(entNum)
if classname and isAntirushClass(classname) then
local x, y, z = getEntityOrigin(entNum)
if x and y and z and isWithinBoxRange(px, py, pz, x, y, z, ANTIRUSH_SCAN_RANGE) then
results[#results + 1] = {
entnum = entNum,
shortname = sanitizeText(getEntityShortname(entNum)),
x = x,
y = y,
z = z,
distance = ANTIRUSH_SCAN_RANGE
}
end
end
end
table.sort(results, function(a, b) return a.entnum < b.entnum end)
return results, nil
end
local function listAntirushCandidates(clientNum)
local results, err = findAntirushEntitiesNearPlayer(clientNum)
if not results then
printToClient(clientNum, "^1aa antirush:^7 " .. err)
return
end
printToClient(clientNum, "^3AUTOADMIN ANTIRUSH")
if #results == 0 then
printToClient(clientNum, "^1No matching entities found.")
else
for i = 1, #results do
printToClient(clientNum,
string.format("ID: %d - NAME: %s", results[i].entnum, results[i].shortname))
end
end
printToClient(clientNum, "^3aa antirush [ID]^7 saves the selected objective.")
end
local function saveAntirushById(clientNum, wantedId)
local entnum = tonumber(wantedId)
if not entnum then
printToClient(clientNum, "^1aa antirush:^7 invalid id")
return
end
local results, err = findAntirushEntitiesNearPlayer(clientNum)
if not results then
printToClient(clientNum, "^1aa antirush:^7 " .. err)
return
end
local selected = nil
for i = 1, #results do
if results[i].entnum == entnum then
selected = results[i]
break
end
end
if not selected then
printToClient(clientNum, "^1aa antirush:^7 id not found in your nearby list")
return
end
antirushEntries[#antirushEntries + 1] = {
shortname = selected.shortname,
x = selected.x,
y = selected.y,
z = selected.z,
distance = selected.distance
}
local ok, path = writeProtectedFile()
if not ok then
printToClient(clientNum, "^1aa antirush:^7 failed to write " .. path)
return
end
printToClient(clientNum, string.format(
'^3aa antirush:^7 saved "%s" at %.3f %.3f %.3f with distance %.0f',
selected.shortname, selected.x, selected.y, selected.z, selected.distance
))
end
local function findTrickplantEntitiesNearPlayer(clientNum)
local px, py, pz = getPlayerOrigin(clientNum)
if not px then
return nil, "could not read your position"
end
local results = {}
for entNum = 0, MAX_GENTITIES - 1 do
local classname = getEntityClassname(entNum)
if isDynamiteClass(classname) then
local x, y, z = getEntityOrigin(entNum)
if x and y and z and isWithinBoxRange(px, py, pz, x, y, z, TRICKPLANT_SCAN_RANGE) then
results[#results + 1] = {
entnum = entNum,
x = x,
y = y,
z = z,
distance = TRICKPLANT_SCAN_RANGE
}
end
end
end
table.sort(results, function(a, b) return a.entnum < b.entnum end)
return results, nil
end
local function listTrickplantCandidates(clientNum)
local results, err = findTrickplantEntitiesNearPlayer(clientNum)
if not results then
printToClient(clientNum, "^1aa trickplant:^7 " .. err)
return
end
printToClient(clientNum, "^3AUTOADMIN TRICKPLANT")
if #results == 0 then
printToClient(clientNum, "^1No nearby dynamite entities found.")
else
for i = 1, #results do
printToClient(clientNum,
string.format("ID: %d - POS: %.3f %.3f %.3f", results[i].entnum, results[i].x, results[i].y, results[i].z))
end
end
printToClient(clientNum, "^3aa trickplant [ID]^7 saves the selected trickplant area.")
end
local function saveTrickplantById(clientNum, wantedId)
local entnum = tonumber(wantedId)
if not entnum then
printToClient(clientNum, "^1aa trickplant:^7 invalid id")
return
end
local results, err = findTrickplantEntitiesNearPlayer(clientNum)
if not results then
printToClient(clientNum, "^1aa trickplant:^7 " .. err)
return
end
local selected = nil
for i = 1, #results do
if results[i].entnum == entnum then
selected = results[i]
break
end
end
if not selected then
printToClient(clientNum, "^1aa trickplant:^7 id not found in your nearby list")
return
end
trickplantEntries[#trickplantEntries + 1] = {
x = selected.x,
y = selected.y,
z = selected.z,
distance = selected.distance
}
local ok, path = writeProtectedFile()
if not ok then
printToClient(clientNum, "^1aa trickplant:^7 failed to write " .. path)
return
end
printToClient(clientNum, string.format(
'^3aa trickplant:^7 saved %.3f %.3f %.3f with distance %.0f',
selected.x, selected.y, selected.z, selected.distance
))
end
local function killPlayer(clientNum)
et.G_Damage(clientNum, clientNum, 1022, 400, 24, 0)
end
local function removeClosestDynamiteFromPlayer(clientNum)
local px, py, pz = getPlayerOrigin(clientNum)
if not px then
return false
end
local bestEnt = nil
local bestDist = nil
for entNum = 0, MAX_GENTITIES - 1 do
local classname = getEntityClassname(entNum)
if isDynamiteClass(classname) then
local ex, ey, ez = getEntityOrigin(entNum)
if ex and ey and ez then
local dist = distance3d(px, py, pz, ex, ey, ez)
if not bestDist or dist < bestDist then
bestDist = dist
bestEnt = entNum
end
end
end
end
if bestEnt then
et.G_FreeEntity(bestEnt)
et.G_Print(string.format(
"%s: removed dynamite entity %d from client %d\n",
MODNAME, bestEnt, clientNum
))
return true
end
return false
end
local function findMatchingAntirushEntry(clientNum)
local px, py, pz = getPlayerOrigin(clientNum)
if not px then
return nil
end
for i = 1, #antirushEntries do
local e = antirushEntries[i]
if isWithinBoxRange(px, py, pz, e.x, e.y, e.z, e.distance) then
return e
end
end
return nil
end
local function findMatchingTrickplantEntry(clientNum)
local px, py, pz = getPlayerOrigin(clientNum)
if not px then
return nil
end
for i = 1, #trickplantEntries do
local e = trickplantEntries[i]
if isWithinBoxRange(px, py, pz, e.x, e.y, e.z, e.distance) then
return e
end
end
return nil
end
local function handleDynamitePlant(clientNum)
if #antirushEntries > 0 and isProtectionActive() then
local antirush = findMatchingAntirushEntry(clientNum)
if antirush then
chatAll(string.format(
'^3AUTOADMIN:^7 %s ^7was killed for rushing protected objective ^3%s^7.',
getPlayerName(clientNum),
antirush.shortname
))
killPlayer(clientNum)
removeClosestDynamiteFromPlayer(clientNum)
return
end
end
if #trickplantEntries > 0 then
local trickplant = findMatchingTrickplantEntry(clientNum)
if trickplant then
if removeClosestDynamiteFromPlayer(clientNum) then
chatAll(string.format(
'^3AUTOADMIN:^7 Dynamite planted by %s ^7was removed due to trickplant protection.',
getPlayerName(clientNum)
))
end
return
end
end
end
local function getObjectiveTakenSlot(text)
local slot = string.match(text, '^Item:%s*(%d+)%s+team_CTF_redflag%s*$')
if slot then
return tonumber(slot)
end
slot = string.match(text, '^Item:%s*(%d+)%s+team_CTF_blueflag%s*$')
if slot then
return tonumber(slot)
end
return nil
end
local function handleObjectiveTake(clientNum)
if #antirushEntries == 0 then
return
end
if not isProtectionActive() then
return
end
local antirush = findMatchingAntirushEntry(clientNum)
if antirush then
chatAll(string.format(
'^3AUTOADMIN:^7 %s ^7was killed for rushing protected objective ^3%s^7.',
getPlayerName(clientNum),
antirush.shortname
))
killPlayer(clientNum)
end
end
local function showHelp(clientNum)
printToClient(clientNum, "^3AUTOADMIN HELP")
printToClient(clientNum, "aa help")
printToClient(clientNum, " Shows this help text.")
printToClient(clientNum, "aa antirush")
printToClient(clientNum, " Lists nearby objective entities that can be protected against rushing.")
printToClient(clientNum, "aa antirush [ID]")
printToClient(clientNum, " Saves the selected antirush objective.")
printToClient(clientNum, "aa trickplant")
printToClient(clientNum, " Lists nearby dynamite entities that can be protected against trickplants.")
printToClient(clientNum, "aa trickplant [ID]")
printToClient(clientNum, " Saves the selected trickplant area.")
printToClient(clientNum, "aa list")
printToClient(clientNum, " Shows all saved antirush and trickplant entries.")
printToClient(clientNum, "aa remove [NUMBER]")
printToClient(clientNum, " Removes one saved entry from the combined list.")
printToClient(clientNum, "aa edit [NUMBER] [DISTANCE]")
printToClient(clientNum, " Changes the distance of one saved entry.")
end
function et_InitGame(levelTime, randomSeed, restart)
et.G_Print(string.format("%s %s loaded\n", MODNAME, VERSION))
loadAllowedGuids()
loadProtectedFile()
currentLevelTime = levelTime or 0
protectionStartLevelTime = currentLevelTime
announceDone = false
announceAtLevelTime = currentLevelTime + 5000
protectionExpiredAnnounced = false
et.G_Print(string.format(
"%s: protection starts at levelTime=%d and antirush lasts %.1f minutes\n",
MODNAME,
protectionStartLevelTime,
getProtectMinutes()
))
end
function et_RunFrame(lvltime)
currentLevelTime = lvltime or 0
if not announceDone and currentLevelTime >= announceAtLevelTime then
announceProtectedObjectives()
announceDone = true
end
if announceDone and not protectionExpiredAnnounced and not isProtectionActive() then
announceProtectionEnded()
protectionExpiredAnnounced = true
end
end
function et_Print(text)
if not text then
return
end
local plantSlot = string.match(text, DYNAMITE_PLANT_PATTERN)
if plantSlot then
handleDynamitePlant(tonumber(plantSlot))
return
end
local takeSlot = getObjectiveTakenSlot(text)
if takeSlot then
handleObjectiveTake(takeSlot)
return
end
end
function et_ClientCommand(clientNum, command)
local cmd0 = et.trap_Argv(0)
local cmd1 = et.trap_Argv(1)
local cmd2 = et.trap_Argv(2)
local cmd3 = et.trap_Argv(3)
if cmd0 ~= "aa" then
return 0
end
if not requireAuthorization(clientNum) then
return 1
end
if cmd1 == "help" or cmd1 == "" or cmd1 == nil then
showHelp(clientNum)
return 1
end
if cmd1 == "antirush" then
if cmd2 and cmd2 ~= "" then
saveAntirushById(clientNum, cmd2)
else
listAntirushCandidates(clientNum)
end
return 1
end
if cmd1 == "trickplant" then
if cmd2 and cmd2 ~= "" then
saveTrickplantById(clientNum, cmd2)
else
listTrickplantCandidates(clientNum)
end
return 1
end
if cmd1 == "list" then
listSavedEntries(clientNum)
return 1
end
if cmd1 == "remove" then
if cmd2 and cmd2 ~= "" then
removeSavedEntry(clientNum, cmd2)
else
printToClient(clientNum, "^1aa remove:^7 usage: aa remove [NUMBER]")
end
return 1
end
if cmd1 == "edit" then
if cmd2 and cmd2 ~= "" and cmd3 and cmd3 ~= "" then
editSavedEntryDistance(clientNum, cmd2, cmd3)
else
printToClient(clientNum, "^1aa edit:^7 usage: aa edit [NUMBER] [DISTANCE]")
end
return 1
end
showHelp(clientNum)
return 1
endYeah i am sometimes bored in the train.
Have a good day