- --Creator: Wizard
- --Script Name: Command Script
- --Website: http://phasorscripts.wordpress.com/
- --Xfire: th3w1zard3
- --Version: 5.13 The 'Nimbus' Release
- --Check Change Log for information on the updates
- --Thank you Elite for the awesome work you did in updating this script to the latest phasor, and the other awesome features you put in.
- --Without you I never would have updated to the newer phasor, and this script never would have been made.
- -- I FOUND A MAGICAL COMMAND THAT HELPED ME TEST THIS AMAZING SCRIPT: luac -p -l commands.lua | grep 'ETTABUP.*_ENV' (or ETGLOBAL for 5.1)
- --Do Not Modify unless you really know what you are doing
- -- Script Variables
- -- Counts
- local cur_players = 0
- local rtv_counter = 0
- local votekick_counter = 0
- -- Strings
- local script_version = "5.13 The 'Nimbus' Release"
- -- Timers
- local infammo_timer
- local lo3_timer
- local maintimer
- local rtvtimer
- local votekicktimer
- -- Script Variables
- local changelog
- local dont_call_onservercommand
- local executingPlayerId
- local Game
- local gameend
- local gametype
- local Map
- local output_environment = -1
- local Persistent
- local processid
- local profilepath
- local server_prefix
- local team_play
- local timelimit_set_value
- local votekickPlayerId
- -- Phasor doesn't automatically check limits for write functions, it just errors, so let's make our own check.
- local function writewithinlimit(address, value, writefunc, minlimit, maxlimit)
- writefunc(address, value <= minlimit and minlimit or value >= maxlimit and maxlimit or value)
- end
- local function writebyte(address, offset, value)
- if value then
- address = address + offset
- else
- value = offset
- end
- writewithinlimit(address, value, _G.writebyte, 0, 0xFF)
- end
- local function writechar(address, offset, value)
- if value then
- address = address + offset
- else
- value = offset
- end
- writewithinlimit(address, value, _G.writechar, -0x80, 0x7F)
- end
- local function writeword(address, offset, value)
- if value then
- address = address + offset
- else
- value = offset
- end
- writewithinlimit(address, value, _G.writeword, 0, 0xFFFF)
- end
- local function writeshort(address, offset, value)
- if value then
- address = address + offset
- else
- value = offset
- end
- writewithinlimit(address, value, _G.writeshort, -0x8000, 0x7FFF)
- end
- local function writedword(address, offset, value)
- if value then
- address = address + offset
- else
- value = offset
- end
- writewithinlimit(address, value, _G.writedword, 0, 0xFFFFFFFF)
- end
- local function writeint(address, offset, value)
- if value then
- address = address + offset
- else
- value = offset
- end
- writewithinlimit(address, value, _G.writeint, -0x80000000, 0x7FFFFFFF)
- end
- -- Phasor's read/writestring in previous versions are broken.
- local function readstring(address, length)
- address = type(address) == "number" and address or error "bad argument #1 to 'readstring' expected number, got '" .. type(address) .. "'"
- if length then
- length = type(length) == "number" and length or error "bad argument #2 to 'readstring' expected number, got '" .. type(length) .. "'"
- else
- length = length or 256
- end
- local char_table = {}
- local char = string.char
- local word, dword, byte1, byte2, byte3, byte4
- local i = 0
- while i < length do
- -- quickens write calls (screw you oxide for using virtualprotect)
- if (length-i) >= 4 then
- dword = readdword(address + i)
- byte1 = bit32.band(dword, 0xFF)
- if byte1 == 255 or byte1 == 0 then break end
- char_table[#char_table+1] = char(byte1)
- byte2 = bit32.band(bit32.rshift(dword, 8), 0xFF)
- if byte2 == 255 or byte2 == 0 then break end
- char_table[#char_table+1] = char(byte2)
- byte3 = bit32.band(bit32.rshift(dword, 16), 0xFF)
- if byte3 == 255 or byte3 == 0 then break end
- char_table[#char_table+1] = char(byte3)
- byte4 = bit32.band(bit32.rshift(dword, 24), 0xFF)
- if byte4 == 255 or byte4 == 0 then break end
- char_table[#char_table+1] = char(byte4)
- i = i + 4
- elseif (length-i) >= 2 then
- word = readword(address + i)
- byte1 = bit32.band(word, 0xFF)
- if byte1 == 255 or byte1 == 0 then break end
- char_table[#char_table+1] = char(byte1)
- byte2 = bit32.band(bit32.rshift(word, 8), 0xFF)
- if byte2 == 255 or byte2 == 0 then break end
- char_table[#char_table+1] = char(byte2)
- i = i + 2
- else
- byte1 = readbyte(address + i)
- if byte1 == 0 or byte1 == 255 then break end
- char_table[#char_table+1] = char(byte1)
- i = i + 1
- end
- end
- return table.concat(char_table)
- end
- function readwidestring(address, length)
- address = type(address) == "number" and address or error "bad argument #1 to 'readwidestring' expected number, got '" .. type(address) .. "'"
- if length then
- length = type(length) == "number" and length or error "bad argument #2 to 'readwidestring' expected number, got '" .. type(length) .. "'"
- else
- length = length or 51001
- end
- local char_table = {}
- local char = string.char
- local word, dword, byte1, byte2, byte3, byte4
- local i = 0
- while i < length do
- -- quickens write calls (screw you oxide for using virtualprotect)
- if (length-i) >= 4 then
- dword = readdword(address + i)
- byte1 = bit32.band(dword, 0xFF)
- if byte1 == 255 or byte1 == 0 then break end
- char_table[#char_table+1] = char(byte1)
- byte2 = bit32.band(bit32.rshift(dword, 8), 0xFF)
- if byte2 ~= 255 or byte2 ~= 0 then break end
- byte3 = bit32.band(bit32.rshift(dword, 16), 0xFF)
- if byte3 == 255 or byte3 == 0 then break end
- char_table[#char_table+1] = char(byte3)
- byte4 = bit32.band(bit32.rshift(dword, 24), 0xFF)
- if byte4 ~= 255 or byte4 ~= 0 then break end
- i = i + 4
- else
- word = readword(address + i)
- byte1 = bit32.band(word, 0xFF)
- if byte1 == 255 or byte1 == 0 then break end
- char_table[#char_table+1] = char(byte1)
- byte2 = bit32.band(bit32.rshift(word, 8), 0xFF)
- if byte2 ~= 255 or byte2 ~= 0 then break end
- i = i + 2
- end
- end
- return table.concat(char_table)
- end
- local function writestring(address, offset, str)
- address = type(address) == "number" and address or error "bad argument #1 to 'writestring' expected number, got '" .. type(address) .. "'"
- if str then
- offset = type(offset) == "number" and offset or error "bad argument #2 to 'writestring' expected number, got '" .. type(offset) .. "'"
- str = type(str) == "string" and str or error "bad argument #3 to 'writestring' expected string, got '" .. type(str) .. "'"
- else
- str = type(offset) == "string" and offset or error "bad argument #2 to 'writestring' expected string, got '" .. type(offset) .. "'"
- offset = nil
- end
- address = address + (offset or 0x0)
- local byte_table = {}
- local byte = string.byte
- for char in string.gmatch(str, '.') do
- byte_table[#byte_table+1] = byte(char)
- end
- local length = #byte_table
- local i = 0
- while i < length do
- -- quickens write calls (screw you oxide for using virtualprotect)
- if (length-i) >= 4 then
- writedword(address + i, tonumber(string.format("%02X%02X%02X%02X", byte_table[i+4], byte_table[i+3], byte_table[i+2], byte_table[i+1]), 16))
- i = i + 4
- elseif (length-i) >= 2 then
- writeword(address + i, tonumber(string.format("%02X%02X", byte_table[i+2], byte_table[i+1]), 16))
- i = i + 2
- else
- writebyte(address + i, byte_table[i+1])
- i = i + 1
- end
- end
- end
- local function writewidestring(address, offset, str)
- address = type(address) == "number" and address or error "bad argument #1 to 'writewidestring' expected number, got '" .. type(address) .. "'"
- if str then
- offset = type(offset) == "number" and offset or error "bad argument #2 to 'writewidestring' expected number, got '" .. type(offset) .. "'"
- str = type(str) == "string" and str or error "bad argument #3 to 'writewidestring' expected string, got '" .. type(str) .. "'"
- else
- str = type(offset) == "string" and offset or error "bad argument #2 to 'writewidestring' expected string, got '" .. type(offset) .. "'"
- offset = nil
- end
- address = address + (offset or 0x0)
- local byte_table = {}
- local byte = string.byte
- for char in string.gmatch(str, '.') do
- byte_table[#byte_table+1] = byte(char)
- end
- local length = #byte_table
- while i < length do
- -- quickens write calls (screw you oxide for using virtualprotect)
- if i % 4 == 0 and length - i >= 4 then
- writedword(address + i, tonumber((byte_table[i+2]*100) .. (byte_table[i+1]*100)))
- i = i + 2
- else
- writeword(address + i, byte_table[i+1])
- i = i + 1
- end
- end
- end
- -- Local variables defined for decreased execution time (and also to organize what is using the global environment)
- local io, tostring, tonumber, next, type, os, select = io, tostring, tonumber, next, type, os, select
- local sub, gsub, find, lower, format, match = string.sub, string.gsub, string.find, string.lower, string.format, string.match
- local insert, remove, concat = table.insert, table.remove, table.concat
- local ceil, floor = math.ceil, math.floor
- -- Table Management
- local TM = setmetatable({
- unused_tables = {},
- __gc = function(self) self.unused_tables[#self.unused_tables+1] = self end,
- __tostring = function(t)
- local tableStr = "table { "
- if next(t) then
- for k,v in next,t do
- if v == t then goto nextVal end
- k = type(k) == "string" and '"' .. k .. '"' or k
- v = type(v) == "string" and '"' .. v .. '"' or tostring(v)
- tableStr = tableStr .. (k .. " => ") .. v .. ", "
- ::nextVal::
- end
- tableStr = sub(tableStr, 1, #tableStr-2) .. " }"
- else
- tableStr = tableStr .. " }"
- end
- return tableStr
- end,
- deleteEntries = function(t)
- for key,_ in next,t do
- t[key] = nil
- end
- return t
- end
- },
- {
- __call = function(TM, t)
- local mt = getmetatable(t)
- if mt then
- mt.__index = TM
- return t
- else
- return setmetatable(t, TM)
- end
- end
- }
- )
- TM.__index = TM
- local function getobject(objId)
- return objId and _G.getobject(objId)
- end
- -- Tables
- local access_table = {}
- local addresses
- local admin_table = {}
- local ban_table = {}
- local ban_penalty = {}
- local bos_table = {}
- local Commands = TM{commandAliases = TM{}}
- Commands.__index = Commands -- class setup
- local commandAliases = Commands.commandAliases
- local cmdreply = setmetatable({index = 0}, {
- __mode = "v", -- weak table
- __len = function(self) return (rawget(self, "index") or 0) end,
- __call = function(self, bResetAll)
- if not bResetAll then
- local index = rawget(self, "index") + 1
- rawset(self, "index", index)
- return index
- end
- rawset(self, "header", nil)
- rawset(self, "align", nil)
- rawset(self, "delim", nil)
- rawset(self, "separator", nil)
- rawset(self, "index", 0)
- end
- })
- -- Default Scripted Game Variables
- local defaults = {
- kickbans_file = "KicksAndBans",
- commands_file = "commands",
- admin_file = "admins",
- banlist_file = "banned",
- sharedhash_file = "sharedhashes",
- ban_penalty = "5m 1d 10d",
- --tkban_type = "ip",
- adminblocker = 0,
- anticaps = false,
- antispam = "players",
- chatcommands = true,
- chatids = true,
- crouch_camo = false,
- deathless = false,
- falldamage = true,
- firstjoin_message = true,
- hash_duplicates = true,
- infinite_ammo = false,
- killing_spree = true,
- multiteam_vehicles = false,
- noweapons = false,
- pm_enabled = true,
- respawn_time = false,
- rtv_enabled = true,
- rtv_required = 50,
- rtv_timeout = 120,
- sa_message = true,
- scrim_mode = false,
- spam_max = 7,
- spam_timeout = 60,
- tbag_detection = true,
- uniques_enabled = true,
- votekick_enabled = true,
- votekick_action = "kick",
- votekick_required = 70,
- votekick_timeout = 120,
- wb_message = true
- }
- local ip_table = setmetatable(TM{}, TM{
- __call = function(ip_table, ip, bScriptReloadNeedMuteCheck)
- local iptable = TM.New()
- iptable.disarmed = false
- iptable.tempadmin = false
- iptable.spamcounter = 0
- iptable.rcon_fails = 0
- iptable.rconfail_timer = 0
- if bScriptReloadNeedMuteCheck then
- local ban_entry
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.time ~= "Unbanned" and ban_entry.type == "chat" and netMatch(ban_entry.ip, ip) then
- iptable.muted = true
- break
- end
- end
- else
- iptable.muted = false
- end
- ip_table[ip] = iptable
- return iptable
- end
- })
- local leave_table = TM{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}
- local locations = TM{} -- map = {locname = {x, y, z}}
- local spawnWeapons = TM{}
- local tag_table = TM{}
- local objects = TM{}
- local player_table = setmetatable(TM{[0] = TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}, TM{drones = TM{}, weapons = TM{}}},
- TM{
- __call = function(player_table, playerId)
- local ptable = player_table[playerId]
- ptable.hash = gethash(playerId)
- ptable.ip = getip(playerId)
- ptable.admin_entry = admin_table[ptable.hash]
- for index,thisAdmin in next,admin_table do
- if thisAdmin.type == "ip" and netMatch(index, ptable.ip) and (ptable.admin_entry and ptable.admin_entry.level > thisAdmin.level or not ptable.admin_entry) then
- ptable.admin_entry = thisAdmin
- break
- end
- end
- ptable.afk = false
- ptable.bulletmode = false
- ptable.colorspawn = false
- ptable.crouch = false
- ptable.drones = ptable.drones and ptable.drones:deleteEntries() or TM.New()
- ptable.dmgmultiplier = 1
- ptable.name = getname(playerId)
- ptable.godmode = false
- ptable.ghostmode = false
- ptable.invisible = false
- ptable.hidden = false
- ptable.objspawnid = false
- ptable.player_struct = getplayer(playerId)
- ptable.objectId = getplayerobjectid(playerId)
- ptable.object_struct = getobject(ptable.objectId)
- ptable.vehicleObjId = ptable.object_struct and readdword(ptable.object_struct + 0x11C) or 0xFFFFFFFF
- ptable.m_vehicleObj = getobject(ptable.vehicleObjId)
- ptable.playerIndex = resolveplayer(playerId)
- ptable.tbagname = ""
- ptable.x,ptable.y,ptable.z = 0,0,0
- return ptable
- end
- })
- local randomNames = TM{"Butcher", "Caboose", "Crazy", "Cupid", "Darling", "Dasher", "Disco", "Donut", "Dopey", "Ghost", "Goat", "Grumpy", "Hambone", "Hollywood", "Howard", "Jack", "Killer", "King", "Mopey", "Noodle", "Penguin", "Pirate", "Prancer", "Saucy", "Shadow", "Sleepy", "Snake", "Sneak", "Stompy", "Stumpy", "The Bear", "The Big L", "Tooth", "Walla Walla", "Weasel", "Wheezy", "Whicker", "Whisp", "Wilshire"}
- local rcon_passwords = TM{}
- local sharedhashes = TM{
- "f443106bd82fd6f3c22ba2df7c5e4094",
- "c702226e783ea7e091c0bb44c2d0ec64",
- "d72b3f33bfb7266a8d0f13b37c62fddb",
- "55d368354b5021e7dd5d3d1525a4ab82",
- "3d5cd27b3fa487b040043273fa00f51b",
- "b661a51d4ccf44f5da2869b0055563cb",
- "740da6bafb23c2fbdc5140b5d320edb1",
- "10440b462f6cbc3160c6280c2734f184",
- "7503dad2a08026fc4b6cfb32a940cfe0",
- "4486253cba68da6786359e7ff2c7b467",
- "f1d7c0018e1648d7d48f257dc35e9660",
- "40da66d41e9c79172a84eef745739521",
- "2863ab7e0e7371f9a6b3f0440c06c560",
- "34146dc35d583f2b34693a83469fac2a",
- "b315d022891afedf2e6bc7e5aaf2d357",
- "81f9c914b3402c2702a12dc1405247ee",
- "63bf3d5a51b292cd0702135f6f566bd1",
- "6891d0a75336a75f9d03bb5e51a53095",
- "325a53c37324e4adb484d7a9c6741314",
- "0e3c41078d06f7f502e4bb5bd886772a",
- "fc65cda372eeb75fc1a2e7d19e91a86f",
- "f35309a653ae6243dab90c203fa50000",
- "50bbef5ebf4e0393016d129a545bd09d",
- "a77ee0be91bd38a0635b65991bc4b686",
- "3126fab3615a94119d5fe9eead1e88c1",
- "d41d8cd98f00b204e9800998ecf8427e"
- }
- local unique_table = TM(setmetatable({total = 0}, TM{__len = function(self) return self.total end}))
- local valid_maps = TM{}
- local valid_gametypes = TM{}
- -- Get Unused Table if available.
- function TM.New()
- local unused_tables = TM.unused_tables
- local length = #unused_tables
- local t = unused_tables[length]
- if t then
- -- use an unused table
- unused_tables[length] = nil
- t:deleteEntries()
- else
- -- no tables available, make a new one
- t = setmetatable({}, TM)
- end
- return t
- end
- -- Memoize Code.
- local globalCache = TM.New()
- local function getCallMetamethod(f)
- if type(f) ~= 'table' then return nil end
- local mt = getmetatable(f)
- return type(mt)=='table' and mt.__call
- end
- local function resetCache(f, call)
- globalCache[f] = TM{ results = TM.New(), children = TM.New(), call = call or getCallMetamethod(f) }
- end
- local function getCacheNode(cache, args)
- local node = cache
- local arg
- for i = 1,#args do arg = args[i]
- node = node.children[--[[type(arg) == "table" and concat(arg, "", 1, #arg) or--]] arg]
- if not node then return nil end
- end
- return node
- end
- local function getOrBuildCacheNode(cache, args)
- local node = cache
- local arg
- for i = 1,#args do arg = args[i]
- --arg = type(arg) == "table" and concat(arg, "", 1, #arg) or arg
- node.children[arg] = node.children[arg] or TM{ children = TM.New() }
- node = node.children[arg]
- end
- return node
- end
- local function getFromCache(cache, args)
- local node = getCacheNode(cache, args)
- return node and node.results or TM.New()
- end
- local function insertInCache(cache, args, results)
- local node = getOrBuildCacheNode(cache, args)
- node.results = results
- end
- local function resetCacheIfMetamethodChanged(t)
- local call = getCallMetamethod(t)
- assert(type(call) == "function", "The __call metamethod must be a function")
- if globalCache[t].call ~= call then
- resetCache(t, call)
- end
- end
- local function buildMemoizedFunction(f)
- local tf = type(f)
- return function (...)
- if tf == "table" then resetCacheIfMetamethodChanged(f) end
- local results = getFromCache( globalCache[f], TM{...} )
- if #results == 0 then
- results = TM{ f(...) }
- insertInCache(globalCache[f], TM{...}, results)
- end
- return table.unpack(results)
- end
- end
- local function isCallable(f)
- local tf = type(f)
- if tf == 'function' then return true end
- if tf == 'table' then
- return type(getCallMetamethod(f))=="function"
- end
- return false
- end
- local function assertCallable(f)
- assert(isCallable(f), "Only functions and callable tables are admitted on memoize. Received " .. tostring(f))
- end
- local function memoize(f)
- assertCallable(f)
- resetCache(f)
- return buildMemoizedFunction(f)
- end
- -- fixes a phasor bug where player 1 gets output from hprintf in their console...
- local function privatesay(message, playerId)
- _G.privatesay(message, playerId)
- if getplayer(0) then
- sendconsoletext(0, " \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ")
- end
- end
- local function getname(playerId)
- return playerId and player_table[playerId].name or "the Server"
- end
- local function gethash(playerId)
- return playerId and player_table[playerId].hash or nil
- end
- local function getip(playerId)
- return playerId and player_table[playerId].ip or nil
- end
- local function getplayer(playerId)
- return playerId and player_table[playerId].player_struct or nil
- end
- local function GetGameAddresses(game)
- if game == "PC" then
- addresses = {
- stats_header = 0x639720,
- stats_globals = 0x639898,
- ctf_globals = 0x639B98,
- slayer_globals = 0x63A0E8,
- oddball_globals = 0x639E58,
- koth_globals = 0x639BD0,
- race_globals = 0x639FA0,
- race_locs = 0x670F40,
- map_pointer = 0x63525C,
- gametype_base = 0x671340,
- network_struct = 0x745BA0,
- camera_base = 0x69C2F8,
- player_header_pointer = 0x75ECE4,
- obj_header_pointer = 0x744C18,
- collideable_objects_pointer = 0x744C34,
- map_header_base = 0x630E74,
- banlist_header = 0x641280,
- game_globals = "???", -- (???) Why do I not have this for PC?
- gameinfo_header = 0x671420,
- mapcycle_header = 0x614B4C,
- network_server_globals = 0x69B934,
- sockaddr_pointer = 0x6A1F08,
- flags_pointer = 0x6A590C,
- hash_table_base = 0x6A2AE4,
- -- String/Data Addresses.
- init_file_address = 0x8EB38,
- broadcast_version_address = 0x5DF840,
- version_info_address = 0x5E02C0,
- broadcast_game_address = 0x5E4768,
- public_value_address = 0x6164C0,
- server_port_address = 0x625230,
- timelimit_address = 0x626630,
- server_path_address = 0x62C390,
- computer_name_address = 0x62CD60,
- profile_path_address = 0x635610,
- map_name_address = 0x63BC78,
- computer_specs_address = 0x662D04,
- map_name_address2 = 0x698F21,
- server_password_address = 0x69B93C,
- banlist_path_address = 0x69B950,
- rcon_password_address = 0x69BA5C,
- --Patches
- special_chars_patch = 0x517D6B,
- gametype_patch = 0x481F3C,
- color_patch = 0x4828FE,
- devmode_patch1 = 0x4A4DBF,
- devmode_patch2 = 0x4A4E7F,
- hash_duplicate_patch = 0x59C516,
- gametype_patch = 0x481F3C, -- I 'thought' this worked but haven't tested in ages.
- hashcheck_patch = 0x59c280,
- servername_patch = 0x517D6B,
- versioncheck_patch = 0x5152E7
- }
- elseif game == "CE" then
- addresses = {
- -- Structs/headers.
- stats_header = 0x5BD740,
- stats_globals = 0x5BD8B8,
- ctf_globals = 0x5BDBB8,
- slayer_globals = 0x5BE108,
- oddball_globals = 0x5BDE78,
- koth_globals = 0x5BDBF0,
- race_globals = 0x5BDFC0,
- race_locs = 0x5F5098,
- map_pointer = 0x5B927C,
- gametype_base = 0x5F5498,
- network_struct = 0x6C7980,
- camera_base = 0x62075C,
- player_globals = 0x6E1478, -- From OS.
- player_header_pointer = 0x6E1480,
- obj_header_pointer = 0x6C69F0,
- collideable_objects_pointer = 0x6C6A14,
- map_header_base = 0x6E2CA4,
- banlist_header = 0x5C52A0,
- game_globals = 0x61CFE0, -- (???)
- gameinfo_header = 0x5F55BC,
- mapcycle_header = 0x598A8C,
- network_server_globals = 0x61FB64,
- sockaddr_pointer = 0x626388,
- hash_table_base = 0x5AFB34,
- -- String/Data Addresses.
- init_file_address = 0x8EB26,
- broadcast_version_address = 0x564B34,
- version_info_address = 0x565104,
- broadcast_game_address = 0x569EAC,
- public_value_address = 0x59A424,
- server_port_address = 0x5A91A0,
- timelimit_address = 0x5AA5B0,
- server_path_address = 0x5B0670,
- computer_name_address = 0x5B0D40,
- profile_path_address = 0x5B9630,
- map_name_address = 0x5BFC98,
- computer_specs_address = 0x5E6E5C,
- map_name_address2 = 0x61D151,
- server_password_address = 0x61FB6C,
- banlist_path_address = 0x61FB80,
- rcon_password_address = 0x61FC8C,
- --Patches
- special_chars_patch = 0x4CE0CD,
- gametype_patch = 0x45E50C,
- color_patch = 0x45EB5E,
- devmode_patch1 = 0x47DF0C,
- devmode_patch2 = 0x47DFBC,
- hash_duplicate_patch = 0x5302E6,
- hashcheck_patch = 0x530130,
- servername_patch = 0x4CE0CD,
- versioncheck_patch = 0x4CB587,
- }
- end
- end
- -- This is my ingenius way to execute a command and bypass ALL of my code.
- -- So I can do sv_kick without having to worry about creating an infinite loop.
- local function halo_svcmd(command, retBool)
- dont_call_onservercommand = true
- --print "BEFORE HALO_SVCMD"
- local response = svcmd(command, retBool)
- --print "AFTER HALO_SVCMD"
- dont_call_onservercommand = false
- return retBool and response
- end
- local function halo_svcmdplayer(command, playerId, retBool)
- dont_call_onservercommand = true
- --print "BEFORE HALO_SVCMDPLAYER"
- local response = svcmdplayer(command, playerId, retBool)
- --print "AFTER HALO_SVCMDPLAYER"
- dont_call_onservercommand = false
- return retBool and response
- end
- local function svcmd(command, retBool)
- --print "BEFORE SVCMD"
- if OnServerCommandAttempt(nil, command) ~= false then
- --print "AFTER SVCMD"
- return _G.svcmd(command, retBool)
- end
- end
- local function svcmdplayer(command, playerId, retBool)
- --print "BEFORE SVCMDPLAYER"
- if OnServerCommandAttempt(playerId, command) ~= false and OnServerCommand(playerId, command) ~= false then
- --print "AFTER SVCMDPLAYER"
- return halo_svcmd(command, retBool)
- end
- end
- math.randomseed(ceil(os.clock()) + os.time())
- local getsuckyrand = math.random
- getsuckyrand(1, 10) getsuckyrand(1, 10) getsuckyrand(1, 10)
- --Low and High are INCLUSIVE.
- local function rand(low, high)
- low = tonumber(low) or error("Bad argument #1 to 'rand' (number expected, got " .. type(low) .. ")")
- high = tonumber(high) or error("Bad argument #2 to 'rand' (number expected, got " .. type(high) .. ")")
- return getsuckyrand(low, high)
- end
- local getrandomnumber = math.rand
- local function setspeed(playerId, speed)
- local m_player = getplayer(playerId) or error("bad argument #1 to 'setspeed' expected valid playerId, got '" .. type(playerId) .. "'")
- speed = tonumber(speed) or error("bad argument #2 to 'setspeed' expected number, got '" .. type(speed) .. "'")
- writefloat(getplayer(playerId) + 0x6C, speed and speed < 999999999999999999999999999999 and speed or 999999999999999999999999999999)
- end
- -- This local function gets the playerId's memory ID from their object struct
- -- Accepts the object ID of the playerId as an argument
- -- Returns the playerId, or nil.
- local function objectidtoplayer(objectId)
- local m_object = getobject(objectId)
- if m_object then
- local playerId = readword(m_object + 0xC0)
- local m_player = _G.getplayer(playerId)
- if m_player then
- return playerId
- end
- end
- end
- objectidtoplayer = memoize(objectidtoplayer) -- memoized
- -- I am having weird issues with resolveplayer not working correctly, so I'm overriding it.
- local function resolveplayer(playerId)
- return playerId and player_table[playerId].playerIndex
- end
- -- This function will get the XYZ coordinates of an object, and return them as 3 separate variables.
- -- It will also determine if the object has a parent (i.e player in a vehicle) and return those coords instead.
- -- I don't trust Phasor's getobjectcoords, and this way I know exactly how it will work.
- function getobjectcoords(objectId)
- local m_object = getobject(objectId)
- local vehicleObjId = readdword(m_object + 0x11C)
- local m_vehicleObj = getobject(vehicleObjId)
- -- Replace m_object with vehicle object struct (if there is one)
- m_object = m_vehicleObj or m_object
- return readfloat(m_object + 0x5C),readfloat(m_object + 0x60),readfloat(m_object + 0x64)
- end
- local function getplayerobjectid(playerId)
- return playerId and player_table[playerId].objectId or 0xFFFFFFFF
- end
- local function getplayerobject(playerId)
- local ptable = playerId and player_table[playerId]
- return (ptable and ptable.object_struct or nil), (ptable and ptable.objectId or 0xFFFFFFFF)
- end
- -- Gets the object ID of the player's vehicle.
- -- Accepts argument 'playerId' (memory ID), object_struct
- -- Returns the vehicle's object ID, or nil
- local function getplayervehicleid(playerId)
- return playerId and player_table[playerId].vehicleObjId or 0xFFFFFFFF
- end
- -- This is the same as getplayervehicleid except it returns BOTH the vehicle's object struct and vehicleObjId.
- -- Returns the vehicle's object struct and vehicle's object ID, or nil.
- local function getplayervehicle(playerId)
- local ptable = playerId and player_table[playerId]
- return (ptable and ptable.m_vehicleObj or nil), (ptable and ptable.vehicleObjId or 0xFFFFFFFF)
- end
- -- Gets the object ID of the player's weapon.
- -- Accepts arguments 'playerId' (memory ID) and 'slot' (weapon slot) which is a number from 0 to 3.
- -- and object_struct, object_id, and player_struct (for efficiency)
- -- Slot is an optional argument. If not passed, then getplayerweaponid returns player's current weapon ID.
- -- Returns the weapon's object ID, or 0xFFFFFFFF if no weapon, or nil if the player is dead
- local function getplayerweaponid(playerId, slot)
- m_playerObj = m_playerObj or getplayerobject(playerId, slot)
- if not m_playerObj then
- return
- end
- -- Return vehicle's weapon if they are in a vehicle.
- local m_vehicleObj = getplayervehicle(playerId)
- if m_vehicleObj then
- return readdword(m_vehicleObj + 0x2F8)
- end
- -- Return current weapon if no slot passed.
- if not slot then
- return readdword(m_playerObj + 0x118)
- end
- -- Return weapon at the specified slot.
- return readdword(m_playerObj + 0x2F8 + slot*4)
- end
- -- This is the same as getplayerweaponid except it returns BOTH the weapon's object struct and weaponObjId.
- -- Returns the weapon's object struct and weapon's object ID, or nil.
- local function getplayerweapon(playerId, slot)
- local weaponObjId = getplayerweaponid(playerId, slot)
- return getobject(weaponObjId), weaponObjId
- end
- local function cleanupdrones(playerId)
- local ptable = player_table[playerId]
- local vehicleObjId
- for i = 1,#ptable.drones do vehicleObjId = ptable.drones[i]
- if getobject(vehicleObjId) then
- destroyobject(vehicleObjId)
- end
- ptable.drones[i] = nil
- end
- end
- --[[ General lua functions ]]--
- local function round(val, place)
- place = place or 0 return floor(val * (10 ^ place) + 0.5) * (10 ^ -place)
- end
- local function formatTime(time)
- time = tonumber(time)
- if time == -1 then
- return "--"
- elseif time then
- local temp = time
- local centuries = floor(temp / 3153600000)
- temp = temp - centuries * 3153600000
- local years = floor(temp / 31536000)
- temp = temp - years * 31536000
- local weeks = floor(temp / 604800)
- temp = temp - weeks * 604800
- local days = floor(temp / 86400)
- temp = temp - days * 86400
- local hours = floor(temp / 3600)
- temp = temp - hours * 3600
- local minutes = floor(temp / 60)
- temp = temp - minutes * 60
- local seconds = floor(temp)
- return format("%02d:%02d:%02d:%02d:%02d:%02d", years, weeks, days, hours, minutes, seconds)
- else
- return time
- end
- end
- formatTime = memoize(formatTime) -- memoized
- local function wordtotime(timeStr, bancount)
- local length = #timeStr
- local time
- -- Check if timeStr is in the correct format before we do anything.
- if tonumber(sub(timeStr, 1, length-1)) and match(sub(timeStr, length, length), "[cywdhms]") then
- time = 0
- local num = ""
- local holder, tempnum, char
- for i = 1,length do
- char = sub(timeStr, i, i)
- if tonumber(char) then
- num = num .. char
- else
- tempnum = tonumber(num)
- holder = 0
- holder = char == "s" and tempnum
- holder = char == "m" and tempnum * 60 or holder
- holder = char == "h" and tempnum * 3600 or holder
- holder = char == "d" and tempnum * 86400 or holder
- holder = char == "w" and tempnum * 604800 or holder
- holder = char == "y" and tempnum * 31536000 or holder
- holder = char == "c" and tempnum * 3153600000 or holder
- holder = holder or 1
- time = time + holder
- end
- end
- if time > 0 then
- return time, char
- end
- end
- time = tonumber(timeStr)
- if time == 0 and bancount then
- return ban_penalty[bancount], "?"
- elseif time then
- return time, "*"
- end
- end
- wordtotime = memoize(wordtotime) -- memoized
- local function timetoword(time)
- time = type(time) == "number" and time or tonumber(time)
- if time then
- local returntime = ""
- local centuries = floor(time / 3153600000)
- time = time - centuries * 3153600000
- local years = floor(time / 31536000)
- time = time - years * 31536000
- local weeks = floor(time / 604800)
- time = time - weeks * 604800
- local days = floor(time / 86400)
- time = time - days * 86400
- local hours = floor(time / 3600)
- time = time - hours * 3600
- local minutes = floor(time / 60)
- time = time - minutes * 60
- local seconds = floor(time)
- returntime = seconds > 0 and (seconds == 1 and "1 second" or seconds .. " seconds") or returntime
- returntime = minutes > 0 and (minutes == 1 and "1 minute" or minutes .. " minutes " .. returntime) or returntime
- returntime = hours > 0 and (hours == 1 and "1 hour" or hours .. " hours " .. returntime) or returntime
- returntime = days > 0 and (days == 1 and "1 day" or days .. " days " .. returntime) or returntime
- returntime = weeks > 0 and (weeks == 1 and "1 week" or weeks .. " weeks " .. returntime) or returntime
- returntime = years > 0 and (years == 1 and "1 year" or years .. " years " .. returntime) or returntime
- returntime = centuries > 0 and (centuries == 1 and "1 century" or centuries .. " centuries " .. returntime) or returntime
- return returntime or "0 seconds"
- end
- end
- timetoword = memoize(timetoword) -- memoized
- local function getTimeAndReason(timeandreason, bancount)
- local words = tokenizecmdstring(timeandreason)
- local count = #words
- local time
- local reasons = TM.New()
- local timetypes_used = ""
- local word, addTime, timetype, reasons_started
- for i = 1,count do word = words[i]
- if not reasons_started then
- addTime, timetype = wordtotime(word)
- if timetype and (find(timetypes_used, timetype) or find(timetypes_used, "[%?%*]")) then
- return "You can only use 1 of each time type (cywdhms)\nIf you specified a number, you cannot specify multiple time arguments.\nCheck the guide for more information"
- elseif addTime then
- time = (time or 0) + addTime
- if not find(timetypes_used, timetype) then
- timetypes_used = timetypes_used .. timetype
- end
- else
- reasons_started = true
- reasons[#reasons+1] = word
- end
- else
- reasons[#reasons+1] = word
- end
- end
- return (time or -1), (reasons[2] and concat(reasons, " ") or reasons[1] or "None Given")
- end
- getTimeAndReason = memoize(getTimeAndReason) -- memoized
- local function gettag(type_or_id, tagname)
- if tagname then
- return tag_table[type_or_id] and tag_table[type_or_id][tagname] or nil
- elseif tag_table[type_or_id] then
- return tag_table[type_or_id].tag_class, tag_table[type_or_id].tag_name
- end
- end
- local function getObjType(objectId)
- local m_object = getobject(objectId)
- return m_object and readword(m_object + 0xB4) or nil
- end
- getObjType = memoize(getObjType) -- memoized
- local function resetweapons(playerId)
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if getplayerweapon(playerId) then return end
- local x,y,z = getobjectcoords(playerObjId)
- assignweapon(playerId, createobject(gettag("weap", "weapons\\pistol\\pistol"), 0, 60, false, x+1.0, y, z + 2.0))
- assignweapon(playerId, createobject(gettag("weap", "weapons\\assault rifle\\assault rifle"), 0, 60, false, x+1.0, y, z + 2.0))
- end
- local function ResetPlayer(playerId)
- local ptable = player_table[playerId]
- local iptable = ip_table[getip(playerId)]
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if playerObjId ~= 0xFFFFFFFF then
- ptable.godmode = false
- cleanupdrones(playerId)
- resetweapons(playerId)
- end
- ptable.bulletmode = false
- iptable.disarmed = false
- ptable.dmgmultiplier = 1
- ptable.ghostmode = false
- ptable.hidden = false
- ptable.objspawnid = false
- --ptable.rcon_fails = 0 -- shouldn't reset this.. lol
- iptable.suspended = false
- end
- local function validate_ipv4(ip)
- if not ip then return nil end
- ip = gsub(gsub(ip, "[%s]*", ""), "x+", "*")
- local a,b,c,slash,d,finish = match(ip, "^([^%.]+)%.([^%.]*)%.?([^%./]*)%.?(/?)([^%.]*)()")
- a = a == "" and "*" or match(a or "", "[%d%*]+")
- b = b == "" and "*" or match(b or "", "[%d%*]+")
- c = c == "" and "*" or match(c or "", "[%d%*]+")
- slash = slash ~= ""
- d = d or ""
- --print("IP VALIDATION I:",a,b,c,d,slash,finish)
- if slash then
- if d:find("/") or not match(d, "[%d%*]+") then return false end -- can't have two slashes
- d = "0/"..d -- Alternate form 194.1.4/24
- else
- d = d == "" and "*" or match(d, "[%d%*/]+")
- end
- if not a or not b or not c then
- return false -- bad ip
- end
- local found,a2,b2,c2,d2 = match(ip, "(%-)(%d+)%.(%d*)%.?(%d*)%.?(%d*)%c*$", finish)
- --print("IP VALIDATION II:",found,a2,b2,c2,d2)
- if not found then
- if a2 and a ~= "" then return false end -- this should just never happen lol
- return format("%s.%s.%s.%s",a,b,c,d)
- elseif slash then
- return false -- can't have a slash, and a iplimit.. lol
- end
- a2 = a2 == "" and "*" or match(a2, "[%d%*]+")
- b2 = b2 == "" and "*" or match(b2, "[%d%*]+")
- c2 = c2 == "" and "*" or match(c2, "[%d%*]+")
- d2 = d2 == "" and "*" or match(d2, "[%d%*]+")
- if not a2 or not b2 or not c2 then
- return false -- bad ip
- end
- if c2:find("/") and d2:find("/") then return false end
- return format("%s.%s.%s.%s-%s.%s.%s.%s", a,b,c,d,a2,b2,c2,d2)
- end
- validate_ipv4 = memoize(validate_ipv4) -- memoized
- local function check_ip(ip)
- local i = 1
- local octets = 1
- local octet = ""
- local err = ""
- local errors = 0
- local blocks = TM.New()
- local c, block
- while (i <= #ip + 1) do
- c = sub(ip, i, i)
- if c == "." or #ip+1 == i then
- octets = octets + 1
- block = tonumber(octet)
- if not block or block > 255 or block < 0 or octets > 5 then
- errors = errors + 1
- err = err .. " \f3>" .. (block or "?") .. "<\f8"
- else
- blocks[#blocks + 1] = octet
- err = err .. "\f0 " .. block .. "\f8"
- end
- octet = ""
- else
- octet = octet .. c
- end
- i = i + 1
- end
- local result = TM.New()
- result[1] = err
- if errors > 0 then
- return result
- end
- result[2] = blocks
- return result
- end
- check_ip = memoize(check_ip) -- memoized
- local function ip2long(ip_addr)
- local blocks = check_ip(ip_addr)[2] or error("Invalid IP-Address. IP_ADDR: " .. tostring(ip_addr) .. "\r\nError: " .. check_ip(ip_addr)[1])
- local a = bit32.lshift(blocks[1], 24)
- local b = #blocks >= 2 and bit32.lshift(blocks[2], 16)
- local c = #blocks >= 3 and bit32.lshift(blocks[3], 8)
- if not b or not c then return nil end
- return bit32.bor(bit32.bor(a, b, c), blocks[4])
- end
- ip2long = memoize(ip2long) -- memoized
- local function convertSign(num, maxSize)
- return num - bit32.band(num, maxSize)*2
- end
- convertSign = memoize(convertSign) -- memoized
- local function long2ip(addr)
- addr = tonumber(addr) or error("Invalid 32-bit Long: " .. addr)
- local a = bit32.rshift(bit32.band(addr, bit32.lshift(0xFF, 24)), 24)
- local b = bit32.rshift(bit32.band(addr, bit32.lshift(0xFF, 16)), 16)
- local c = bit32.rshift(bit32.band(addr, bit32.lshift(0xFF, 8)), 8)
- local d = bit32.band(addr, 0xFF)
- return format("%i.%i.%i.%i", convertSign(a, 255), convertSign(b, 255), convertSign(c, 255), convertSign(d, 255))
- end
- long2ip = memoize(long2ip) -- memoized
- function netMatch(network, ip)
- network = validate_ipv4(network)
- -- if no ip to check, then just validate the network.
- if not ip then return network end
- ip = validate_ipv4(ip)
- local orig_network = network
- if ip == network then
- --print("used network " .. network .. " for ip " .. ip)
- return network
- end
- network = gsub(network, ' ', '')
- if find(network, '*') then
- if find(network, '/') then
- network = tokenizestring(network, '/')[1]
- end
- local nCount
- network, nCount = gsub(network, '*', '*')
- network = gsub(network, '*', '0')
- if nCount == 1 then
- network = network .. '/24'
- elseif nCount == 2 then
- network = network .. '/16'
- elseif nCount == 3 then
- network = network .. '/8'
- elseif nCount > 3 then
- return network -- if *.*.*.*, then all, so matched
- end
- end
- if find(ip, '*') then
- if find(ip, '/') then
- ip = tokenizestring(ip, '/')[1]
- end
- local nCount
- ip, nCount = gsub(ip, '*', '*')
- ip = gsub(ip, '*', '0')
- if nCount == 1 then
- ip = ip .. '/24'
- elseif nCount == 2 then
- ip = ip .. '/16'
- elseif nCount == 3 then
- ip = ip .. '/8'
- elseif nCount > 3 then
- return ip -- if *.*.*.*, then all, so matched
- end
- end
- --print("from original network " .. orig_network .. ", used network " .. network .. " for " .. ip)
- local d = find(network, '-')
- if not d then
- local ip_arr = tokenizestring(network, "/")
- local network_long = ip2long(ip_arr[1])
- local mask = bit32.lshift(0xFFFFFFFF, (32 - (ip_arr[2] or 32)))
- local ip_arr2 = tokenizestring(ip, "/")
- local ip_long = ip2long(ip_arr2[1])
- local mask2 = bit32.lshift(0xFFFFFFFF, (32 - (ip_arr2[2] or 32)))
- return bit32.band(network_long, mask, mask2) == bit32.band(ip_long, mask, mask2)
- else
- local from = ip2long(sub(network, 1, d-1))
- local to = ip2long(sub(network, d+1))
- ip = ip2long(ip)
- return ip >= from and ip <= to
- end
- end
- netMatch = memoize(netMatch) -- memoized
- local function loadBanFile(filename, bantype)
- local file = io.open(filename)
- if file then
- local t = TM.New()
- local b
- local pos, endline, timestr, formatBantype, unique_index, count
- for line in file:lines() do
- -- Sometimes a rand blank line appears in the file, let's make sure not to error for those
- if match(line, "%g%g%g+") and sub(line, 1, 1) ~= "#" then
- -- create a new table for the ban entry if we need to (I love ternary operator too much)
- b = TM.New()
- -- A line can ONLY have the following format: Name, HashOrIp [, IP] [, Bancount [, Time [, Bantype]]]
- -- The exception is namebans, which will always be: Name [, Bantype] where Bantype can only be the string 'name' and nothing else
- -- Examples of valid chat bans:
- -- 123456789abcdef123456789abcdef,127.0.0.1
- -- wizard,123456789abcdef123456789abcdef,127.0.0.1
- -- wizard,123456789abcdef123456789abcdef,127.0.0.1,1
- -- wizard,123456789abcdef123456789abcdef,127.0.0.1,1,--
- -- wizard,123456789abcdef123456789abcdef,127.0.0.1,1,--,chat
- -- wizard,123456789abcdef123456789abcdef,127.0.0.1,1,--,chat,he was spamming
- -- First half: Match chatban (name,hash,ip) or hashban (name,hash) or nameban (name [,bantype])
- -- if this matches then this is a chatban
- b.name,b.hash,b.ip,endline = match(line, "^(.-[^,]?),?(%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+),([^,]+)(.-)$")
- b.ip = b.ip and (b.ip == "1.2.3.4" and b.ip or validate_ipv4(b.ip))
- if b.hash and b.ip then
- formatBantype = "chat"
- unique_index = b.hash .. (b.ip or "") .. "chat"
- goto ReadSecondHalf
- end
- -- this will match a hash ban
- b.name,b.hash,endline = match(line, "^(.-[^,]?),?(%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+)(.*)$")
- if b.hash then
- formatBantype = "hash"
- unique_index = b.hash .. "hash"
- goto ReadSecondHalf
- end
- -- this will match an IP ban.
- b.name,b.ip,endline = match(line, "^(.-[^,]?)[,]([^,]+)(.-)$")
- b.ip = b.ip and validate_ipv4(b.ip)
- if not b.ip then
- b.name,b.ip,b.reason = match(line, "^(.-[^:]?):([^:]+)(.-)$")
- b.ip = b.ip and validate_ipv4(b.ip)
- end
- if b.ip then
- formatBantype = "ip"
- unique_index = b.ip .. "ip"
- goto ReadSecondHalf
- end
- -- and lastly this will match a name ban.
- b.name,b.type = match(line, "^(.-[^,]?),?(%w-)")
- if b.name then
- formatBantype = "name"
- unique_index = b.name .. "name"
- goto ReadSecondHalf
- end
- error(filename .. " is formatted incorrectly! Line: " .. line)
- ::ReadSecondHalf::
- -- This part matches the rest of the line. Here are some examples that it will match (starting from the end of the string)
- -- (nothing here)
- -- ,1 ,(count)
- -- ,5,-- ,(count),(infinite time)
- -- ,2,2015-06-13 05:29:51,chat ,(count),(time),(bantype)
- -- ,3,-1,chat,offensive language ,(count),(infinite time),(bantype),(reason)
- if not b.reason and endline and endline ~= "" then
- count,timestr,b.type,b.reason = match(endline, "^,(%d+),?(.*[^,]),?(%w*),?(.-)$")
- b.reason = b.reason and b.reason ~= "" and b.reason
- -- these don't exist in a nameban
- elseif not b.type or b.type == "" then
- b.count = nil
- b.type = nil
- b.reason = nil
- timestr = nil
- end
- -- Check if the ban types are what they should be.
- -- I try to make my code stop using tons of checks, but this is the one time where it actually needs them
- b.type = b.type and b.type ~= "" and b.type
- if b.type and b.type ~= formatBantype then
- error(filename .. " is formatted incorrectly! expected bantype " .. formatBantype .. " instead got " .. tostring(b.type) .. " on line: " .. line)
- elseif bantype and bantype ~= formatBantype then
- error(filename .. " should only have '" .. bantype .. "' bans. Ban of type '" .. formatBantype .. "' was found in the line: " .. line)
- else
- b.type = formatBantype
- end
- if timestr then
- -- Match the time.
- -- Time format: YYYY-MM-DD HH:MM:SS
- t.year, t.month, t.day, t.hour, t.min, t.sec = match(timestr, "^(%d%d%d%d)%-(%d%d)%-(%d%d)%s+(%d%d):(%d%d):(%d%d)$")
- -- convert 'ban expiration date' to 'seconds remaining until ban expires'
- if t.sec then
- b.time = os.time(t)
- -- else time will become -1 (infinite) or "Unbanned"
- else
- b.time = find(timestr, "Unbanned") and "Unbanned" or -1
- end
- -- time not specified in ban file, should be indefinite.
- else
- b.time = -1
- end
- if formatBantype ~= "name" then
- count = tonumber(count)
- b.count = count and count > 0 and count or 1
- end
- -- Make sure this entry hasn't already been added before we add it.
- if not ban_table[unique_index] then
- b.name = b.name == "" and "Unnamed" or b.name
- ban_table[#ban_table+1] = b
- ban_table[unique_index] = #ban_table
- end
- end
- end
- file:close()
- end
- end
- local function updateBanFiles(bantype)
- -- write the bans to the banned.txt file
- -- Save all bans to banned.txt
- local writetbl = TM.New()
- local ban_entry
- local file = io.open(profilepath .. defaults.banlist_file .. ".txt", "w")
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.type == "chat" then
- writetbl[#writetbl+1] = ban_entry.name..","..ban_entry.hash..","..(ban_entry.ip or "1.2.3.4")..","..ban_entry.count..","..(ban_entry.time == "Unbanned" and "Unbanned" or ban_entry.time == -1 and "--" or os.date("%Y-%m-%d %X", ban_entry.time))..","..ban_entry.type..(ban_entry.reason and (","..ban_entry.reason) or "")
- elseif ban_entry.type == "hash" then
- writetbl[#writetbl+1] = ban_entry.name .. "," .. ban_entry.hash .. "," .. ban_entry.count .. "," .. (ban_entry.time == "Unbanned" and "Unbanned" or ban_entry.time == -1 and "--" or os.date("%Y-%m-%d %X", ban_entry.time)) .. "," .. ban_entry.type..(ban_entry.reason and (","..ban_entry.reason) or "")
- elseif ban_entry.type == "ip" then
- writetbl[#writetbl+1] = ban_entry.name..","..ban_entry.ip..","..ban_entry.count..","..(ban_entry.time == "Unbanned" and "Unbanned" or ban_entry.time == -1 and "--" or os.date("%Y-%m-%d %X", ban_entry.time))..","..ban_entry.type..(ban_entry.reason and (","..ban_entry.reason) or "")
- elseif ban_entry.type == "name" then
- writetbl[#writetbl+1] = ban_entry.name..","..ban_entry.type..(ban_entry.reason and (","..ban_entry.reason) or "")
- end
- end
- file:write(concat(writetbl, "\n"))
- file:close()
- end
- local function updateAdminFiles()
- local file = io.open(profilepath .. defaults.admin_file .. ".txt", "w")
- local writetbl = TM.New()
- for index,admin_entry in next,admin_table do
- writetbl[#writetbl+1] = admin_entry.name .. "," .. index .. "," .. admin_entry.level .. "," .. admin_entry.type
- end
- file:write(concat(writetbl, "\n"))
- file:close()
- end
- local function loadAllAdminFiles()
- local timestamp = os.date "%Y_%m_%d_%H_%M_%S"
- local file = io.open(profilepath .. "admin.txt")
- if file then
- local name, hash, level
- for line in file:lines() do
- -- format the line (name, hash, level)
- name, hash, level = match(line, "^(%w-),(%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+),(%d+)%c*$")
- if hash then
- admin_table[hash] = TM{name = name, level = tonumber(level), type = "hash"}
- end
- end
- file:close()
- os.rename(profilepath .. "admin.txt", profilepath .. "old_admin_" .. timestamp .. ".txt")
- end
- -- Now stores IP admins as well.
- file = io.open(profilepath .. defaults.admin_file .. ".txt")
- if file then
- local name, hash, ip, level, admintype
- for line in file:lines() do
- -- format the line (name, hash, level)
- name, hash, level = match(line, "^(%w-),(%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+),(%d+)")
- if hash then
- admin_table[hash] = TM{name = name, level = tonumber(level), type = "hash"}
- else
- -- format the line (name, hash, level, ip)
- name, ip, level = match(line, "^(%w-),(%g-),(%d+)")
- ip = validate_ipv4(ip)
- if ip then
- admin_table[ip] = TM{name = name, level = tonumber(level), type = "ip"}
- else
- error(defaults.admin_file .. ".txt is incorrectly formatted! Line: " .. line)
- end
- end
- end
- file:close()
- end
- -- IP Admins now use admins.txt, but this is here for backwards compatibility.
- file = io.open(profilepath .. "ipadmins.txt")
- if file then
- local name, level, ip
- for line in file:lines() do
- -- format the line (name, hash, level, ip)
- name, ip, level = match(line, "^(%w-),(%g-),(%d+)%c*$")
- ip = validate_ipv4(ip)
- if ip then
- admin_table[ip] = TM{name = name, level = tonumber(level), type = "ip"}
- end
- end
- file:close()
- os.rename(profilepath .. "ipadmins.txt", profilepath .. "old_ipadmins_" .. timestamp .. ".txt")
- end
- updateAdminFiles()
- end
- -- changes 'sv_myCommand' into 'thisCommand', '/thisCommand' into 'thisCommand', and '\thisCommand' into 'thisCommand'
- local function getvalidformat(command)
- local sv_found, slash_found, both_found = sub(command, 1, 3), sub(command, 1, 1), sub(command, 1, 4)
- if sv_found == "sv_" then
- return gsub(sub(command, 4), "[_ ]", "")
- elseif slash_found == "\\" or slash_found == "/" then
- return gsub(sub(command, 2), "[_ ]", "")
- elseif both_found == "\\sv_" or both_found == "/sv_" then
- return gsub(sub(command, 5), "[_ ]", "")
- end
- return gsub(command, "[_ ]", "")
- end
- getvalidformat = memoize(getvalidformat) -- memoized
- local function getaccess(playerId)
- local access
- if getplayer(playerId) then
- return player_table[playerId].admin_entry and player_table[playerId].admin_entry.level
- else
- access = true
- end
- return access
- end
- local function SelectRandomPlayer(team)
- local t = TM.New()
- local size = 0
- for i = 0,15 do
- if getplayer(i) and (not team or getteam(i) == team) then
- size = size + 1
- t[size] = i
- end
- end
- if size > 0 then
- return t[rand(1, size)]
- end
- end
- -- Origstring is the string to search in, wild is the string to search for.
- local function wildstring(origstring, wild, case_sensative)
- -- If not case sensitive then make all arguments lowercase.
- if not case_sensative then
- origstring, wild = lower(origstring), lower(wild)
- end
- wild = gsub(wild, "?", ".")
- wild = gsub(wild, "*", ".*")
- origstring = gsub(origstring, " ", "_")
- wild = gsub(wild, " ", "_")
- --[[say "-----"
- say(origstring)
- say(wild)--]]
- local found = match(origstring, wild)
- --say(tostring(found))
- if found and #found == #origstring then
- return true
- end
- return false
- end
- wildstring = memoize(wildstring) -- memoized
- local function getvalidplayers(expression, playerId)
- local players = TM.New()
- if cur_players ~= 0 and expression then
- if expression == "*" then
- for i = 0,15 do
- if getplayer(i) then
- players[#players+1] = i
- end
- end
- elseif expression == "me" then
- if playerId then
- players[1] = playerId
- end
- elseif expression == "red" then
- for i = 0,15 do
- if getplayer(i) and getteam(i) == 0 then
- players[#players+1] = i
- end
- end
- elseif expression == "blue" then
- for i = 0,15 do
- if getplayer(i) and getteam(i) == 1 then
- players[#players+1] = i
- end
- end
- elseif expression == "randomred" or expression == "randred" then
- players[1] = SelectRandomPlayer(0)
- elseif expression == "randomblue" or expression == "randblue" then
- players[1] = SelectRandomPlayer(1)
- elseif (tonumber(expression) or 0) >= 1 and (tonumber(expression)) <= 16 then
- local playerId2 = tonumber(expression)
- if getplayer(rresolveplayer(playerId2)) then
- players[1] = rresolveplayer(playerId2)
- end
- elseif expression == "rand" or expression == "random" then
- players[1] = SelectRandomPlayer()
- else
- for i = 0,15 do
- if getplayer(i) and wildstring(getname(i), expression) then
- players[#players+1] = i
- end
- end
- end
- return next(players) and players or false
- end
- return false
- end
- local function LoadTags()
- local map_base = readdword(addresses.map_pointer)
- local tag_table_base = readdword(map_base) -- Confirmed. (0x40440028)
- local tag_table_count = readdword(map_base + 0xC) -- Confirmed. Number of tags in the tag table.
- local tag_table_size = 0x20 -- Confirmed.
- local reverse = string.reverse
- local tag_class, tag_id, tag_name_address, tag_name
- for i=0,(tag_table_count - 1) do
- tag_class = reverse(readstring(tag_table_base + (tag_table_size * i), 4))
- tag_id = readdword(tag_table_base + 0xC + (tag_table_size * i))
- tag_name_address = readdword(tag_table_base + 0x10 + tag_table_size * i)
- tag_name = readstring(tag_name_address)
- tag_table[tag_class] = tag_table[tag_class] or TM.New()
- tag_table[tag_class][tag_name] = tag_id
- tag_table[tag_id] = TM.New()
- tag_table[tag_id].tag_name = tag_name
- tag_table[tag_id].tag_class = tag_class
- end
- objects.cyborg = gettag("bipd", "characters\\cyborg_mp\\cyborg_mp")
- objects.camo = gettag("eqip", "powerups\\active camouflage")
- objects.health = gettag("eqip", "powerups\\health pack")
- objects.overshield = gettag("eqip", "powerups\\over shield")
- objects.fnade = gettag("eqip", "weapons\\frag grenade\\frag grenade")
- objects.pnade = gettag("eqip", "weapons\\plasma grenade\\plasma grenade")
- objects.shee = gettag("vehi", "vehicles\\banshee\\banshee_mp")
- objects.turret = gettag("vehi", "vehicles\\c gun turret\\c gun turret_mp")
- objects.ghost = gettag("vehi", "vehicles\\ghost\\ghost_mp")
- objects.rhog = gettag("vehi", "vehicles\\rwarthog\\rwarthog")
- objects.tank = gettag("vehi", "vehicles\\scorpion\\scorpion_mp")
- objects.hog = gettag("vehi", "vehicles\\warthog\\mp_warthog")
- objects.rifle = gettag("weap", "powerups\\assault rifle ammo\\assault rifle ammo")
- objects.ball = gettag("weap", "weapons\\ball\\ball")
- objects.flag = gettag("weap", "weapons\\flag\\flag")
- objects.flamethrower = gettag("weap", "weapons\\flamethrower\\flamethrower")
- objects.needler = gettag("weap", "weapons\\needler\\mp_needler")
- objects.pistol = gettag("weap", "weapons\\pistol\\pistol")
- objects.ppistol = gettag("weap", "weapons\\plasma pistol\\plasma pistol")
- objects.prifle = gettag("weap", "weapons\\plasma rifle\\plasma rifle")
- objects.frg = gettag("weap", "weapons\\plasma_cannon\\plasma_cannon")
- objects.rocket = gettag("weap", "weapons\\rocket launcher\\rocket launcher")
- objects.shotgun = gettag("weap", "weapons\\shotgun\\shotgun")
- objects.sniper = gettag("weap", "weapons\\sniper rifle\\sniper rifle")
- objects.sheebolt = gettag("proj", "vehicles\\banshee\\banshee bolt")
- objects.sheerod = gettag("proj", "vehicles\\banshee\\mp_banshee fuel rod")
- objects.turretbolt = gettag("proj", "vehicles\\c gun turret\\mp gun turret")
- objects.ghostbolt = gettag("proj", "vehicles\\ghost\\ghost bolt")
- objects.tankshot = gettag("proj", "vehicles\\scorpion\\bullet")
- objects.tankshell = gettag("proj", "vehicles\\scorpion\\tank shell")
- objects.hogshot = gettag("proj", "vehicles\\warthog\\bullet")
- objects.rifleshot = gettag("proj", "weapons\\assault rifle\\bullet")
- objects.flame = gettag("proj", "weapons\\flamethrower\\flame")
- objects.needlershot = gettag("proj", "weapons\\needler\\mp_needle")
- objects.pistolshot = gettag("proj", "weapons\\pistol\\bullet")
- objects.ppistolbolt = gettag("proj", "weapons\\plasma pistol\\bolt")
- objects.priflebolt = gettag("proj", "weapons\\plasma rifle\\bolt")
- objects.priflecbolt = gettag("proj", "weapons\\plasma rifle\\charged bolt")
- objects.rocketproj = gettag("proj", "weapons\\rocket launcher\\rocket")
- objects.shottyshot = gettag("proj", "weapons\\shotgun\\pellet")
- objects.snipershot = gettag("proj", "weapons\\sniper rifle\\sniper bullet")
- objects.fuelrodshot = gettag("proj", "weapons\\plasma_cannon\\plasma_cannon")
- end
- function votekickTimer(id, count)
- say("The VoteKick on " .. getname(votekickPlayerId) .. " has expired!")
- votekicktimer = nil
- votekickPlayerId = nil
- votekick_counter = -defaults.votekick_timeout
- for i = 0,15 do
- ip_table[getip(i)].used_votekick = false
- end
- return false
- end
- local function WriteLog(filename, logStr)
- local file = io.open(filename, "a")
- if file then
- file:write(format("%s\t%s\n", os.date "%Y/%m/%d %H:%M:%S", logStr))
- file:close()
- end
- end
- local function cmdlog(message)
- WriteLog(profilepath .. "logs\\" .. defaults.commands_file .. ".log", message)
- end
- -- This local function makes sure that we never have any commands that output more than 8 lines
- -- We need this because Halo only lets you see 8 lines of text at a time in the chat
- -- This local function will also split lines into more lines if a line is too long.
- -- If a person is executing \pl in the chat, we want them to be able to see players 1 through 16, therefore this local function is born.
- -- Arguments are output, maximum number of lines to use (MIGHT go over maxlines if the line length is already too long)
- -- maxlinesize is the maximum number of characters a line can have
- -- If output is a table, this local function will check for the keys 'align', 'header', 'delim', and 'separator', otherwise it'll read it as a string.
- local function formatOutput(output, maxlines, maxlinesize)
- -- error if the arguments were passed incorrectly.
- if type(output) ~= "string" and type(output) ~= "table" then
- error("bad argument #1 to 'formatOutput' (expected table or string, got " .. type(output) .. ")" .. " Value: " .. tostring(output))
- elseif maxlines and type(maxlines) ~= "number" then
- error("bad argument #2 to 'formatOutput' (expected number, got " .. type(maxlines) .. " Value: " .. tostring(maxlines))
- elseif maxlinesize and type(maxlinesize) ~= "number" then
- error("bad argument #3 to 'formatOutput' (expected number, got " .. type(maxlinesize) .. " Value: " .. tostring(maxlinesize))
- end
- -- handle our arguments
- local newOutput = type(output) == "string" and tokenizestring(output, "\n") or output
- maxlines = maxlines or 9001
- maxlinesize = maxlinesize or 9001
- local header = newOutput.header
- local numOfLines = #newOutput
- local linesCombined = ceil((numOfLines + (header and 1 or 0))/maxlines)
- -- duplicate the header by linesCombined times.
- if header then
- if type(header) ~= "string" then
- error("Output header needs to be a string, got " .. type(header))
- end
- for i = 1,linesCombined do
- insert(newOutput, 1, header)
- cmdreply.index = cmdreply.index + 1
- numOfLines = numOfLines + 1
- end
- end
- -- If we have no more output, then we don't need to do anything more.
- if numOfLines == 1 and header or numOfLines == 0 then
- return newOutput[1]
- end
- if newOutput.align then
- local delimiter = newOutput.delim or "|"
- local separator = newOutput.separator or delimiter
- local mins = TM.New()
- local length, lineParts
- for i = 1,numOfLines do
- lineParts = tokenizestring(newOutput[i], delimiter)
- for j = 1,#lineParts do
- -- Format every string to the biggest length possible for that entry.
- length = #(lineParts[j])
- if not mins[j] or length > mins[j] then
- mins[j] = length
- end
- end
- end
- local numOfLineParts
- for i = 1,numOfLines do
- lineParts = tokenizestring(newOutput[i], delimiter)
- numOfLineParts = #lineParts
- for j = 1,numOfLineParts do
- lineParts[j] = format("%-" .. mins[j] .. "s", lineParts[j])
- end
- lineParts[numOfLineParts] = sub(lineParts[numOfLineParts], 1, -1) -- removes the last delimiter in the line
- newOutput[i] = concat(lineParts, separator)
- end
- end
- -- If our output uses too many lines. We now need to combine lines until we are within maxlines
- local lineIter = 1
- local numOfLinesToCombine = floor(numOfLines / linesCombined)
- while numOfLines > maxlines do
- for i = 2,linesCombined do -- should be 1,linesCombined-1 but 2,linesCombined works fine
- if lineIter+1 > numOfLines then break end
- newOutput[lineIter] = newOutput[lineIter] .. " - " .. newOutput[lineIter+1]
- remove(newOutput, lineIter+1)
- numOfLines = numOfLines - 1
- cmdreply.index = cmdreply.index - 1
- end
- lineIter = lineIter + 1
- if numOfLinesToCombine == 1 then
- linesCombined = linesCombined - 1
- if linesCombined < 2 then break end
- numOfLinesToCombine = floor(numOfLines / linesCombined)
- end
- numOfLinesToCombine = numOfLinesToCombine - 1
- end
- -- Make sure the line isn't too long.
- -- If it is, we put the part that's too long into a new table which we will put back into output later.
- lineIter = 1
- local line, length
- while newOutput[lineIter] do
- line = newOutput[lineIter]
- length = #line
- if length > maxlinesize then
- newOutput[lineIter] = sub(line, 1, maxlinesize) -- first part of line
- insert(newOutput, lineIter+1, sub(line, maxlinesize)) -- insert a new line right after this one with the second part
- numOfLines = numOfLines + 1
- cmdreply.index = cmdreply.index + 1
- end
- lineIter = lineIter + 1
- end
- return concat(newOutput, "\n", 1, numOfLines)
- end
- function delayMsg(id, count, arguments)
- local msg, playerId = arguments[1], arguments[2]
- msg = type(msg) == "table" and concat(msg, "\n") or msg
- if playerId then
- if output_environment == 2 then
- say(msg)
- elseif output_environment == 3 then
- privatesay(playerId, msg)
- end
- end
- return false
- end
- local function sendresponse(message, playerId, log)
- if not message then
- -- this will reset all the properties of cmdreply
- cmdreply(true)
- return
- end
- local playerCheck = getplayer(playerId)
- local tempmessage = message
- if not playerCheck then
- message = formatOutput(message)
- hprintf(message)
- elseif output_environment == 1 then
- message = formatOutput(message, 20, 76)
- sendconsoletext(playerId, message)
- elseif output_environment == 2 or output_environment == 3 then
- message = formatOutput(message, 6, 100)
- registertimer(0, "delayMsg", TM{message, playerId})
- end
- if log and playerCheck then
- cmdlog("Response to " .. getname(playerId) .. " (" .. player_table[playerId].admin_entry.name .. "): " .. message)
- end
- -- this will reset all the properties of cmdreply
- if tempmessage == cmdreply then cmdreply(true) end
- end
- local function setscore(playerId, score)
- if gametype == 1 then
- local m_player = getplayer(playerId)
- writeshort(m_player+0xC8, score)
- elseif gametype == 2 then
- writeint(addresses.slayer_globals + 0x40 + playerId*4, score)
- elseif gametype == 3 then
- local oddball_game = readbyte(addresses.gametype_base + 0x8C)
- if oddball_game == 0 or oddball_game == 1 then
- writeint(addresses.oddball_globals + 0x84 + playerId*4, score * 30)
- else
- writeint(addresses.oddball_globals + 0x84 + playerId*4, score)
- end
- elseif gametype == 4 then
- local m_player = getplayer(playerId)
- writeshort(m_player + 0xC4, score * 30)
- elseif gametype == 5 then
- local m_player = getplayer(playerId)
- writeshort(m_player + 0xC6, score)
- end
- end
- local function WriteChangeLog()
- local file = io.open("changelog_" .. script_version .. ".txt", "w")
- local changelog = TM.New()
- changelog[#changelog+1] = "Changelog for Commands Script"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 5.13 The 'Nimbus' Release (Released Released February 21th, 2015)"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "--Fixed a few minor bugs, there was a couple of issues with the banlist saving/reloading that happened in rare situations"
- changelog[#changelog+1] = "--Revamped even more code for optimization, and added lots of memoizing."
- changelog[#changelog+1] = "Changelog for Commands Script"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 5.01 The 'Nimbus' Release (Released Released February 20th, 2015)"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "--Fixed a very minor issue with banlist reloading. (was still loading from unused_banlist.txt, not a major problem)"
- changelog[#changelog+1] = "--Found out that the 'tbag' feature Aelite added was only supposed to apply to kills, so that is now a thing"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 5.0 The 'Nimbus' Release (**WIZARD IS BACK** Released February 19, 2015)"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "--You can change logfile and text files with the following new commands: sv_sharedhash_file, sv_banlist_file, sv_admin_file, sv_commands_file and sv_kickbans_file"
- changelog[#changelog+1] = "--This script will no longer load the defaults.txt if this script was loaded from the persistent folder (Phasor Only)"
- changelog[#changelog+1] = "--Time arguments for all commands have changed. All now use the format 5d 3s 2y 5m etc. If you do not specify a character (cywdhms) at the end of your time, then it will default to seconds, so something like sv_respawn_time 500m is different than sv_respawn_time 500."
- changelog[#changelog+1] = "--Commands that use a player's IP now appends a /24 at the end, which contains the range of 256 addresses within the range of the original IP address. That means if you use sv_ipban 1 and player 1 has an IP of 192.168.0.1, it will ban all the IPs from 192.168.0.0 through 192.168.0.255. This is just a default, you can change it to the old way by appending a /32 at the end of the player."
- changelog[#changelog+1] = "--The mute command is now the same command as textban, unmute will now untextban a player while sv_unban will unban a textban ID (from sv_banlist)"
- changelog[#changelog+1] = "--Timestamps added to the ban files are now YY-MM-DD HH:MM:SS instead of just a huge number that represents seconds (you can modify ban expire time a lot easier now)"
- changelog[#changelog+1] = "--This script will now load sapp's 'ipbans.txt' file."
- changelog[#changelog+1] = "--Loading/saving of admins/ban_table are much more reliable now, the script will error if your file is formatted incorrectly"
- changelog[#changelog+1] = "--All scripted game variables (like deathless, infinite ammo, noweapons) now are integrated completely and will not spam the output window onnewgame anymore"
- changelog[#changelog+1] = "--Kick/Ban/Mute commands now let you pass reason and time normally, you don't have to use _ for reasons anymore."
- changelog[#changelog+1] = "--All structures now follow a global naming scheme that I plan to use in all my scripts from now on"
- changelog[#changelog+1] = "--All code now uses my phasor functions to get addresses (getplayerobject, getplayerweapon, etc) for increased performance"
- changelog[#changelog+1] = "--This script now uses local variables to optimize performance."
- changelog[#changelog+1] = "--Revamped ALL functions to execute faster with better code. Some of them I haven't even touched since version 1.0. The first version."
- changelog[#changelog+1] = "--Added a /disconnect and sv_disconnect command which will give a player a 'lost network connection' screen"
- changelog[#changelog+1] = "--Removed a few useless commands that never did work but somehow people found out about (probably because of /list lol)"
- changelog[#changelog+1] = "--Gethelp added. Usage: sv_gethelp (command) or /help (command) without ()"
- changelog[#changelog+1] = "--Global rcons functionality updated (see guide for details)"
- changelog[#changelog+1] = "--List command updated so it will not take a 'page' argument. To get a list of commands, type sv_list or /list"
- changelog[#changelog+1] = "--Organized all commands by table so now all commands are fully documented with help notes and everything"
- changelog[#changelog+1] = "--textbanlist, iprangebanlist, ipbanlist, and namebanlist are all deprecated. Commands will save the bans in the 'banned.txt' (or whatever sv_banlist_file is set to (banned.txt by default)) file from now on."
- changelog[#changelog+1] = "--Commands now uses admins.txt for both hash admins and IP admins, ipadmins.txt will still be read for backwards compatibility."
- changelog[#changelog+1] = "--The old deprecated ban files will now have 'archived_' in front of them. Same goes for the admin files."
- changelog[#changelog+1] = "--Commands will automatically load the old ban files for backwards compatibility so you do not need to do anything with that. Just know that the old files won't get updated anymore."
- changelog[#changelog+1] = "--All banlist and unban commands are now deprecated and have been removed. Use sv_banlist and sv_unban to view the banlist and unban people."
- changelog[#changelog+1] = "--Anyone joining with a hacked hash (like hash 'myfakehashtrollu') will not be allowed into the server"
- changelog[#changelog+1] = "--Chat commands now directly execute server commands (/e is now deprecated) and the script is much smaller because of it"
- changelog[#changelog+1] = "--Rewrote BOS functionality"
- changelog[#changelog+1] = "--Rewrote the Spawn functionality and made the code 10x smaller by using better and more efficient coding"
- changelog[#changelog+1] = "--I've fixed things here and there, added things that were removed from my original Commands."
- changelog[#changelog+1] = "--Fixed /read (it never worked). Also accepts number structs."
- changelog[#changelog+1] = "--Fixed /write to not break on invalid syntax. Also accepts number structs.."
- changelog[#changelog+1] = "--Added randomred and randomblue to expressions list."
- changelog[#changelog+1] = "--Added a control command (FINALLY)"
- changelog[#changelog+1] = "--Fixed sending negative numbers to setplasmas and setfrags"
- changelog[#changelog+1] = "--Fixed occasional glitches with setammo."
- changelog[#changelog+1] = "--Rewrote the access system. You now do not have to start at lvl 0 being the highest, you can now have levels in any order"
- changelog[#changelog+1] = "--Script also tells you if your access.ini is not formatted correctly and why and then raises an error."
- changelog[#changelog+1] = "--Changed sv_status to sv_status_more as to not interfere with normal sv_status"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 4.2(Released August 3rd, 2013)"
- changelog[#changelog+1] = "--Update Reason: Bug fixes and Added Features"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added the time limit address thanks to wizard. sv_time_cur is now compatible with Halo CE"
- changelog[#changelog+1] = "--Added the sendconsoletext overload to the command scripts. Thank you Nuggetz."
- changelog[#changelog+1] = "--Added 'sv_hash_duplicates' command which enables/disables the checking of duplicate keys in the server."
- changelog[#changelog+1] = "--Added 'sv_multiteam_vehicles' Enables/Disables the ability to enter a vehicle with another playerId in FFA."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified all tables that used the hash for identication, and changed it to IP"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed minor bug with votekick"
- changelog[#changelog+1] = "--Fixed issue with sv_superban"
- changelog[#changelog+1] = "--Fixed AntiCaps command. WARNING: If you use a chatfilter script. Load that script before this one."
- changelog[#changelog+1] = "--Fixed issue with team play detection"
- changelog[#changelog+1] = "--Fixed minor bugs."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 4.1(Released July 23rd, 2013)"
- changelog[#changelog+1] = "--Update Reason: Bug fixes"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed minor bugs"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 4.0(Released July 21st, 2013)"
- changelog[#changelog+1] = "--Update Reason: make it compatible with new Phasor"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added 'sv_addrcon' This gives you the ability to have more than one rcon."
- changelog[#changelog+1] = "--Added 'sv_delrcon' Removes rcons from the rcon list."
- changelog[#changelog+1] = "--Added 'sv_rconlist' Displays all available rcons"
- changelog[#changelog+1] = "--Added 'sv_iprangeban' ban_table entire IP Range"
- changelog[#changelog+1] = "--Added 'sv_iprangeunban' Removes an IP from the banlist"
- changelog[#changelog+1] = "--Added 'sv_iprangebanlist' Shows all IP's banned"
- changelog[#changelog+1] = "--Added 'sv_read' command."
- changelog[#changelog+1] = "--Added 'sv_load' shortcut for sv_script_load."
- changelog[#changelog+1] = "--Added 'sv_unload' shortcut for sv_script_unload."
- changelog[#changelog+1] = "--Added 'sv_resetplayer' and '/resetplayer' removes all troll command settings."
- changelog[#changelog+1] = "--Added 'sv_damage' Increases playerId damage."
- changelog[#changelog+1] = "--Added reason to sv_textban"
- changelog[#changelog+1] = "--Added Command_Balance local function since sv_team_balance is not a command anymore for the moment."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified Reason is said to the public"
- changelog[#changelog+1] = "--Modified Adminblocker the admin is notified if a command is being executed on them."
- changelog[#changelog+1] = "--Modified AntiSpam changed from boolean to a type: all, players, off"
- changelog[#changelog+1] = "--Modified 'sv_commands' -> 'sv_cmds'"
- changelog[#changelog+1] = "--Modified 'sv_ipban' now accepts IP's'"
- changelog[#changelog+1] = "--Modified AFK detection. Works better"
- changelog[#changelog+1] = "--Modified NameBan. Banned names are changed to 'playerId' on join."
- changelog[#changelog+1] = "--Modified Tbag Detection: Detects victim location. You must be near the victims death to be able to tbag him/her."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed most bugs with the new phasor"
- changelog[#changelog+1] = "--Fixed 'sv_scrimmode'"
- changelog[#changelog+1] = "--Fixed @ bug"
- changelog[#changelog+1] = "--Fixed AccessMerging bug when -1 was given to any other level other than 0"
- changelog[#changelog+1] = "--Fixed minor Bos Bug"
- changelog[#changelog+1] = "--Fixed setscore bug"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Removed sv_pinglist command"
- changelog[#changelog+1] = "--Removed sv_hash_check, sv_version, and sv_version_check. Phasor has them built in."
- changelog[#changelog+1] = "--Removed Portal Blocking"
- changelog[#changelog+1] = "--Removed /setname until further notice"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 3.0.1 (Released February 28th, 2013)"
- changelog[#changelog+1] = "--Update Reason: Mainly Bug Fixes"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added sv_scrimmode"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified ipadminadd now accepts IP's"
- changelog[#changelog+1] = "--Modified 'sv_admin_add: Combined sv_admin_add and sv_admin_addh"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed /e bug"
- changelog[#changelog+1] = "--Fixed spam_max and spam_timeout bugs"
- changelog[#changelog+1] = "--Fixed textban bugs"
- changelog[#changelog+1] = "--Fixed superban bugs"
- changelog[#changelog+1] = "--Fixed ipban bug"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 3.0.0 (released February 11th, 2013)"
- changelog[#changelog+1] = "--Update Reason: Bug Fixes and New Features"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added safe guards for the admin system."
- changelog[#changelog+1] = "--Added Ping List command. Displays the Players ID, Name and Ping level."
- changelog[#changelog+1] = "--Added System for no Hash and/or IP admins"
- changelog[#changelog+1] = "--Added a sv_login command so if you are using the System for no Hash and/or IP Admins people with rcon are able to use chat commands"
- changelog[#changelog+1] = "--Added a sv_status command. It will show the current status of defaults.txt commands."
- changelog[#changelog+1] = "--Added info shown to the sv_info command"
- changelog[#changelog+1] = "--Added 'sv_chatcommands' to enable or disable admin chat commands"
- changelog[#changelog+1] = "--Added 'sv_adminblocker' enables,disables or limits the abiliy of an admin to kick/ban another admin"
- changelog[#changelog+1] = "--Added 'sv_anticaps' Enables or Disables the use of caps in the server"
- changelog[#changelog+1] = "--Added 'sv_antispam' Enables or Disables the antispam system of the script"
- changelog[#changelog+1] = "--Added 'sv_spammax' Changes the max amount of messages that can be sent in 1 minute"
- changelog[#changelog+1] = "--Added 'sv_spamtimeout' Changes the time you are muted for spamming"
- changelog[#changelog+1] = "--Added a time amount that a playerId can be textbanned 'sv_textban [playerId] {time}'. if no time is set then the default is -1 which is forever."
- changelog[#changelog+1] = "--Added a way to use any command without the 'sv_' Ex: 'sv_admin_add' can be written as 'admin_add' "
- changelog[#changelog+1] = "--Added a time amount that a playerId can be ipbanned 'sv_ipban [playerId] {time} {message}'. if no time is set then the default is -1 which is forever."
- changelog[#changelog+1] = "--Added 'sv_bosplayers' to see the available players that can be banned on sight."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified how defaults.txt works. If a command is not specified in the defaults.txt file it is set to default by the script so no errors occur during game."
- changelog[#changelog+1] = "--Modified Tbag function"
- changelog[#changelog+1] = "--Modified ban, you are now able to send reason(s) for the ban which will be written a file."
- changelog[#changelog+1] = "--Modified kick, you are now able to send reason(s) for the kick which will be written a file."
- changelog[#changelog+1] = "--Modified Ipban, you are now able to send reason(s) for the ipban which will be written a file."
- changelog[#changelog+1] = "--Modified Superban, you are now able to send reason(s) for the superban which will be written a file."
- changelog[#changelog+1] = "--Modified Votekick. You can only votekick again after 1 minute has passed since last votekick."
- changelog[#changelog+1] = "--Modified ChangeLevel. The coding for this command has been improved."
- changelog[#changelog+1] = "--Modified GetHelp"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed Ipban bug"
- changelog[#changelog+1] = "--Fixed the '/e' command."
- changelog[#changelog+1] = "--Fixed the 'sv_unmute' command."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Removed sv_command_type and all content related to it"
- changelog[#changelog+1] = "--Removed redundant code."
- changelog[#changelog+1] = "--Renamed 'sv_sa_message' to 'sv_serveradmin_message'"
- changelog[#changelog+1] = "--Renamed 'sv_fj_message' to 'sv_firstjoin_message'"
- changelog[#changelog+1] = "--Renamed 'sv_wb_message' to 'sv_welcomeback_message'"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.4.3 (released September 23rd,2012"
- changelog[#changelog+1] = "--Update Reason: Fixed issues with ServerChat Function."
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed OnServerChat local function error caused Chat Commands to fail."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.4.2 (released August 29th,2012"
- changelog[#changelog+1] = "--Update Reason: Fixed issues from version 2.4.1 and new commands."
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added a change admin level command. You can now change the level of an IP and/or Hash admin level. 'sv_change_level'"
- changelog[#changelog+1] = "--Added a Command Type command. You can now change between the way Wizard setup his chat commands, and my way. 'sv_command_type'"
- changelog[#changelog+1] = "--Added a Command Type command to the default.txt"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--ReAdded Private say command"
- changelog[#changelog+1] = "--ReAdded '/e' command."
- changelog[#changelog+1] = "--ReAdded Nuke Command."
- changelog[#changelog+1] = "--ReAdded SetName Command."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified Tbag function"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed 'sv_info' command error"
- changelog[#changelog+1] = "--Fixed OnServerChat, now you wont get 'You are not allowed to use this command' every time you type."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.4.1 (released August 22nd,2012"
- changelog[#changelog+1] = "--Update Reason: Fixed issues from version 2.4"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed 'sv_players_more' issue."
- changelog[#changelog+1] = "--Fixed 'sv_players' issue."
- changelog[#changelog+1] = "--Fixed Chat Command issue. If you were admin, then you could do any In-Chat in the script. Check Manual for info on how to add new commands."
- changelog[#changelog+1] = "--Fixed Command issue. If you were admin, then you could do any In-Console in the script. Check Manual for info on how to add new commands."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Removed Restriction of Portal Blocking. Warning: Modded Maps with portals might cause the server to crash. Hope to fix soon."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.4 (released August 19th,2012"
- changelog[#changelog+1] = "--Update Reason: New Features, Fix minor bugs, Remove non-working commands(will be re-add later), and Organize the Script"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added Admin Add Hash. You can now add people via hash. So you are able to add people without them being in the server. 'sv_admin_addh'. This is mostly used if you have 5 or more people you want to add at the same time. Another Script is needed to succesfully use this command."
- changelog[#changelog+1] = "--Added a Portal Blocking Command. If someone is blocking a portal they will be killed. 'sv_pbdet'"
- changelog[#changelog+1] = "--Added a Private Messaging boolean for the @ in chat. 'sv_pvtmessage'"
- changelog[#changelog+1] = "--Added Private Messaging to the default.txt"
- changelog[#changelog+1] = "--Added a Tbagging function."
- changelog[#changelog+1] = "--Added a Tbagging Boolean Command. 'sv_tbagdet'"
- changelog[#changelog+1] = "--Added Tbagging Command to the default.txt"
- changelog[#changelog+1] = "--Added Killing spree Notifications"
- changelog[#changelog+1] = "--Added a Killing spree Notification command 'sv_killspree'"
- changelog[#changelog+1] = "--Added Killing spree Notification to the default.txt"
- changelog[#changelog+1] = "--Added a 'Welcome back' message in OnPlayerJoin. It will only say it if you are not an IP/Hash Admin"
- changelog[#changelog+1] = "--Added a Welcome back message command. 'sv_welcomeback_message'"
- changelog[#changelog+1] = "--Added Welcome Back Message to the default.txt"
- changelog[#changelog+1] = "--Added a 'This is the players first time joining the server' message in OnPlayerJoin"
- changelog[#changelog+1] = "--Added a Command for Server Admin Message. 'sv_sa_message'"
- changelog[#changelog+1] = "--Added Server Admin message to the default.txt"
- changelog[#changelog+1] = "--Added a Command for First Joining Message 'sv_firstjoin_message'"
- changelog[#changelog+1] = "--Added First Joining Message to the default.txt"
- changelog[#changelog+1] = "--Added a Command for Unique Counting. 'sv_uniques_enabled'"
- changelog[#changelog+1] = "--Added Unique Counting to the default.txt"
- changelog[#changelog+1] = "--Added a 'sv_players_more' Command. This does the same local function as 'sv_players' but it gives you more information on each playerId."
- changelog[#changelog+1] = "--Added IP to the info Command."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed RTV Enabled Command "
- changelog[#changelog+1] = "--Fixed VoteKick Enabled Command "
- changelog[#changelog+1] = "--Fixed info command. "
- changelog[#changelog+1] = "--Fixed time current command. "
- changelog[#changelog+1] = "--Fixed Set Teleport Shortcut. 'sv_st' "
- changelog[#changelog+1] = "--Fixed Teleport Delete Shortcut. 'sv_t del'"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified 'sv_players' command. Now it only gives you playerId ID, playerId Name, and playerId Team."
- changelog[#changelog+1] = "--Modified 'sv_count' command. Now disables if 'sv_uniques_enabled' is disabled."
- changelog[#changelog+1] = "--Modified Chat Commands: all commands can now be used in chat. Note: Some shortcuts have been transfered but not all."
- changelog[#changelog+1] = "--Modified GetHelp Commnad"
- changelog[#changelog+1] = "--Modified List Command"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Removed 'sv_unban' command from the script. Caused the OnSeverCommand local function to crash."
- changelog[#changelog+1] = "--Removed Private say command"
- changelog[#changelog+1] = "--Removed '/e' command."
- changelog[#changelog+1] = "--Removed Nuke Command."
- changelog[#changelog+1] = "--Removed SetName Command."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Access level crash fixes and a few other features"
- changelog[#changelog+1] = "--Organized all of the Functions"
- changelog[#changelog+1] = "--Commented all Main Functions. This will only show on the Commented version of the script"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.3 (released June 13th 2012"
- changelog[#changelog+1] = "Mainly fixed up the admin system"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added a /crash [playerId] and a sv_crash [playerId] command. Do not use it when the game is ending... you've been warned..."
- changelog[#changelog+1] = "--Added a /scorelimit and a sv_scorelimit command"
- changelog[#changelog+1] = "--Added a /a del command."
- changelog[#changelog+1] = "--Added sv_ipadminadd to the rcon"
- changelog[#changelog+1] = "--Added a patch that will allow new gametypes to be added without restarting the server"
- changelog[#changelog+1] = "--Added textbanning. It's like the mute command except it's a permanent"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified the AdminList command. Shows a lot more now."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed rcon commands so that the responses show up with the /e command"
- changelog[#changelog+1] = "--Fixed the ipban command (whoops)"
- changelog[#changelog+1] = "--Fixed a very small problem with the setcolor command."
- changelog[#changelog+1] = "--Fixed up the timelimit command :)"
- changelog[#changelog+1] = "--Fixed ipadmins. They can now use the rcon."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--This script no longer uses Phasor admins, if it sees that you are, it will delete all of them and add them to mine, so if you see admin.txt"
- changelog[#changelog+1] = "turned into admins.txt, don't worry, it's supposed to do that."
- changelog[#changelog+1] = "--This script enables CE devmode commands (cheat_deathless_player, cheat_medusa, etc)"
- changelog[#changelog+1] = "--IP admins no longer get removed when you unload the commands script"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.201 (released on June 5th 2012)"
- changelog[#changelog+1] = "This is mainly just a bug fix version"
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added a /setscore and sv_setscore command."
- changelog[#changelog+1] = "--Added New functionality to /hax and /unhax"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified setkills, setassists, and setdeaths to work a little cleaner"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed /commands to show all of the commands."
- changelog[#changelog+1] = "--Fixed a weird problem with the /enter command (when you ejected it would crash your game)"
- changelog[#changelog+1] = "--Fixed /a list (i forgot to check for the /, i was only checking for \\a list, so /a list wouldn't work)"
- changelog[#changelog+1] = "--Fixed falldamage (and also made it so longer falls don't kill you)"
- changelog[#changelog+1] = "--Fixed /hide, when you leave and another person rejoins with your playerId number, it will no longer hide them (thank you mitch... lol)"
- changelog[#changelog+1] = "--Fixed a bug when loading this script first, it wouldn't let other scripts control the weapons being assigned on spawn (can't believe i didn't see it earlier, ty nuggets + others)"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.2 (Released on June 1st 2012)"
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added unique playerId tracking. It will keep track of the number of unique players who joined the server"
- changelog[#changelog+1] = "--Added '/count' Get the number of unique players"
- changelog[#changelog+1] = "--Added /balance, it executes sv_teams_balance in console"
- changelog[#changelog+1] = "--Added sv_privatesay. Looks like i forgot the sv_command for that"
- changelog[#changelog+1] = "--Added private chat. Use @(playerId expression) to message someone"
- changelog[#changelog+1] = "--Added /setcolor. Only works in FFA gametypes."
- changelog[#changelog+1] = "--Added namebanning to superban."
- changelog[#changelog+1] = "--Added a \ameban command."
- changelog[#changelog+1] = "--Added ipadmin deleting"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modifed 'sv_map' made it so that the sv_map and /m loads the commands script by default"
- changelog[#changelog+1] = "--Modified the AdminList local function to be a lot more useful"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed Bugs"
- changelog[#changelog+1] = "--Fixed votekick."
- changelog[#changelog+1] = "--Fixed /privatesay. It would only let you message one word before"
- changelog[#changelog+1] = "--Fixed access levels for the script. It kind of worked, but not really."
- changelog[#changelog+1] = "--Fixed an issue with /timelimit and sv_time_cur"
- changelog[#changelog+1] = "--Fixed deathless glitch"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Removed some of the spam when the script loads (it was an easy way to accomplish what i wanted at the time)"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.001"
- changelog[#changelog+1] = "--Fixed /ipadminadd "
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 2.0(Released April 22nd, 2012)"
- changelog[#changelog+1] = "This is pretty much a rewrite of the entire script. So many new features were added. So many that I don't even want to make this changelog. Anyway, I'm forcing myself to make it. So here it is:"
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Added hash check manipulation. You can now disable or enable hash checking (meaning that cracked versions can join your server if its disabled, but that also means everyone is unbannable if they spoof their key (which most people don't know how to do)."
- changelog[#changelog+1] = "--Added sv_revoke and /revoke. The syntax is /revoke [playerId]. This will take away someone's admin who is currently in the server."
- changelog[#changelog+1] = "--Added /os, this will give you an Overshield (syntax is /os [playerId])"
- changelog[#changelog+1] = "--Added a command to view all admins on the server, syntax is: /a list"
- changelog[#changelog+1] = "--Added a command to view the current admins in the server. Syntax is: /viewadmins"
- changelog[#changelog+1] = "--Added a command to view the server specs (processor speed, model name, manufacturer). Syntax is /specs, or sv_specs in console"
- changelog[#changelog+1] = "--Added another playerId expression. Now you are able to use 'rand' as a playerId name So like '/k rand' would kick a rand person"
- changelog[#changelog+1] = "--Added version changing. You can change to any version of Halo. Syntax is: /version {version} or sv_version {version} in console."
- changelog[#changelog+1] = "--Added version check removal. You can enable or disable version checking. Having this disabled means that any person on any version can join your server (please note that your server will only appear on the server you specify in the version command)"
- changelog[#changelog+1] = "--Added a defaults.txt. This text file gets called on server startup."
- changelog[#changelog+1] = "--Added a sv_commands and a /commands. This will show all the commands that exist for this script."
- changelog[#changelog+1] = "--Added a /hide and a /unhide command, these will make you totally hidden from everyone else in the server. It also removes you from the scoreboard, however, it only works with players that join after you execute it. People in the server at the time that you use it will still see you on the scoreboard."
- changelog[#changelog+1] = "--Added a parameter to '/spd'. Syntax is /spd [playerId] {speed}. Doing /spd [playerId] will show you their current speed."
- changelog[#changelog+1] = "--Added another parameter to '/t'. Syntax is '/t list', this will show you the list of teleports for the map."
- changelog[#changelog+1] = "--Added infinite nades to sv_infinite_ammo"
- changelog[#changelog+1] = "--Added a '/banlist' command to chat. This will show you the banlist."
- changelog[#changelog+1] = "--Added a '/alias' command to chat. This will show aliases of the playerId you pick. Kinda glitchy, oxide's fault, not mine."
- changelog[#changelog+1] = "--Added sv_rtv_needed [decimal 0 to 1]"
- changelog[#changelog+1] = "--Added sv_votekick_needed [decimal 0 to 1]"
- changelog[#changelog+1] = "--Added sv_rtv_enabled [true or false, 1 or 0]"
- changelog[#changelog+1] = "--Added sv_votekick_enabled [true or false, 1 or 0]"
- changelog[#changelog+1] = "--Added ipbanning. Syntax is sv_ipban, sv_ipbanlist, sv_ipunban, and for chat: /ipban, /ipbanlist, /ipunban."
- changelog[#changelog+1] = "--Added 'sv_launch' and '/launch'. Syntax is 'sv_launch [playerId]' or '/launch [playerId]'"
- changelog[#changelog+1] = "--Added a control command. Syntax is 'sv_control [victim] [controller]' or '/c [victim] [controller]' in chat."
- changelog[#changelog+1] = "--Added a privatesay command. Syntax is 'sv_privatesay [playerId] [message]' or '/privatesay [playerId] [message]' in chat"
- changelog[#changelog+1] = "--Added temp.txt managing, basically so values that you set the previous map won't be erased when the next map loads (like when you do sv_respawn_time 5, and it goes back to default everytime you reload the script)"
- changelog[#changelog+1] = "--Added ipadminadding. You can add admins via IP now. Syntax is sv_ipadminadd (playerId) (nickname) (level) or /ipadminadd (playerId) (nickname) (level) in chat."
- changelog[#changelog+1] = "--Added: Now includes logging. This will log directly to commands.log in the log folder"
- changelog[#changelog+1] = "--Added: If you do not have an access file, this script will make one for you."
- changelog[#changelog+1] = "--Added '/e' command."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Modified /timelimit and sv_timelimit. It will change the ingame timelimit (time remaining) as well as the timelimit for every game after that. This still breaks with sv_reloadscripts."
- changelog[#changelog+1] = "--Modified sv_afk was changed to 'sv_setafk'. Thought it was a better name for the command."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Fixed /setname, it will change your name, but for others to see it it requires a rejoin."
- changelog[#changelog+1] = "--Fixed the admin system, before you had to do sv_reloadscripts after you added someone, that's been fixed."
- changelog[#changelog+1] = "--Fixed access.ini not syncing with chat commands, meaning if you have sv_kick in your access level, you can now use /k in the chat."
- changelog[#changelog+1] = "--Fixed a bug with /ammo, this now works correctly. Syntax is: /ammo [playerId] [type (1 or 2)] [ammo] or sv_setammo in console."
- changelog[#changelog+1] = "--Fixed smiley's BOS commands, thanks to bvigil for telling me what it was supposed to do."
- changelog[#changelog+1] = "--Fixed a bug with /tp and sv_teleport_pl, which were crashing when the other playerId was dead."
- changelog[#changelog+1] = "--Fixed /setplasmas, thank you sanity for the notice..."
- changelog[#changelog+1] = "--Fixed a reported bug with /noweapons... I was never able to reproduce it, so I must have indirectly fixed it."
- changelog[#changelog+1] = "--Fixed /info which would crash when you used a playerId expression that was not a number."
- changelog[#changelog+1] = "--Fixed a couple of bugs with rtv and votekick (whoops)"
- changelog[#changelog+1] = "--Fixed a bug with 'sv_mute' and '/mute'. You can no longer mute admins."
- changelog[#changelog+1] = "--Fixed /st. This will set a teleport location to wherever you are standing. Syntax is: /st [teleport name]"
- changelog[#changelog+1] = "--Fixed the spawngun. Syntax is /setmode (playerId) spawngun (object)"
- changelog[#changelog+1] = "--Fixed Smiley's BoS (Ban On Sight) system. I had to rewrite 80% of it to work with the new Phasor. It now also bans the person's IP."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Sorry this took so long, it took a while to rewrite the whole script. Technically it's been done for a while, i was just waiting for Oxide to release phasor 059. But that won't happen until after june, and there's no way i'm keeping you all waiting. Hope you enjoy it."
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 1.0"
- changelog[#changelog+1] = "First Official Release (January or something)"
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Script Created"
- file:write(concat(changelog, "\n"))
- file:close()
- end
- function tempBanPlayer(id, count, playerIndex)
- halo_svcmd("sv_ban " .. playerIndex .. " 1s")
- return false
- end
- local function addBan(player_name, player_hash, player_ip, ban_time, bantype, reason)
- local banid, ban_entry
- -- check if they've already been banned before
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if bantype == ban_entry.type then
- if player_hash and player_hash == ban_entry.hash then
- banid = id
- break
- elseif player_ip and ban_entry.ip and netMatch(ban_entry.ip, player_ip) then
- banid = id
- break
- end
- end
- end
- banid = banid or #ban_table+1
- ban_table[banid] = ban_table[banid] or TM.New()
- local bancount = (ban_table[banid].count or 0) + 1
- ban_table[banid].count = bancount
- ban_table[banid].name = player_name
- ban_table[banid].hash = player_hash
- ban_table[banid].ip = player_ip
- ban_table[banid].time = ban_time == -1 and -1 or ban_time > 0 and ban_time + os.time() or ban_penalty[bancount]
- ban_table[banid].type = bantype
- ban_table[banid].reason = reason
- updateBanFiles(bantype)
- end
- local function checkaccess(thisCommand, access)
- local allow = false
- local command_access = access_table[access]
- if command_access == -1 or command_access and command_access[thisCommand] then
- allow = true
- end
- return allow
- end
- -- This local function will only work if admins are organized by lowest level = highest admin.
- -- If lvl 5 is the most powerful admin and lvl 0 is the least powerful, this local function will not work.
- local function checkAdminBlockerAccess(executorPlayerId, playerId, access, type)
- access = access or getaccess(executorPlayerId)
- local player_access = getaccess(playerId)
- if player_access then
- if defaults.adminblocker == 1 and access > player_access then
- return false
- elseif defaults.adminblocker == 2 and access >= player_access then
- return false
- elseif defaults.adminblocker == 3 and access_table[access] == -1 then
- return false
- end
- end
- return true
- end
- local function Say(message)
- for i = 0,15 do
- if getplayer(i) then
- sendconsoletext(i, message)
- end
- end
- end
- local function capitalizeWords(str, amount)
- return gsub(str, '(%a)(%a+)', function(cap, rest) return ('%1'):upper() .. '%2' end)
- end
- capitalizeWords = memoize(capitalizeWords) -- memoized
- local function trim(str)
- return gsub(str, "^%s*(.-)%s*$", "%1")
- end
- trim = memoize(trim) -- memoized
- local function tokenizecmdstring(str, tblToReuse)
- local strParts = type(tblToReuse) == "table" and tblToReuse:deleteEntries() and tblToReuse or TM.New()
- --remove spaces at beginning and end
- str = trim(str) .. " "
- -- return if no delims found
- if not find(str, '[%s"]') then strParts[1] = str return strParts end
- local strPart, newPos, pos
- repeat
- strPart,newPos = match(str, '^"(.-)"%s+()', pos)
- if not strPart then
- strPart,newPos = match(str, '([^%s]+)%s+()', pos)
- end
- pos = newPos
- strParts[#strParts+1] = strPart
- until not strPart
- ::returnSplits::
- return strParts
- end
- --tokenizecmdstring = memoize(tokenizecmdstring) -- memoized
- local function tokenizestring(str, ...)
- local tblToReuse = select(-1, ...)
- tblToReuse = not tblToReuse and error("bad argument #2 to 'tokenizestring' delimeter string expected, got nil") or type(tblToReuse) == "table" and TM.deleteEntries(tblToReuse) and tblToReuse or nil
- local subs = type(tblToReuse) == "table" and tblToReuse or TM.New()
- if (...) == "" then
- for i = 1,#str do
- subs[#subs+1] = sub(str, i, i)
- end
- return subs
- end
- local strPart = ""
- local char, iter, delim
- for i = 1,#str do
- char = sub(str, i, i)
- iter = 1
- delim = select(iter, ...)
- repeat
- if delim == char then
- strPart = sub(strPart, 1, -1)
- if strPart ~= "" then
- subs[#subs+1] = strPart
- strPart = ""
- goto continue
- end
- end
- iter = iter + 1
- delim = select(iter, ...)
- until not delim or delim == select(-1, ...)
- strPart = strPart .. char
- ::continue::
- end
- if strPart ~= "" then
- subs[#subs+1] = strPart
- end
- return subs
- end
- --tokenizestring = memoize(tokenizestring) -- memoized
- function Commands.Create(cmdName, commandInfo, ...)
- -- Display errors if a command was created incorrectly.
- if not commandInfo.help then error("NO HELP INFO IN COMMAND CREATION") end
- local thisCmdFunc
- for i = 1,select("#", ...) do
- thisCmdFunc = select(i, ...)
- if not thisCmdFunc.arguments then error("NO ARGUMENTS IN COMMAND CREATION") end
- if not thisCmdFunc.arguments.minArgs then error("NO MINIMUM ARGUMENTS IN COMMAND CREATION") end
- if not thisCmdFunc.arguments.maxArgs then error("NO MAXIMUM ARGUMENTS IN COMMAND CREATION") end
- if type(thisCmdFunc.func) ~= "function" then error("BAD FUNCTION IN COMMAND CREATION: " .. type(thisCmdFunc.func)) end
- end
- --stupid tabs...
- commandInfo.help = gsub(commandInfo.help, "\t", "")
- -- Create this command with properties from the Commands class.
- local newCommand = {name = cmdName, commandInfo, ...}
- setmetatable(newCommand, Commands)
- -- set command aliases
- local aliases = commandInfo.aliases
- if aliases then
- local commandAliases = Commands.commandAliases
- local alias_name
- for i = 1,#aliases do alias_name = aliases[i]
- commandAliases[alias_name] = cmdName
- Commands[alias_name] = newCommand
- end
- end
- -- Add this command to the Command list.
- Commands[cmdName] = newCommand
- Commands[#Commands+1] = cmdName
- end
- function Commands.Execute(thisCommand, arguments, command, executorPlayerId)
- local parsedArguments, newErr
- local err = ""
- -- Loop through all overloaded functions for this command.
- for i = 2,#thisCommand do
- -- Validate and parse all arguments
- parsedArguments, newErr = thisCommand:validateArguments(arguments, thisCommand[i].arguments, command, executorPlayerId)
- -- have they passed the correct arguments for this overloaded command?
- if parsedArguments == true then
- sendresponse(newErr, executorPlayerId)
- goto endCommand
- elseif newErr == "" then
- -- call the command, and stop looping.
- thisCommand[i].func(executorPlayerId, thisCommand:unpackArguments(parsedArguments))
- goto endCommand
- else
- err = err .. "\n" .. newErr
- end
- end
- sendresponse(err .. gsub(thisCommand[1].help, ".-Syntax: %%s(.-)", "\nInvalid Syntax: " .. command .. "%1"), executorPlayerId)
- ::endCommand::
- end
- -- Needed because I need to pass a specific amount of arguments to command functions.
- function Commands:unpackArguments(myTable)
- for i = 1,#myTable do
- if myTable[i] == nil then
- myTable[i] = false
- end
- end
- return table.unpack(myTable, 1, #myTable)
- end
- -- Validates and parses an argument table --
- function Commands:validateArguments(arguments, argumentTypes, command, executorPlayerId)
- local err = ""
- local minArgs, maxArgs = argumentTypes.minArgs, argumentTypes.maxArgs
- -- Make sure they are actually passing a second argument.
- if not arguments[1] and minArgs > 0 then
- return true, gsub(self[1].help, "^.-Syntax:.-%%s(.-)$", "\nCorrect Syntax: " .. command .. "%1")
- end
- local argument, argType, length
- local parsedArguments = TM.New()
- for i = 1,#argumentTypes do argument = arguments[i]
- argType = argumentTypes[i]
- if not argument then
- if #parsedArguments < minArgs then
- err = err .. "\nToo few arguments passed to this command! Expected " .. minArgs .. " - " .. maxArgs .. " got " .. #parsedArguments
- goto ReturnArgs
- end
- else
- length = #argument
- end
- if argType == "Boolean" then
- if argument == "true" or argument == "1" then
- argument = true
- elseif argument == "false" or argument == "0" then
- argument = false
- elseif arguments[i] then
- err = err .. "\n'" .. arguments[i] .. "' is not a valid Boolean!\nBooleans must be: true or 1 to Enable/Turn On, false or 0 to Disable/Turn Off"
- end
- elseif argType == "Percent" then
- argument = tonumber(argument)
- argument = argument and (argument <= 1 and argument >= 0 and argument * 100 or argument <= 100 and argument)
- err = not argument and "Invalid Percentage. Percent arguments must be between 0 and 100." or err
- elseif argType == "Player" then
- local players = getvalidplayers(argument, executorPlayerId)
- if players then
- argument = players
- elseif argument == nil and #arguments >= minArgs and executorPlayerId then
- argument = TM{executorPlayerId}
- elseif not argument then
- err = err .. "\nYou did not specify a player!"
- else
- err = err .. "\n'" .. arguments[i] .. "' is not a valid Player!"
- end
- elseif argType == "Single Player" then
- local players = getvalidplayers(argument, executorPlayerId)
- if players then
- argument = players[1]
- err = players[2] and err .. "\n'" .. argument[i] .. "' cannot reference more than one player in this command!" or err
- elseif argument == nil and #arguments >= minArgs and executorPlayerId then
- argument = executorPlayerId
- elseif not argument then
- err = err .. "\nYou did not specify a player!"
- else
- err = err .. "\n'" .. arguments[i] .. "' is not a valid player!"
- end
- elseif argType == "Hash" then
- argument = match(argument, "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+")
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid Hash!" or err
- elseif argType == "IP Address" then
- argument = validate_ipv4(argument)
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid IP Address!" or err
- elseif argType == "Team" then
- argument = team_play and ("Red" and 0 or "Blue" and 1) or tonumber(argument)
- argument = argument and argument >= 0 and argument <= 15 and argument
- err = not argument and "The '" .. arguments[i] .. "' team does not exist!" or err
- elseif argType == "Time And Reason" then
- argument, parsedArguments[i+1] = getTimeAndReason(concat(arguments, " ", i), self.usesBanCounts and (player_table[parsedArguments[i-1]].bancount or 0) or nil)
- elseif argType == "Time" then
- local temp
- argument, temp = getTimeAndReason(concat(arguments, " ", i), self.usesBanCounts and (player_table[parsedArguments[i-1]].bancount or 0) or nil)
- err = temp ~= "None Given" and err .. "\n'" .. concat(arguments, " ", i) .. "' is an Incorrect Time!\nCorrect Examples: 5d 2h 3m 4s" or err
- elseif argType == "Time String" then
- local timeErr = not argument and "'" .. argument .. "' is an Incorrect Time!\nCorrect Examples: 5d 2h 3m 4s"
- if timeErr then goto TimeStringEnd end
- for j = i+1,#arguments do
- timeErr = not arguments[j] and "'" .. arguments[j] .. "' is an Incorrect Time!\nCorrect Examples: 5d 2h 3m 4s"
- if timeErr then break end
- argument = argument .. " " .. arguments[j]
- end
- ::TimeStringEnd::
- err = timeErr and err .. "\n" .. timeErr or err
- elseif argType == "Remaining Arguments" then
- argument = concat(arguments, " ", i)
- elseif argType == "Access Level" then
- argument = tonumber(argument)
- argument = argument and access_table[argument] and argument
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid Access Level.\nUse 'sv_access_levels' for available levels!" or err
- elseif argType == "Whole Number" then
- argument = tonumber(argument)
- argument = argument and argument >= 0 and argument
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a Whole (Non-Negative) Number!" or err
- elseif argType == "Positive Number" then
- argument = tonumber(argument)
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a Positive Number!" or err
- elseif argType == "Number" then
- argument = tonumber(argument)
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a Number!" or err
- elseif argType == "Password" then
- argument = length and length >= 4 and length <= 8 and argument
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a Password between 4 and 8 characters!" or err
- elseif argType == "Map" then
- argument = valid_maps[argument] and argument
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid Map!" or err
- elseif argType == "Gametype" then
- argument = valid_gametypes[argument] and argument
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid GameType!" or err
- elseif argType == "String" then
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid argument for this command!" or err
- elseif argType == "AdminBlocker Type" then
- argument = tonumber(argument) or argument
- argument = (argument == 0 or argument == "Unsafe") and 0 or (argument == 1 or argument == "Lenient") and 1 or (argument == 2 or argument == "Moderate") and 2 or (argument == 3 or argument == "Strict") and 3
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid AdminBlocker Type!" or err
- elseif argType == "Datatype" then
- argument = (argument == "bit8" or argument == "bit16" or argument == "bit32" or argument == "char" or argument == "byte" or argument == "short" or argument == "word" or argument == "int" or argument == "dword" or argument == "float" or argument == "string" or argument == "widestring") and argument
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid DataType!" or err
- elseif argType == "Struct" then
- argument = (argument == "player" or argument == "object" or argument == "weapon" or argument == "vehicle") and argument
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid Struct!" or err
- elseif argType == "Bit" then
- if argument == "true" or argument == "1" then
- argument = 1
- elseif argument == "false" or argument == "0" then
- argument = 0
- else
- err = err .. "\n'" .. arguments[i] .. "' is not a valid Bit!\nBits must be one of the following: true or 1, false or 0"
- end
- end
- parsedArguments[i] = argument
- end
- if #parsedArguments > maxArgs and #arguments > maxArgs then
- err = err .. "\nToo many Arguments passed to this command! Expected " .. minArgs .. " - " .. maxArgs .. " got " .. #parsedArguments
- end
- ::ReturnArgs::
- return parsedArguments, err
- end
- function Commands:AliasToCommand(cmd)
- return self.realname
- end
- -- Script Validation
- function Commands:validscripts(...)
- end
- Commands.Create(
- "rconadd",
- {
- aliases = {"addrcon"},
- help = [[-- Add Rcon Password
- -- Syntax: %s [Password] {Level}
- -- Adds a global Rcon password to the list.
- -- These RCon passwords are different from the normal sv_rcon_password
- -- The difference is non-admins can use these, while sv_rcon_password only admins can use]]
- },
- {
- arguments = {"Password", "Access Level", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, password, level)
- if rcon_passwords[password] then
- sendresponse(password .. " is already a rcon password", executorPlayerId)
- return
- end
- rcon_passwords[password] = level or 0
- sendresponse(password .. " has been added as a rcon password", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "adminadd",
- {
- aliases = {"a", "addadmin"},
- help = [[-- Admin Add
- -- Syntax: %s [Player or Hash or IP Address] [Nickname] {Level} {Admin Type 'Hash' or 'IP'}
- -- Adds a person to the admin list.
- -- This command can take a Hash, IP, or Player as an argument.
- -- If you do not pass a level, they will automatically be added as a level 0 admin.
- -- The default for Admin Type is 'hash'. This argument is also case insensitive.]]
- },
- {
- arguments = {"Single Player", "String", "Access Level", "String", minArgs = 2, maxArgs = 4},
- func = function(executorPlayerId, playerId, nickname, level, admin_type)
- admin_type = admin_type and lower(admin_type) or "hash"
- if admin_type ~= "hash" and admin_type ~= "ip" then
- sendresponse("'" .. admin_type .. "' is not a valid Admin Type!", executorPlayerId)
- return
- end
- if not match(nickname, "[%l%u]+") then
- sendresponse("Admin nicknames must only contain letters.", executorPlayerId)
- return
- end
- if player_table[playerId].admin_entry then
- sendresponse(getname(playerId) .. " is already a " .. admin_type .. " admin", executorPlayerId)
- return
- end
- -- Create a new admin entry
- local newAdmin = TM.New()
- newAdmin.name = nickname
- newAdmin.level = level or 0
- newAdmin.type = admin_type
- -- Add the admin entry to the admin table.
- admin_table[admin_type == "hash" and gethash(playerId) or (getip(playerId) .. "/24")] = newAdmin
- player_table[playerId].admin_entry = newAdmin
- updateAdminFiles()
- sendresponse(getname(playerId) .. " is now a " .. admin_type .. " admin!", executorPlayerId)
- end
- },
- {
- arguments = {"Hash", "String", "Access Level", minArgs = 2, maxArgs = 3},
- func = function(executorPlayerId, hash, nickname, level)
- if not match(nickname, "%l+") then
- sendresponse("Admin nicknames must only contain letters.", executorPlayerId)
- return
- end
- for i = 1,#sharedhashes do
- if hash == sharedhashes[i] then
- sendresponse("This is a shared hash, and therefore cannot become an admin.", executorPlayerId)
- return
- end
- end
- if admin_table[hash] then
- sendresponse("That Hash is already an admin.", executorPlayerId)
- return
- end
- -- Create a new admin entry
- local newAdmin = TM.New()
- newAdmin.name = nickname
- newAdmin.level = level or 0
- newAdmin.type = "hash"
- -- Add the admin entry to the admin table.
- admin_table[hash] = newAdmin
- for i = 0,15 do
- if gethash(i) == hash then
- player_table[i].admin_entry = newAdmin
- end
- end
- updateAdminFiles()
- sendresponse("That hash has been successfully added to the admin list.", executorPlayerId)
- end
- },
- {
- arguments = {"IP Address", "String", "Access Level", minArgs = 2, maxArgs = 3},
- func = function(executorPlayerId, ip_address, nickname, level)
- if not match(nickname, "%l+") then
- sendresponse("Admin nicknames must only contain letters.", executorPlayerId)
- return
- end
- for index,thisAdmin in next,admin_table do
- if thisAdmin.type == "ip" and netMatch(index, ip_address) then
- sendresponse("That IP Address is already an admin.", executorPlayerId)
- return
- end
- end
- -- Create a new admin entry
- local newAdmin = TM.New()
- newAdmin.name = nickname
- newAdmin.level = level or 0
- newAdmin.type = "ip"
- -- Add the admin entry to the admin table.
- admin_table[ip_address] = newAdmin
- for i = 0,15 do
- if getplayer(i) then
- if netMatch(ip_address, getip(i)) then
- player_table[i].admin_entry = newAdmin
- end
- end
- end
- updateAdminFiles()
- sendresponse("That IP Address has been successfully added to the admin list.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "admindel",
- {
- aliases = {"deladmin", "revoke", "a del", "adminrevoke", "revokeadmin"},
- help = [[-- Admin Delete
- -- Syntax: %s [Player or Admin Nickname]
- -- Removes an admin from the admin list by index number.
- -- Use 'sv_admin_list' to get a list of admins for their index.
- -- You can also pass a player to this command.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, ip
- for i = 1,#players do playerId = players[i]
- if not player_table[playerId].admin_entry then
- cmdreply[cmdreply()] = getname(playerId) .. " was never an admin"
- goto continue
- end
- admin_table[gethash(playerId)] = nil
- for index,thisAdmin in next,admin_table do
- if thisAdmin.type == "ip" and netMatch(index, ip) then
- admin_table[index] = nil
- end
- end
- player_table[playerId].admin_entry = nil
- updateAdminFiles()
- cmdreply[cmdreply()] = getname(playerId) .. " is no longer an admin"
- ::continue::
- end
- sendresponse(cmdreply, playerId)
- end
- },
- {
- arguments = {"String", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, nickname)
- if not next(admin_table) then
- sendresponse("There are no admins on this server.", executorPlayerId)
- return
- end
- for k,thisAdmin in next,admin_table do
- if thisAdmin.name == nickname then
- admin_table[k] = nil
- sendresponse(nickname .. " is no longer an admin", executorPlayerId)
- updateAdminFiles()
- for i = 0,15 do
- if player_table[i].admin_entry == thisAdmin then
- player_table[i].admin_entry = nil
- end
- end
- return
- end
- end
- sendresponse("There are no admins with a nickname of '" .. nickname .. "'", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setafk",
- {
- aliases = {"afk"},
- help = [[-- Set AFK Player
- -- Syntax: %s [Player]
- -- Sets the specified player to the AFK status.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- player_table[playerId].afk = true
- cmdreply[cmdreply()] = getname(playerId) .. " is now afk"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "adminlist",
- {
- aliases = {"admins", "listadmins", "alist"},
- help = [[-- Admin List
- -- Syntax: %s {Type}
- -- Shows a list of all Admins
- -- Type can be either 'IP', 'Hash', or 'Temp' for filtering.]]
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, admin_type)
- cmdreply.header = "[Name | Level | Admin Type]"
- cmdreply.align = true
- cmdreply.delim = "|"
- local hash_admin, ip_admin
- for index,thisAdmin in next,admin_table do
- cmdreply[cmdreply()] = thisAdmin.name .. " | " .. thisAdmin.level .. " | " .. thisAdmin.type .. " Admin"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "alias",
- {
- help = [[-- Alias
- -- Syntax: %s [player]
- -- Shows all names used with the hash]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- halo_svcmdplayer("sv_alias_hash " .. resolveplayer(playerId), executorPlayerId)
- end
- end
- }
- )
- -- whatever local function that calls this one will set the reference of 'boolCheck' to whatever newBool is, or will do nothing if newBool is nil.
- local function ReturnScriptBooleanCheck(boolName, boolCheck, argBool)
- local are_is = sub(boolName, -1, -1) == "s" and "are" or "is" -- lol
- if argBool == nil then
- return nil, boolName .. " is currently " .. (boolCheck == true and "On" or boolCheck == false and "Off" or tostring(boolCheck))
- end
- local response
- if argBool then
- if not boolCheck then
- response = boolName .. " " .. are_is .. " now on"
- else
- argBool = nil
- response = "(*) " .. boolName .. " " .. are_is .. " already enabled"
- end
- elseif not argBool then
- if boolCheck then
- response = boolName .. " " .. are_is .. " now off"
- else
- argBool = nil
- response = "(*) " .. boolName .. " " .. are_is .. " already off"
- end
- end
- return argBool, response
- end
- -- Scripted Game Boolean Commands
- Commands.Create(
- "anticaps",
- {
- aliases = {"disablecaps", "nocaps"},
- help = [[-- AntiCaps
- -- Syntax: %s {Boolean}
- -- Enables or Disables the use of caps in the server]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Anticaps", defaults.anticaps, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.anticaps = newBool
- end
- end
- }
- )
- Commands.Create(
- "chatcommands",
- {
- help = [[-- ChatCommands
- -- Syntax: %s {Boolean}
- -- Enable/Disable Chat Commands for Admins]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Chat Commands", defaults.chatcommands, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.chatcommands = newBool
- end
- end
- }
- )
- Commands.Create(
- "chatids",
- {
- aliases = {"chatid", "showplayernumbers"},
- help = [[-- Show Player IDs In Chat
- -- Syntax: %s {Boolean}
- -- Enable/Disable the showing of Player IDs in the chat.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Chat IDs", defaults.chatids, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.chatids = newBool
- end
- end
- }
- )
- Commands.Create(
- "crouchcamo",
- {
- aliases = {"tigermode", "ninja", "ninjamode"},
- help = [[--Enable or Disable Crouch Camo
- -- Syntax: %s {Boolean}
- -- Enables or Disables the use of crouch camo]],
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, players, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Crouch Camo", defaults.crouch_camo, strBool)
- if newBool ~= nil then
- defaults.crouch_camo = newBool
- end
- sendresponse(response)
- end
- }
- )
- Commands.Create(
- "uniquesenabled",
- {
- aliases = {"uniqueplayercounting"},
- help = [[-- Unique Player Counting
- -- Syntax: %s {Boolean}
- -- Enables/Disables the Unique Player Counting feature.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Unique Player Counting", defaults.uniques_enabled, strBool)
- sendresponse(response, executorPlayerId)
- if newBool then
- local file = io.open(profilepath .. "uniques.txt")
- if not file then
- return
- end
- local index,ip,joincount,names
- for line in file:lines() do
- -- ignore blank lines
- if match(line, "%g%g%g+") then
- unique_table.total = unique_table.total + 1
- index,joincount,names = match(line, "^(.+),(%d+),(.-)$")
- if index then
- names = tokenizestring(names, ",")
- unique_table[index] = TM{joincount = joincount, names = names}
- else
- names,index,ip = match(line, "^(.-),(%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+),(.-)$")
- if names and validate_ipv4(ip) then
- joincount = 1
- unique_table[ip] = TM{joincount = 1, names = TM{names}}
- unique_table[match(ip, "%d+%.%d+%.%d+%.")] = TM{joincount = 1, names = TM{names}}
- end
- end
- end
- end
- file:close()
- elseif newBool ~= nil then
- defaults.uniques_enabled = false
- end
- end
- }
- )
- Commands.Create(
- "deathless",
- {
- aliases = {"deathlessplayer", "deathlessmode", "cheatdeathlessplayer"},
- scrimBlock = true,
- help = [[-- Deathless Players
- -- Syntax: %s {Boolean}
- -- Enables/Disables the Deathless Players mode.
- -- Players cannot die while this mode is enabled (obviously).
- -- The default for this command is (obviously) Off]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Deathless Player", defaults.deathless, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.deathless = newBool
- end
- end
- }
- )
- Commands.Create(
- "falldamage",
- {
- scrimBlock = true,
- help = [[-- Fall Damage
- -- Syntax: %s [Boolean]
- -- Enable/Disable the damage players receive from falling.
- -- The default for this command is: Enabled]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Falldamage", defaults.falldamage, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.falldamage = newBool
- end
- end
- }
- )
- Commands.Create(
- "firstjoinmessage",
- {
- help = [[-- First Join Message
- -- Syntax: %s [Boolean]
- -- Enable/Disable the First Join Message.
- -- The default for this command is: Enabled.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("First Join Message", defaults.firstjoin_message, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.firstjoin_message = newBool
- end
- end
- }
- )
- Commands.Create(
- "hashduplicates",
- {
- help = [[-- Hash Duplicate Checking
- -- Syntax: %s {Boolean}
- -- Allows/Deny's multiple players with the same hash to join the server
- -- The default for this command is: Enabled.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Hash Duplicate Checking", defaults.hash_duplicates, strBool)
- sendresponse(response, executorPlayerId)
- if newBool then
- writebit(addresses.hash_duplicate_patch, 0, 0)
- defaults.hash_duplicates = true
- elseif newBool ~= nil then
- writebit(addresses.hash_duplicate_patch, 0, 1)
- defaults.hash_duplicates = false
- end
- end
- }
- )
- Commands.Create(
- "infiniteammo",
- {
- aliases = {"infammo"},
- scrimBlock = true,
- help = [[-- Infinite Ammo
- -- Syntax: %s [Boolean]
- -- Enable or disable infinite ammo"]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Infinite Ammo", defaults.infinite_ammo, strBool)
- sendresponse(response, executorPlayerId)
- if newBool then
- defaults.infinite_ammo = true
- local ptable, m_weaponObj, weaponObjId
- infammo_timer = registertimer(500, "playerWeaponCheckTimer")
- for playerId = 0,15 do
- if not getplayer(playerId) then
- goto continue
- end
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- goto continue
- end
- ptable = player_table[playerId]
- local m_weaponObj, weaponObjId
- for slot = 1,4 do
- weaponObjId = ptable.weapons[slot]
- m_weaponObj = getobject(weaponObjId)
- if m_weaponObj then
- writeshort(m_weaponObj + 0x2B6, 0x7CFF)
- writeshort(m_weaponObj + 0x2B8, 0x7CFF)
- updateammo(weaponObjId)
- ptable.weapons = weaponObjId
- end
- end
- ::continue::
- end
- elseif newBool ~= nil then
- local m_playerObj, m_weaponObj, weaponObjId, mapId, tag_address, tag_data_address, address_magazines, rounds_total_initial, rounds_loaded_maximum
- for i = 0,15 do
- m_playerObj = getplayerobject(i)
- if not m_playerObj then
- goto continue
- end
- for x = 1,4 do
- m_weaponObj, weaponObjId = getplayerweapon(i, x)
- if not m_weaponObj then
- goto continue2
- end
- mapId = readdword(m_weaponObj)
- tag_address = gettagaddress(mapId)
- tag_data_address = readdword(tag_address + 0x14)
- address_magazines = readdword(tag_data_address + 0x4F0 + 0x4)
- rounds_total_initial = readshort(address_magazines + 0x8)
- rounds_loaded_maximum = readshort(address_magazines + 0xA)
- writeshort(m_weaponObj + 0x2B6, rounds_total_initial or 0)
- writeshort(m_weaponObj + 0x2B8, rounds_loaded_maximum or 0)
- updateammo(weaponObjId)
- ::continue2::
- end
- ::continue::
- end
- if infammo_timer then removetimer(infammo_timer) end
- defaults.infinite_ammo = false
- end
- end
- }
- )
- Commands.Create(
- "killspree",
- {
- aliases = {"killingspree"},
- help = [[-- Killing Spree Detection
- -- Syntax: %s [Boolean]
- -- Enable/Disable Killing Spree Notifications]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Killing Spree Notifications", defaults.killing_spree, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.killing_spree = newBool
- end
- end
- }
- )
- Commands.Create(
- "multiteamvehicles",
- {
- help = [[-- Multi Team Vehicles
- -- Syntax: %s {Boolean}
- -- Allows/Deny's players to enter enemy vehicles.
- -- Note: This command only works on Free-For-All GameTypes.
- -- The default for this command is: Disabled.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Multi-Team Vehicles", defaults.multiteam_vehicles, strBool)
- sendresponse(response, executorPlayerId)
- if newBool then
- local m_player
- for i = 0,15 do
- m_player = getplayer(i)
- if m_player then
- writebyte(m_player + 0x20, 0)
- end
- end
- defaults.multiteam_vehicles = true
- elseif newBool ~= nil then
- local m_player
- for i = 0,15 do
- m_player = getplayer(i)
- if m_player then
- writebyte(m_player + 0x20, readbyte(m_player + 0x66))
- end
- end
- defaults.multiteam_vehicles = false
- end
- end
- }
- )
- Commands.Create(
- "noweapons",
- {
- help = [[-- No Weapons
- -- Syntax: %s {Boolean}
- -- Enables/Disables the use of weapons in a server.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("No-Weapons mode", defaults.noweapons, strBool)
- sendresponse(response, executorPlayerId)
- if newBool then
- local m_playerObj, m_weaponObj, weaponObjId
- for playerId = 0,15 do
- m_playerObj = getplayerobject(playerId)
- if m_playerObj then
- for j = 1,4 do
- m_weaponObj, weaponObjId = getplayerweapon(playerId, j)
- if m_weaponObj then
- destroyobject(weaponObjId)
- end
- end
- end
- end
- defaults.noweapons = true
- elseif newBool ~= nil then
- for playerId = 0,15 do
- if getplayer(playerId) then
- resetweapons(playerId)
- end
- end
- defaults.noweapons = false
- end
- end
- }
- )
- Commands.Create(
- "pmenabled",
- {
- aliases = {"pvtmessage", "privatemessage"},
- help = [[-- Private Messaging
- -- Syntax: %s {Boolean}
- -- Enable/Disable Private Messaging
- -- To use private messaging, type @(playerIndex) (message) in the chat, without the ( )]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Private Messaging", defaults.pm_enabled, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.pm_enabled = newBool
- end
- end
- }
- )
- Commands.Create(
- "rtvenabled",
- {
- help = [[-- RockTheVote
- -- Syntax: %s {Boolean}
- -- Enables or disables the use of RockTheVote in the server
- -- To initiate a rtv, type 'skip' or 'rtv' in the chat.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("RockTheVote", defaults.rtv_enabled, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.rtv_enabled = newBool
- end
- end
- }
- )
- Commands.Create(
- "serveradminmessage",
- {
- aliases = {"samessage"},
- help = [[-- Server Admin Message
- -- Syntax: %s {Boolean}
- -- Enable/Disable Server Admin join notification.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Server Admin Message", defaults.sa_message, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.sa_message = newBool
- end
- end
- }
- )
- Commands.Create(
- "scrimmode",
- {
- help = [[-- Scrim mode
- -- Syntax: %s {Boolean}
- -- Enables/Disables Scrim Mode
- -- This mode will disable certain commands, so people can't cheat during scrims.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Scrim mode", defaults.scrim_mode, strBool)
- sendresponse(response, executorPlayerId)
- if newBool then
- for i = 0,15 do
- ResetPlayer(i)
- end
- controllers:deleteEntries()
- slaving:deleteEntries()
- defaults.falldamage = true
- defaults.deathless = false
- defaults.infinite_ammo = false
- defaults.scrim_mode = true
- elseif newBool ~= nil then
- defaults.scrim_mode = false
- end
- end
- }
- )
- Commands.Create(
- "tbagdet",
- {
- aliases = {"tbagdetection"},
- help = [[-- Tbag Detection
- -- Syntax: %s [Boolean]
- -- Enable/Disable Tbag announcement]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Tbag Detection", defaults.tbag_detection, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.tbag_detection = newBool
- end
- end
- }
- )
- Commands.Create(
- "votekickenabled",
- {
- help = [[-- VoteKick
- -- Syntax: %s [Boolean]
- -- Enables/Disables the use of VoteKick in a server
- -- Once enabled, people can type 'votekick [player]' in the chat to start a votekick on that player.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("VoteKick", defaults.votekick_enabled, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.votekick_enabled = newBool
- end
- end
- }
- )
- Commands.Create(
- "defaultspawnweapons",
- {
- aliases = {"spawnweapons", "weaponsonspawn", "chooseweapons", "selectweapons", "poontang"},
- help = [[-- Choose Default Spawn Weapons
- -- Syntax: %s {Primary Weapon} {Secondary Weapon} {Tertiary Weapon} {Quaternary Weapon}
- -- Will allow you to change the default]]
- },
- {
- arguments = {"Object", "Object", "Object", "Object", minArgs = 0, maxArgs = 4},
- func = function(executorPlayerId, primary_weap_tagname, secondary_weap_tagname, tertiary_weap_tagname, quaternary_weap_tagname)
- if primary_weap_tagname then
- spawnWeapons[1] = primary_weap_tagname
- spawnWeapons[2] = secondary_weap_tagname
- spawnWeapons[3] = tertiary_weap_tagname
- spawnWeapons[4] = quaternary_weap_tagname
- else
- sendresponse("The current default spawn weapons are displayed below", executorPlayerId)
- local weap
- for i = 1,4 do weap = spawnWeapons[i]
- if weap then
- sendresponse("Spawn Weapon #" .. i .. ": " .. weap)
- end
- end
- end
- end
- }
- )
- Commands.Create(
- "welcomebackmessage",
- {
- aliases = {"wbmessage"},
- help = [[-- Welcome Back Message
- -- Syntax: %s [boolean]
- -- Enable/Disable Welcome Back Message]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Welcome Back Message", defaults.wb_message, strBool)
- sendresponse(response, executorPlayerId)
- if newBool ~= nil then
- defaults.wb_message = newBool
- end
- end
- }
- )
- -- Scripted Game non-boolean Commands
- Commands.Create(
- "adminblocker",
- {
- help = [[-- Admin Blocker
- -- Syntax: %s {type}
- -- Enables, disables or limits the abiliy of an admin to kick/ban ]]
- },
- {
- arguments = {"AdminBlocker Type", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, abtype)
- if abtype > 3 then
- sendresponse([[Invalid AdminBlocker Type!
- Type 0: Admins can kick/ban another admin.
- Type 1: Admins can't kick/ban other admins with higher level.
- Type 2: Admins can't kick/ban other admins with higher or equal level.
- Type 3: Admins can't kick/ban other admins unless they can do all commands.]], executorPlayerId)
- return
- end
- if abtype == 0 then
- defaults.adminblocker = "Unsafe"
- sendresponse("Admins now can kick/ban other admins", executorPlayerId)
- elseif abtype == 1 then
- defaults.adminblocker = "Lenient"
- sendresponse("Admins now cannot kick/ban other admins with higher levels.", executorPlayerId)
- elseif abtype == 2 then
- defaults.adminblocker = "Moderate"
- sendresponse("Admins now cannot kick/ban other admins with higher or equal levels.", executorPlayerId)
- elseif abtype == 3 then
- defaults.adminblocker = "Strict"
- sendresponse("Admins now cannot kick/ban other admins unless they can do all commands.", executorPlayerId)
- elseif defaults.adminblocker == "Unsafe" then
- sendresponse("Admins currently can kick/ban other admins", executorPlayerId)
- elseif defaults.adminblocker == "Lenient" then
- sendresponse("Admins currently cannot kick/ban other admins with higher levels.", executorPlayerId)
- elseif defaults.adminblocker == "Moderate" then
- sendresponse("Admins currently cannot kick/ban other admins with higher or equal levels.", executorPlayerId)
- elseif defaults.adminblocker == "Strict" then
- sendresponse("Admins currently cannot kick/ban another admins unless they have full access.", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "antispam",
- {
- help = [[-- AntiSpam
- -- Syntax: %s {all | players | off}
- -- All = All Players cannot spam in the chat.
- -- Players = All Players EXCEPT Admins cannot spam in the chat.
- -- Off = Disables AntiSpam functionality]]
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, mode)
- if mode ~= "all" and mode ~= "players" and mode ~= "off" then
- sendresponse("Invalid mode. Valid modes are 'all', 'players' and 'off'", executorPlayerId)
- return
- end
- if mode then
- defaults.antispam = mode
- sendresponse("AntiSpam now set to " .. defaults.antispam, executorPlayerId)
- else
- sendresponse("AntiSpam is set to " .. defaults.antispam, executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "balance",
- {
- help = [[-- Balance Teams
- -- Syntax: %s
- -- Balances the number of players on each team.
- -- This command can ONLY be executed on Teamplay GameTypes like CTF.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- if not team_play then
- sendresponse("This command is disabled since it is not a team based game.", executorPlayerId)
- return
- end
- local msg = "Balancing Teams"
- local redsize = getteamsize(0)
- local bluesize = getteamsize(1)
- if bluesize > redsize and cur_players % 2 ~= 1 then
- changeteam(SelectRandomPlayer(1), true)
- elseif bluesize < redsize and cur_players % 2 ~= 1 then
- changeteam(SelectRandomPlayer(0), true)
- else
- msg = "Teams are balanced."
- end
- say(msg)
- sendresponse("The teams have now been balanced", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "banpenalty",
- {
- help = [[-- Ban Penalty
- -- Syntax: %s {1st Bantime} {2nd Bantime} {3rd Bantime} etc..
- -- Determines how much time a player can be banned when the time argument '0' is used in a ban command.]]
- },
- {
- arguments = {"Time String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, times)
- if not times then
- for i = 1,#ban_penalty do
- cmdreply[cmdreply()] = "Ban Penalty #" .. i .. ": " .. ban_penalty[i]
- end
- sendresponse(cmdreply, executorPlayerId)
- else
- local i = 1
- local length = #ban_penalty
- for time in string.gmatch(times, "%d+[cywdhms]") do time = wordtotime(time)
- ban_penalty[i] = time
- i = i + 1
- end
- while length >= i do
- ban_penalty[i] = nil
- i = i + 1
- end
- sendresponse("The Ban Penalties have been changed to: " .. times, executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "ban",
- {
- aliases = {"hashban", "b", "playerban", "banplayer"},
- usesBanCounts = true,
- help = [[-- Ban
- -- Syntax: %s [Player, Hash, or IP Address] {Time} {Reason}
- -- Bans the Player/Hash/IP Address from the server with a reason written to the BanReasons log file]]
- },
- {
- arguments = {"Player", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, players, time, reason)
- local exname = executorPlayerId and getname(executorPlayerId) or "the Server"
- local playerId, name, hash
- for i = 1,#players do playerId = players[i]
- name = getname(playerId)
- if not checkAdminBlockerAccess(executorPlayerId, playerId) then
- sendresponse("You cannot use this command on " .. name, executorPlayerId)
- privatesay(playerId, exname .. " attemped to use Ban on you!")
- goto continue
- end
- hash = gethash(playerId)
- for i = 1,#sharedhashes do
- if hash == sharedhashes[i] then
- cmdreply[cmdreply()] = name .. " has a shared hash, and therefore cannot be hashbanned. Try an IP Ban instead."
- goto continue
- end
- end
- addBan(name, gethash(playerId), nil, time, "hash", reason)
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", name .. " was banned by " .. exname .. " Reason: " .. reason .. " Type: Hash Ban")
- say(name .. " has been banned by " .. exname .. " Reason: " .. reason)
- cmdreply[cmdreply()] = name .. " has been banned from the server"
- registertimer(0, "tempBanPlayer", resolveplayer(playerId))
- updateBanFiles()
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- },
- {
- arguments = {"Hash", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, hash, time, reason)
- local exname = executorPlayerId and getname(executorPlayerId) or "the Server"
- for i = 1,#sharedhashes do
- if hash == sharedhashes[i] then
- sendresponse("That is a shared hash, and therefore cannot be hashbanned. Try an IP Ban instead.", executorPlayerId)
- return
- end
- end
- -- Check if a person in this server has this hash.
- for i = 0,15 do
- if getplayer(i) and gethash(i) == hash then
- registertimer(0, "tempBanPlayer", resolveplayer(playerId))
- end
- end
- addBan("manual_ban" .. #ban_table, hash, nil, time, "hash", reason)
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", "Hash '" .. hash .. "' was banned by " .. exname .. " Reason: " .. reason .. " Type: Hash Ban")
- updateBanFiles()
- sendresponse("That hash has been banned from the server successfully", executorPlayerId)
- end
- },
- {
- arguments = {"IP Address", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, ip_address, time, reason)
- local exname = executorPlayerId and getname(executorPlayerId) or "the Server"
- -- Check if a person in this server has this IP Address.
- for i = 0,15 do
- if getplayer(i) and netMatch(ip_address, getip(i)) then
- registertimer(0, "tempBanPlayer", resolveplayer(playerId))
- end
- end
- addBan("manual_ban" .. #ban_table, nil, ip_address, time, "ip", reason)
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", "IP Address '" .. ip_address .. "' was banned by " .. exname .. " Reason: " .. reason .. " Type: IP Ban")
- updateBanFiles()
- sendresponse("That IP Address has been banned from the server successfully", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "bos",
- {
- help = [[Ban on Sight
- -- Syntax: %s [Bosplayer Index]
- -- Add the specified player to the Ban On Sight (BOS) list.
- -- The next time this person joins the server, they will be banned.
- -- This command explicitly requires a number for an index.
- -- This index must be the player index of a player who has left the server.
- -- Use 'sv_bosplayers' to get a list of players to add to the BOS list.]]
- },
- {
- arguments = {"String", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, playerId)
- local leave_entry = leave_table[playerId]
- if not leave_entry then
- sendresponse("Invalid Player", executorPlayerId)
- return
- end
- local found, bos_entry
- for i = 1,#bos_table do bos_entry = bos_table[i]
- if leave_entry.hash == bos_entry.hash or leave_entry.ip == bos_entry.ip then
- found = true
- end
- end
- if found then
- sendresponse(leave_entry.name .. " is already on the BoS", executorPlayerId)
- else
- cmdreply[cmdreply()] = "Adding " .. leave_entry.name .. " to BoS."
- cmdreply[cmdreply()] = "Entry: " .. leave_entry.name .. " - " .. leave_entry.hash .. " - " .. leave_entry.ip
- sendresponse(cmdreply, executorPlayerId)
- bos_table[#bos_table+1] = leave_entry
- end
- end
- }
- )
- Commands.Create(
- "kickbansfile",
- {
- help = [[-- Kicks and Bans Log File Name
- -- Syntax: %s {Filename}
- -- Allows the executor to view and change the name of the 'BanReasons.log' file.]],
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, filename)
- if not filename then
- sendresponse("The current KickBans file name is " .. defaults.kickbans_file .. ".log", executorPlayerId)
- elseif match(filename, "%w+") then
- defaults.kickbans_file = filename
- sendresponse("The KickBans file has been changed to " .. defaults.kickbans_file .. ".log", executorPlayerId)
- else
- sendresponse("File names must contain alphanumerical characters only!", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "commandsfile",
- {
- help = [[-- Commands Log File Name
- -- Syntax: %s {Filename}
- -- Allows the executor to view and change the name of the 'commands.log' file.]],
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, filename)
- if not filename then
- sendresponse("The current KickBans file name is " .. defaults.commands_file .. ".log", executorPlayerId)
- elseif match(filename, "%w+") then
- defaults.commands_file = filename
- sendresponse("The KickBans file has been changed to " .. defaults.commands_file .. ".log", executorPlayerId)
- else
- sendresponse("File names must contain alphanumerical characters only!", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "adminfile",
- {
- help = [[-- Admins Text File Name
- -- Syntax: %s {Filename}
- -- Allows the executor to view and change the name of the 'admins.txt' file.]],
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, filename)
- if not filename then
- sendresponse("The current Admins file name is " .. defaults.admin_file .. ".txt", executorPlayerId)
- elseif match(filename, "%w+") then
- defaults.admin_file = filename
- sendresponse("The Admins file has been changed to " .. defaults.admin_file .. ".txt", executorPlayerId)
- else
- sendresponse("File names must contain alphanumerical characters only!", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "sharedhashfile",
- {
- help = [[-- Shared Hashes Text File Name
- -- Syntax: %s {Filename}
- -- Allows the executor to view and change the name of the 'sharedhashes.txt' file.
- -- The Shared Hashes file contain hashes that cannot be banned, because they are used by lots of different players.]],
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, filename)
- if not filename then
- sendresponse("The current Shared Hashes file name is " .. defaults.sharedhash_file .. ".txt", executorPlayerId)
- elseif match(filename, "%w+") then
- defaults.sharedhash_file = filename
- sendresponse("The Shared Hashes file has been changed to " .. defaults.sharedhash_file .. ".txt", executorPlayerId)
- else
- sendresponse("File names must contain alphanumerical characters only!", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "banlistfile",
- {
- help = [[-- Kicks and Bans Log File Name
- -- Syntax: %s {Filename}
- -- Allows the executor to view and change the name of the 'banned.txt' file.]],
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, filename)
- if not filename then
- sendresponse("The current Banlist File Name is " .. defaults.banlist_file .. ".txt", executorPlayerId)
- elseif match(filename, "%w+") then
- defaults.banlist_file = filename
- sendresponse("The Banlist file has been changed to " .. defaults.banlist_file .. ".txt", executorPlayerId)
- else
- sendresponse("File names must contain alphanumerical characters only!", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "banlist",
- {
- aliases = {"ipbanlist", "namebanlist", "hashbanlist", "textbanlist"},
- help = [[-- Ban List
- -- Syntax: %s {ip | hash | chat | name}
- -- Displays all players banned from the server.
- -- Specifying a second argument will filter the list by the specified bantype.]]
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, bantype)
- -- Don't need to do anything if the banlist is empty.
- if not ban_table[1] then
- sendresponse("The Banlist is empty", executorPlayerId)
- return
- end
- if bantype and bantype ~= "name" and bantype ~= "chat" and bantype ~= "hash" and bantype ~= "ip" then
- sendresponse("Invalid Bantype. Valid bantypes are ip, hash, name, and chat", executorPlayerId)
- return
- end
- cmdreply.header = "[ID | Name | Bans | Expires | Reason]"
- cmdreply.delim = "|"
- cmdreply.align = true
- local ban_entry, time, timeleft
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.time ~= "Unbanned" then
- -- the only time a ban entry's time can be nil is if it expired, and if so don't display it
- time = ban_entry.time
- timeleft = time ~= "Unbanned" and time ~= -1 and time - os.time() or 0
- if time == -1 or timeleft > 0 then
- if not bantype or bantype == ban_entry.type then
- cmdreply[cmdreply()] = format("[%u | %s | %s | %s | %s]", id, ban_entry.name, ban_entry.count or "N/A", time ~= -1 and formatTime(timeleft) or "Never", ban_entry.reason or "None")
- end
- end
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "unban",
- {
- aliases = {"ipunban", "hashunban", "textunban", "nameunban"},
- help = [[-- Unban
- -- Syntax: %s [ID]
- -- Unbans the specified player.]]
- },
- {
- arguments = {"Positive Number", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, ID)
- local entry = ban_table[ID]
- if not entry then
- sendresponse("Invalid ID", executorPlayerId)
- return
- end
- local index = (entry.ip or "") .. ":" .. (entry.hash or "") .. ":" .. entry.name
- if entry.type == "chat" then
- -- unmute them if they are currently in the game.
- for i = 0,15 do
- if getplayer(i) and netMatch(entry.ip, getip(i)) then
- ip_table[getip(i)].muted = false
- end
- end
- end
- local bantype = entry.type
- entry.time = "Unbanned"
- updateBanFiles(bantype) -- update banlist file.
- sendresponse(bantype .. " ban '" .. index .. "' has been unbanned from the banlist!", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "boslist",
- {
- help = [[-- Ban on Sight List
- -- Syntax: %s
- -- Display the Ban On Sight list]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- if not bos_table[1] then
- sendresponse("The Ban on Sight list is empty!", executorPlayerId)
- return
- end
- cmdreply.header = "[ID | Name | Hash | IP]"
- cmdreply.delim = "|"
- cmdreply.align = true
- local bos_entry
- for id = 1,#bos_table do bos_entry = bos_table[id]
- cmdreply[cmdreply()] = format("[%u | %s | %s | %s]", id, bos_entry.name, bos_entry.hash, bos_entry.ip)
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "bosplayers",
- {
- aliases = {"bosableplayers"},
- help = [[-- Bosable Players List
- -- Syntax: %s
- -- Shows the available players that can be banned on sight.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- if not next(leave_table) then
- sendresponse("There are no players that can be added as a BOS right now", executorPlayerId)
- return
- end
- cmdreply.header = "[ID | Name]"
- cmdreply.delim = "|"
- cmdreply.align = true
- local leave_entry
- for i = 1,16 do leave_entry = leave_table[i]
- if leave_entry then
- cmdreply[cmdreply()] = "[" .. i .. " | " .. leave_entry.name .. " | " .. leave_entry.ip .. "]"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "changelevel",
- {
- aliases = {"adminlevel", "levelchange", "level", "modifylevel"},
- help = [[-- Change Level Command
- -- Syntax: %s [nickname] {level}
- -- Change the specified admins' level]]
- },
- {
- arguments = {"String", "Access Level", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, nickname, level)
- if not next(admin_table) then
- sendresponse("There are no admins on this server" , executorPlayerId)
- return
- end
- local found
- for k,thisAdmin in next,admin_table do
- if thisAdmin.name == nickname then
- if level then
- thisAdmin.level = level
- cmdreply[cmdreply()] = nickname .. " is now a level " .. level .. (thisAdmin.type == "ip" and " IP Admin" or " Hash Admin")
- else
- cmdreply[cmdreply()] = nickname .. " is a level " .. thisAdmin.level .. (thisAdmin.type == "ip" and " IP Admin" or " Hash Admin")
- end
- found = true
- break
- end
- end
- if not found then
- sendresponse("Invalid Nickname" , executorPlayerId)
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "changeteam",
- {
- aliases = {"ts", "teamchange"},
- help = [[-- Change team Command
- -- Syntax: %s [player]
- -- Change the specified players team]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- changeteam(playerId, true)
- cmdreply[cmdreply()] = getname(playerId) .. " has been forced to change teams"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "disconnect",
- {
- aliases = {"losenetworkconnection", "dc"},
- help = [[-- Disconnect Player
- -- Syntax: %s [player]
- -- Will forcibly cause the player to lose connection to the server,
- -- This will not affect the server]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local machine_base = readdword(addresses.network_struct) -- Confirmed.
- local machine_table = machine_base + 0xAA0 -- Confirmed. Player machine table
- local playerId, m_player, player_machine_index, machine_struct, machine_network
- for i = 1,#players do playerId = players[i]
- m_player = getplayer(playerId)
- player_machine_index = readbyte(m_player + 0x64)
- machine_struct = readdword(machine_table + player_machine_index*4)
- machine_network = readdword(readdword(machine_struct))
- writebyte(machine_network, 0)
- halo_svcmd("sv_kick " .. resolveplayer(playerId)) -- just because it takes ages for the server to figure out they quit
- cmdreply[cmdreply()] = getname(playerId) .. " has lost connection successfully."
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "count",
- {
- aliases = {"uniques", "uniqueplayers"},
- help = [[-- Count
- -- Syntax: %s
- -- It will display the number of unique users.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- if not defaults.uniques_enabled then
- sendresponse("'sv_uniques_enabled' is currently disabled.", executorPlayerId)
- return
- end
- sendresponse("There are " .. unique_table.total .. " unique users that have been to this server", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "commands",
- {
- aliases = {"cmds", "commandlist", "list"},
- help = [[-- Commands
- --Syntax %s
- -- Lists the commands you are allowed to executed]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- if not executorPlayerId then
- sendresponse("All Commands: " .. concat(Commands, ", "), executorPlayerId)
- return
- end
- local level = player_table[executorPlayerId].admin_entry.level
- if access_table[level] == -1 then
- sendresponse("All Commands: " .. concat(Commands, ", "), executorPlayerId)
- else
- sendresponse(access_table[level], executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "crash",
- {
- scrimBlock = true,
- help = [[-- Crash Player's Game
- -- Syntax: %s [player]
- -- This command will crash the players game,
- -- This will not affect the server]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- if gameend then
- sendresponse("You cannot crash a player while the game is ended. Wait until next game.", executorPlayerId)
- return
- end
- local exname = getname(executorPlayerId)
- local playerId, objectId, name
- for i = 1,#players do playerId = players[i]
- name = getname(playerId)
- if not checkAdminBlockerAccess(executorPlayerId, playerId) then
- sendresponse("You cannot use this command on " .. name, executorPlayerId)
- privatesay(playerId, exname .. " attemped to use Crash on you!")
- goto continue
- end
- objectId = createobject(gettag("vehi", "vehicles\\warthog\\mp_warthog"), 0, 1, false, 0, 1, 2)
- entervehicle(playerId, objectId, 5)
- destroyobject(objectId)
- cmdreply[cmdreply()] = name .. " had their game crashed by an admin"
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "damage",
- {
- aliases = {"dmg", "setdmg", "setdmgmulti", "setdamage"},
- scrimBlock = true,
- help = [[-- Damage Multiplier
- -- Syntax: %s [player] [damage multiplier]
- -- Increases the amount of damage the player does.]]
- },
- {
- arguments = {"Player", "Number", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players, value)
- local playerId
- for i = 1,#players do playerId = players[i]
- if value then
- player_table[playerId].dmgmultiplier = value
- cmdreply[cmdreply()] = getname(playerId) .. " now has a damage multiplier of " .. value
- else
- cmdreply[cmdreply()] = getname(playerId) .. " has a damage multiplier of " .. player_table[playerId].dmgmultiplier
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "delrcon",
- {
- aliases = {"rcondel"},
- help = [[-- Delete Rcon Password
- -- Syntax: %s {password}
- -- Deletes the rcon password.]]
- },
- {
- arguments = {"String", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, password)
- if not rcon_passwords[password] then
- sendresponse(password .. " is not an rcon password", executorPlayerId)
- return
- end
- rcon_passwords[password] = nil
- sendresponse(password .. " is no longer an rcon password", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "eject",
- {
- aliases = {"playereject", "ejectplayer"},
- scrimBlock = true,
- help = [[-- Eject
- -- Syntax: %s [player]
- -- Force the specified players to exit their vehicle]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, m_playerObj
- for i = 1,#players do playerId = players[i]
- m_playerObj = getplayerobject(playerId)
- if m_playerObj then
- if isinvehicle(playerId) then
- exitvehicle(playerId)
- cmdreply[cmdreply()] = "Ejecting " .. getname(playerId) .. " from their vehicle"
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is not in a vehicle"
- end
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "gethash",
- {
- aliases = {"hash", "gethash"},
- help = [[-- Get Player Hash
- -- Syntax: %s [Player]
- -- Gets the specified player's hash]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- cmdreply[cmdreply()] = getname(playerId) .. ": " .. gethash(playerId)
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "getip",
- {
- help = [[-- Get IP
- -- Syntax: %s [Player]
- -- Get the specified playersIP address]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- cmdreply[cmdreply()] = getname(playerId) .. ": " .. getip(playerId)
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "getloc",
- {
- aliases = {"getplayerlocation", "getplayerloc", "getplayercoords", "getcoords", "coords", "playerloc", "playercoords"},
- help = [[-- Get Location
- -- Syntax: %s [Player]
- -- Get the specified players' coordinates in the server]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- local x,y,z = getobjectcoords(playerObjId, m_playerObj)
- x,y,z = round(x, 2),round(y, 2),round(z, 2)
- cmdreply[cmdreply()] = getname(playerId) .. "'s coords are: X: " .. x .. " Y: " .. y .. " Z: " .. z
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setgod",
- {
- aliases = {"god", "godmode", "godset"},
- scrimBlock = true,
- help = [[-- Set God
- -- Syntax: %s [Player]
- -- Gives you lots of health]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- if defaults.deathless then
- sendresponse("Deathless is now enabled You cannot give out godmode", executorPlayerId)
- return
- end
- local playerId, ptable, m_playerObj
- for i = 1,#players do playerId = players[i]
- m_playerObj = getplayerobject(playerId)
- if m_playerObj then
- ptable = player_table[playerId]
- if not ptable.godmode then
- cmdreply[cmdreply()] = getname(playerId) .. " has been given godmode"
- ptable.godmode = true
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is already in godmode"
- end
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "cheathax",
- {
- aliases = {"hax", "haxolu", "haxor", "1337"},
- scrimBlock = true,
- help = [[-- Cheat Hax
- -- Syntax: %s [Player]
- -- I will never tell]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, m_player
- for i = 1,#players do playerId = players[i]
- m_player = getplayer(playerId)
- setscore(playerId, 9999)
- writeshort(m_player + 0x9C, 9999)
- writeshort(m_player + 0xA4, 9999)
- writeshort(m_player + 0xAC, 9999)
- writeshort(m_player + 0xAE, 9999)
- writeshort(m_player + 0xB0, 9999)
- cmdreply[cmdreply()] = getname(playerId) .. " has been haxed"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "heal",
- {
- aliases = {"healplayer", "playerheal"},
- scrimBlock = true,
- help = [[-- Heal
- -- Syntax: %s [Player]
- -- Heal the specified players]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, m_playerObj, playerObjId, obj_health, m_vehicleObj, x, y, z, healthpack
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- obj_health = readfloat(m_playerObj + 0xE0)
- if obj_health < 1 then
- m_vehicleObj = getplayervehicle(playerId)
- if not m_vehicleObj then
- x,y,z = getobjectcoords(playerObjId)
- healthpack = getobject(createobject(gettag("eqip", "powerups\\health pack"), 0, 0, false, x, y, z+0.5))
- if healthpack then writefloat(healthpack + 0x70, -2) end
- else
- writefloat(m_playerObj + 0xE0, 1)
- end
- cmdreply[cmdreply()] = getname(playerId) .. " has been healed"
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is already at full health"
- end
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "hide",
- {
- aliases = {"hideplayer", "playerhide"},
- scrimBlock = true,
- help = [[-- Hide
- -- Syntax: %s [Player]
- -- You are invisible. Not Camo.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, ptable
- for i = 1,#players do playerId = players[i]
- ptable = player_table[playerId]
- if not ptable.hidden then
- cmdreply[cmdreply()] = getname(playerId) .. " is now hidden"
- ptable.hidden = true
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is already hidden"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "hitler",
- {
- aliases = {"genocide", "killall"},
- scrimBlock = true,
- help = [[-- Hitler
- -- Syntax: %s [Player]
- -- A lethal injection is given to the specified player.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- for i = 0,15 do
- if getplayer(i) then
- kill(i)
- say(getname(i) .. " was shoved into an oven!")
- end
- end
- sendresponse("The server has been purified.", executorPlayerId)
- end
- }
- )
- Commands.Create("info",
- {
- aliases = {"i", "playerinfo", "infoplayer"},
- help = [[-- Info
- Syntax: %s [Player]
- -- Returns a lot of info of the specified player]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local gametype_maximum_health = readfloat(addresses.gametype_base + 0x54)
- local playerId
- for i = 1,#players do playerId = players[i]
- local m_player = getplayer(playerId)
- local ip = getip(playerId)
- local ptable = player_table[playerId]
- local iptable = ip_table[ip]
- local team = getteam(playerId)
- local teamsize = getteamsize(team)
- team = team_play and (team == 0 and "Red" or team == 1 or "Blue" or "Hidden") or "FFA " .. team
- local respawntime = round(readdword(m_player + 0x2C) * 0.033, 2)
- local invis_time = round(readword(m_player + 0x68) * 0.033, 2)
- local speed = readfloat(m_player + 0x6C)
- local objective_mode = readbyte(m_player + 0x74)
- local objective_mode2 = readbyte(m_player + 0x7A)
- local killstreak = readword(m_player + 0x96)
- local kills = readshort(m_player + 0x9C)
- local assists = readshort(m_player + 0xA4)
- local suicides = readshort(m_player + 0xB0)
- local betrays = readshort(m_player + 0xAC) + suicides
- local deaths = readshort(m_player + 0xAE)
- local ping = readword(m_player + 0xDC)
- local m_playerObj, playerObjId = getplayerobject(playerId)
- local invis_info,crouch,health_info,objective_mode,flashlight_mode,flashlight_level
- local x,y,z
- local primary_weap_heat, primary_weap_age, primary_weap_ammo, primary_weap_clip, primary_weap_info
- local secondary_weap_heat, secondary_weap_age, secondary_weap_ammo, secondary_weap_clip, secondary_weap_info
- local primary_weap_info = "Primary: Empty"
- local secondary_weap_info = "Secondary: Empty"
- local weap_slot, nade_info
- if m_playerObj then
- local m_vehicleObj = getplayervehicle(playerId)
- x,y,z = getobjectcoords(playerObjId)
- x,y,z = round(x, 2),round(y, 2),round(z, 2)
- local health = round(readfloat(m_playerObj + 0xE0) * 100)
- local shields = round(readfloat(m_playerObj + 0xE4) * 100)
- local max_health = round(health * readfloat(m_playerObj + 0xD8) / 100)
- local max_shields = round(shields * readfloat(m_playerObj + 0xDC) / 100)
- flashlight_mode = readbit(m_playerObj + 0x204, 19) and "On" or "Off"
- crouch = readbyte(m_playerObj + 0x2A0)
- weap_slot = readbyte(m_playerObj + 0x2F2)
- local nade_type = readbyte(m_playerObj + 0x31C)
- local primary_nades = readbyte(m_playerObj + 0x31E)
- local secondary_nades = readbyte(m_playerObj + 0x31F)
- flashlight_level = round(readfloat(m_playerObj + 0x344) * 100)
- local invis_scale = round(readfloat(m_playerObj + 0x37C) * 100, 2)
- invis_scale = invis_scale == 0 and "No" or invis_scale .. "%"
- invis_info = invis_scale ~= "No" and "Invis: " .. invis_scale .. " (" .. invis_time .. " secs)" or "Invis: " .. invis_scale
- local m_primaryWeapObj, m_secondaryWeapObj
- if m_vehicleObj then
- m_primaryWeapObj = getobject(readdword(m_vehicleObj + 0x2F8))
- elseif weap_slot == 1 then
- m_primaryWeapObj = getobject(readdword(m_playerObj + 0x2FC))
- m_secondaryWeapObj = getobject(readdword(m_playerObj + 0x2F8))
- else
- m_primaryWeapObj = getobject(readdword(m_playerObj + 0x2F8))
- m_secondaryWeapObj = getobject(readdword(m_playerObj + 0x2FC))
- end
- if m_primaryWeapObj then
- local primary_weap_heat = round(readfloat(m_primaryWeapObj + 0x23C) * 100)
- local primary_weap_age = round((1 - readfloat(m_primaryWeapObj + 0x240)) * 100)
- local primary_weap_ammo = readword(m_primaryWeapObj + 0x2B6)
- local primary_weap_clip = readword(m_primaryWeapObj + 0x2B8)
- primary_weap_info = primary_weap_age ~= 100 and "Primary Battery: " .. primary_weap_heat .. "% / " .. primary_weap_age .. "%" or primary_weap_ammo == 0 and primary_weap_clip == 0 and "Primary: Infinite" or "Primary Ammo: " .. primary_weap_clip .. " / " .. primary_weap_ammo
- end
- if m_secondaryWeapObj then
- local secondary_weap_heat = round(readfloat(m_secondaryWeapObj + 0x23C) * 100)
- local secondary_weap_age = round((1 - readfloat(m_secondaryWeapObj + 0x240)) * 100)
- local secondary_weap_ammo = readword(m_secondaryWeapObj + 0x2B6)
- local secondary_weap_clip = readword(m_secondaryWeapObj + 0x2B8)
- secondary_weap_info = secondary_weap_age ~= 100 and "Secondary Battery: " .. secondary_weap_heat .. "% / " .. secondary_weap_age .. "%" or secondary_weap_ammo == 0 and secondary_weap_clip == 0 and "Secondary: Infinite" or "Secondary Ammo: " .. secondary_weap_clip .. " / " .. secondary_weap_ammo
- end
- if crouch == 0 then
- crouch = "Warthog: Driver"
- elseif crouch == 1 then
- crouch = "Warthog: Gunner"
- elseif crouch == 2 then
- crouch = "Warthog: Passenger"
- elseif crouch == 3 then
- crouch = "Stance: Crouching"
- elseif crouch == 4 then
- crouch = "Stance: Standing"
- elseif crouch == 5 then
- crouch = "Ghost: Driver"
- elseif crouch == 6 then
- crouch = "Banshee: Pilot"
- elseif crouch == 13 then
- crouch = "Scorpion: Driver"
- elseif crouch == 17 then
- crouch = "Shade: Gunner"
- elseif crouch == 20 or crouch == 21 or crouch == 22 or crouch == 23 then
- crouch = "Scorpion: Passenger"
- end
- nade_info = "Frag Grenades: " .. primary_nades .. " | " .. "Plasma Grenades: " .. secondary_nades
- nade_info = nade_type == 1 and "Plasma Grenades: " .. secondary_nades .. " | " .. "Frag Grenades: " .. primary_nades or nade_info
- if crouch == "Stance: Crouching" or crouch == "Stance: Standing" then
- if readbyte(m_playerObj + 0x4CC) == 1 then
- crouch = "Stance: Airborne"
- end
- end
- if iptable.suspended then
- health_info = "Respawn: Player is Suspended"
- else
- health_info = format("Health: %s%% (%s) | Shields: %s%% (%s)", health, max_health, shields, max_shields)
- end
- else
- crouch = "Stance: Dead"
- health_info = respawntime == 1 and "Respawn: " .. respawntime .. " sec" or "Respawn: " .. respawntime .. " secs"
- end
- if objective_mode == 0x22 and objective_mode2 == 0x71 then
- objective_mode = "Hill"
- elseif objective_mode == 0x23 and objective_mode2 == 0x71 then
- objective_mode = "Juggernaut"
- elseif objective_mode == 0x23 and objective_mode2 == 0x72 then
- objective_mode = "It"
- elseif objective_mode == 0x29 and objective_mode2 == 0x70 then
- objective_mode = "Ball"
- elseif weap_slot == 2 then
- objective_mode = "Flag"
- else
- objective_mode = "None"
- end
- cmdreply.delim = "|"
- cmdreply[cmdreply()] = "----------"
- cmdreply[cmdreply()] = format("Name: %s ( %u ) | Team: %s (%s) | Speed: %s | Location: (%s, %s, %s)", getname(playerId), resolveplayer(playerId), team, teamsize, round(speed, 2), x, y, z)
- cmdreply[cmdreply()] = format("Hash: %s | IP: %s", gethash(playerId), ip)
- cmdreply[cmdreply()] = format("Admin: %s | Ping: %s | %s", ptable.admin_entry and "YES" or "NO", ping, crouch)
- cmdreply[cmdreply()] = format("Kills: %s (%s) | Assists: %s | Betrays %s | Suicides %s | Deaths %s", kills, killstreak, assists, betrays, suicides, deaths)
- cmdreply[cmdreply()] = format("%s | %s | Light: %s (%s%%)", health_info, invis_info, flashlight_mode, flashlight_level)
- cmdreply[cmdreply()] = format("%s | %s | Objective: %s", primary_weap_info, secondary_weap_info, objective_mode)
- cmdreply[cmdreply()] = nade_info
- cmdreply[cmdreply()] = format("Hidden: %s | God: %s | AFK: %s", ptable.hidden, ptable.godmode, ptable.afk)
- cmdreply[cmdreply()] = "----------"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "ipban",
- {
- aliases = {"banip"},
- help = [[-- IP Ban
- -- Syntax: %s [Player or IP] {Time} {Reason}
- -- Will ban a player/ip from the server.]],
- usesBanCounts = true,
- },
- {
- arguments = {"Player", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, players, time, reason)
- local exname = getname(executorPlayerId)
- local playerId, name
- for i = 1,#players do playerId = players[i]
- name = getname(playerId)
- if not checkAdminBlockerAccess(executorPlayerId, playerId) then
- sendresponse("You cannot use this command on " .. name, executorPlayerId)
- privatesay(playerId, exname .. " attemped to IPBan you!")
- goto continue
- end
- addBan(name, nil, getip(playerId) .. "/24", time, "ip", reason)
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", name .. " was banned by " .. exname .. " Reason: " .. reason .. " Type: IP Ban")
- if defaults.sa_message then
- say(name .. " was IP banned by " .. exname .. " Reason: " .. reason)
- else
- say(name .. " was IP banned! Reason: " .. reason)
- end
- registertimer(0, "tempBanPlayer", resolveplayer(playerId))
- cmdreply[cmdreply()] = name .. " has been IP banned"
- sendresponse(cmdreply, executorPlayerId)
- ::continue::
- end
- end
- },
- {
- arguments = {"IP Address", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, ip_address, time, reason)
- local exname = getname(executorPlayerId)
- addBan("manual_ban" .. #ban_table+1, nil, ip_address, time, "ip", reason)
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", "The IP: " .. ip_address .. " was banned by " .. exname .. " Reason: " .. reason .. " Type: IP Ban")
- sendresponse(ip_address .. " has been IP banned successfully.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "invis",
- {
- aliases = {"camo", "camouflage", "setcamo"},
- help = [[-- Invis
- -- Syntax: %s [Player] {Time}
- -- Will camo the specified player.]]
- },
- {
- arguments = {"Player", "Time", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, time)
- local playerId, m_playerObj, playerObjId, ptable
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- goto continue
- end
- ptable = player_table[playerId]
- if ptable.invisible then
- cmdreply[cmdreply()] = getname(playerId) .. " is already invisible"
- goto continue
- end
- ptable.invisible = time
- cmdreply[cmdreply()] = getname(playerId) .. " is now invisible"
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "kick",
- {
- aliases = {"k", "kickplayer", "playerkick"},
- help = [[-- Kick
- -- Syntax: %s [Player] {Message}
- -- Kicks the player out of the server with a reason written to the KicksAndBans.log]]
- },
- {
- arguments = {"Player", "Remaining Arguments", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, reason)
- reason = reason or "None Given"
- local exname = getname(executorPlayerId)
- local playerId, name
- for i = 1,#players do playerId = players[i]
- name = getname(playerId)
- if not checkAdminBlockerAccess(executorPlayerId, playerId) then
- sendresponse("You cannot use this command on " .. name, executorPlayerId)
- privatesay(playerId, exname .. " attemped to use Kick on you!")
- goto continue
- end
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", name .. " was kicked by " .. exname .. " Reason: " .. reason)
- say(name .. " has been kicked! Reason: " .. reason)
- sendresponse(name .. " has been kicked from the server", executorPlayerId)
- halo_svcmd("sv_kick " .. resolveplayer(playerId))
- ::continue::
- end
- end
- }
- )
- Commands.Create(
- "kill",
- {
- aliases = {"killplayer", "playerkill"},
- scrimBlock = true,
- help = [[-- Kill Player
- -- Syntax: %s [Player]
- -- Kills the specified player, and forces them to respawn.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- if not getplayerobject(playerId) then
- sendresponse(getname(playerId) .. " is already dead!", executorPlayerId)
- goto continue
- end
- kill(playerId)
- sendresponse(getname(playerId) .. " has been killed", executorPlayerId)
- ::continue::
- end
- end
- }
- )
- Commands.Create(
- "launch",
- {
- help = [[-- Launch
- -- Syntax: %s [Player]
- -- Launches the person in a random direction.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, m_vehicleObj, vehicleObjId
- for i = 1,#players do playerId = players[i]
- m_vehicleObj, vehicleObjId = getplayervehicle(playerId)
- if not m_vehicleObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is dead/not in a vehicle"
- goto continue
- end
- local x_or_y = rand(1, 3)
- if x_or_y == 1 then
- local x_rand_vel = rand(6, 11)
- writefloat(m_vehicleObj + 0x94, x_rand_vel)
- writefloat(m_vehicleObj + 0x90, 0)
- writefloat(m_vehicleObj + 0x8C, 0)
- elseif x_or_y == 2 then
- local y_rand_vel = rand(6, 11)
- writefloat(m_vehicleObj + 0x8C, y_rand_vel)
- writefloat(m_vehicleObj + 0x90, 0)
- writefloat(m_vehicleObj + 0x94, 0)
- else
- local z_rand_vel = rand(6, 11)
- writefloat(m_vehicleObj + 0x90, z_rand_vel)
- writefloat(m_vehicleObj + 0x94, 0)
- writefloat(m_vehicleObj + 0x8C, 0)
- end
- writefloat(m_vehicleObj + 0x70, 0.1)
- cmdreply[cmdreply()] = getname(playerId) .. " has been launched!"
- -- update object physics
- writefloat(m_vehicleObj + 0x70, 0.4)
- writebit(m_vehicleObj + 0x10, 0, 0) -- Unset noCollisions bit32.
- writebit(m_vehicleObj + 0x10, 5, 0) -- Unset ignorePhysics.
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- function lo3Timer(id, count)
- if gameend then return false end
- if count >= 3 then
- if not defaults.scrim_mode then say "WARNING! Scrim mode is NOT on!" end
- say "Start your match"
- halo_svcmd "sv_map_reset"
- lo3_timer = nil
- return false
- else
- halo_svcmd "sv_map_reset"
- return true
- end
- end
- Commands.Create(
- "lo3",
- {
- aliases = {"scrim"},
- help = [[-- Live on Three
- -- Syntax: %s
- -- This command will reset the map 3 times]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- if lo3_timer then
- sendresponse("Live on three is already in progress! Please wait!", executorPlayerId)
- else
- lo3_timer = registertimer(1000, "lo3Timer")
- end
- sendresponse("Live on three.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "login",
- {
- aliases = {"l", "log"},
- help = [[-- Login
- -- Syntax: %s [Username] [Password]
- -- If there are no admins in the admin_table then you will be able to login with this command
- -- so you are able to use Chat commands even without being a hash or IP admin, it is only temporary.]]
- },
- {
- arguments = {"String", "String", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, username, password)
- if not executorPlayerId then
- sendresponse("the Server is always logged in.", executorPlayerId)
- return
- end
- local hash, ip = gethash(executorPlayerId), getip(executorPlayerId)
- if ip_table[ip].tempadmin then
- sendresponse("You are already logged in", executorPlayerId)
- return
- end
- if player_table[executorPlayerId].admin_entry then
- sendresponse("You are already an admin!", executorPlayerId)
- return
- end
- if admin_logins[username] == password then
- ip_table[ip].tempadmin = true
- sendresponse("You have successfully logged in, you are now able to use chat commands.", executorPlayerId)
- else
- sendresponse("Bad username/password combo.", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "mnext",
- {
- aliases = {"mapnext"},
- is_alias = true,
- help = [[-- Map Next
- -- Syntax: %s
- -- Shortcut for sv_map_next]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- halo_svcmd "sv_map_next"
- halo_svcmd "sv_mapcycle_timeout 1"
- sendresponse("The next map will start shortly", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "reset",
- {
- aliases = {"mapreset", "resetmap"},
- is_alias = true,
- help = [[-- Map Reset
- -- Syntax: %s
- -- Shortcut for sv_map_reset]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- halo_svcmd "sv_map_reset"
- sendresponse("The map has been reset", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "move",
- {
- aliases = {"j", "mv"},
- scrimBlock = true,
- help = [[-- Move Player
- -- Syntax: %s [player] [x] [y] [z]
- -- Move the player by the set number of coords.]]
- },
- {
- arguments = {"Player", "Number", "Number", "Number", minArgs = 4, maxArgs = 4},
- func = function(executorPlayerId, players, X, Y, Z)
- local playerId, m_playerObj, playerObjId, x, y, z
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- x,y,z = getobjectcoords(playerObjId)
- movobjectcoords(playerObjId, x+X, y+Y, z+Z)
- cmdreply[cmdreply()] = getname(playerId) .. " has been moved"
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "nameban",
- {
- aliases = {"banname"},
- help = [[-- Name Ban
- -- Syntax: %s [player]
- -- Ban a person via their name]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local exname = getname(executorPlayerId)
- local playerId, name, ban_entry, found, b
- for i = 1,#players do playerId = players[i]
- name = getname(playerId)
- if not checkAdminBlockerAccess(executorPlayerId, playerId) then
- sendresponse("You cannot use this command on " .. name, executorPlayerId)
- privatesay(playerId, exname .. " attemped to use NameBan on you!")
- goto continue
- end
- if name ~= "NameBanned" then
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.time ~= "Unbanned" then
- if ban_entry == name then found = true break end
- end
- end
- if not found then
- b = TM.New()
- b.name,b.type = name,"name"
- ban_table[#ban_table+1] = b
- cmdreply[cmdreply()] = halo_svcmd("sv_kick " .. resolveplayer(playerId), true)
- say(name .. " has been name banned from the server")
- end
- else
- cmdreply[cmdreply()] = "You cannot ban this name, this name has been assigned automatically."
- end
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "overshield",
- {
- aliases = {"os", "giveos", "osgive", "giveovershield", "overshieldgive"},
- scrimBlock = true,
- help = [[-- OverShield
- -- Syntax: %s [player]
- -- Give specified players an overshield (os)]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, m_playerObj, playerObjId, m_vehicleObj, vehicleObjId, x, y, z, overshield, obj_shields
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- goto continue
- end
- obj_shields = readfloat(m_playerObj + 0xE4)
- if obj_shields > 1 then
- cmdreply[cmdreply()] = getname(playerId) .. " already has an overshield"
- goto continue
- end
- m_vehicleObj, vehicleObjId = getplayervehicle(playerId)
- if m_vehicleObj then
- writefloat(m_playerObj + 0xE4, 3)
- else
- x,y,z = getobjectcoords(playerObjId)
- overshield = getobject(createobject(gettag("eqip", "powerups\\overshield"), 0, 0, false, x, y, z+0.5))
- if overshield then writefloat(overshield + 0x70, -2) end
- end
- cmdreply[cmdreply()] = getname(playerId) .. " has been given an overshield"
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "players",
- {
- aliases = {"pl", "playerlist"},
- help = [[-- Player List
- -- Syntax: %s
- -- sv_players command modified
- -- Displays all Player Indicies and Names]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- cmdreply.header = "[ID | Name]"
- cmdreply.delim = "|"
- cmdreply.align = true
- local playerId
- for i = 1,16 do playerId = rresolveplayer(i)
- if not getplayer(playerId) then goto continue end
- cmdreply[cmdreply()] = "[" .. i .. " | " .. getname(playerId) .. "]"
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "playersmore",
- {
- aliases = {"plmore", "moreplayers"},
- help = [[-- Extended Player List
- -- Syntax: %s
- -- Shows Player ID, Player Name, Player Team, Status(Admin/Regular), IP, and Hash]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- cmdreply.header = "[ID | Name | Team | Type | IP | Hash]"
- cmdreply.delim = "|"
- cmdreply.align = true
- local playerId, team
- for i = 1,16 do playerId = rresolveplayer(i)
- if not getplayer(playerId) then goto continue end
- team = getteam(playerId)
- team = team_play and (team == 0 and "Red" or team == 1 and "Blue" or "Hidden") or "FFA " .. team
- cmdreply[cmdreply()] = format("[%s | %s | %s | %s | %s | %s]", i, getname(playerId), team, player_table[playerId].admin_entry and "Admin" or "Regular", getip(playerId), gethash(playerId))
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "privatesay",
- {
- aliases = {"pvtsay", "psay", "sayprivately"},
- help = [[-- Private Say
- --Syntax %s {player} {message}
- --Sends a private message to the specifed player]]
- },
- {
- arguments = {"Player", "Remaining Arguments", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, message)
- for i = 1,#players do
- sendconsoletext(players[i], message)
- end
- sendresponse("Private messages sent.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "rconlist",
- {
- aliases = {"listrcons", "rcons"},
- help = [[-- Rcon Password List
- -- Syntax: %s
- -- Lists all available rcon passwords except the main rcon password]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- cmdreply.header = "[Rcon | Level]"
- cmdreply.align = true
- cmdreply.delim = "|"
- local rcon_entry
- for rcon,level in next,rcon_passwords do
- cmdreply[cmdreply()] = "[" .. rcon .. " | " .. level .. "]"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- local function tobinary(number)
- number = tonumber(number) or error("bad argument #1 to 'tobinary' (number expected, got '" .. type(number) .. "')")
- local t = TM.New()
- local rest
- while number > 0 do
- rest = number % 2
- t[#t+1] = rest
- number = (number - rest) * 0.5
- end
- return concat(t)
- end
- tobinary = memoize(tobinary) -- memoized
- Commands.Create(
- "read",
- {
- help = [[-- Read Address/Struct
- -- Syntax: %s [Type] [Struct or Address] [Offset] [Value] [Player or Bit], [Player]
- -- Read the Guide for info on this command]]
- },
- {
- arguments = {"Struct", "Number", "Bit", "Player", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, struct, offset, bit, players)
- local playerId, m_playerObj, playerObjId, value, float
- for i = 1,#players do playerId = players[i]
- m_playerObj = getplayerobject(playerId)
- if struct == "player" then
- struct = getplayer(playerId)
- elseif m_playerObj then
- if struct == "object" then
- struct = m_playerObj
- elseif struct == "weapon" then
- struct = getplayerweapon(playerId)
- if not struct then sendresponse(getname(playerId) .. " is not holding a Weapon", executorPlayerId) return end
- elseif struct == "vehicle" then
- struct = getplayervehicle(playerId)
- if not struct then sendresponse(getname(playerId) .. " is not in a Vehicle", executorPlayerId) return end
- end
- else
- sendresponse("Player Object must exist to use Struct: " .. struct)
- end
- value = readbit(struct + offset, struct)
- sendresponse("Reading " .. format("0x%08X", struct) .. " at Offset " .. format("0x%X", offset) .. " was a Success", executorPlayerId)
- sendresponse("Binary Val: " .. value, executorPlayerId)
- end
- end
- },
- {
- arguments = {"Datatype", "Struct", "Number", "Player", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, datatype, struct, offset, players)
- local playerId, m_playerObj, playerObjId, float, value
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if struct == "player" then
- struct = getplayer(playerId)
- elseif m_playerObj then
- if struct == "object" then
- struct = m_playerObj
- elseif struct == "weapon" then
- struct = getplayerweapon(playerId)
- if not struct then sendresponse(getname(playerId) .. " is not holding a Weapon", executorPlayerId) end
- elseif struct == "vehicle" then
- struct = getplayervehicle(playerId)
- if not struct then sendresponse(getname(playerId) .. " is not in a Vehicle", executorPlayerId) end
- end
- else
- sendresponse("Player Object must exist to use Struct: " .. struct)
- end
- if datatype == "bit8" then
- value = tobinary(readbyte(struct + offset))
- elseif datatype == "bit16" then
- value = tobinary(readword(struct + offset))
- elseif datatype == "bit32" then
- value = tobinary(readdword(struct + offset))
- elseif datatype == "char" then
- value = readchar(struct + offset)
- elseif datatype == "byte" then
- value = readbyte(struct + offset)
- elseif datatype == "short" then
- value = readshort(struct + offset)
- elseif datatype == "word" then
- value = readword(struct + offset)
- elseif datatype == "int" then
- value = readint(struct + offset)
- elseif datatype == "dword" then
- value = readdword(struct + offset)
- elseif datatype == "float" then
- float = true
- value = readfloat(struct + offset)
- elseif datatype == "string" then
- value = readstring(struct + offset)
- elseif datatype == "widestring" then
- value = readwidestring(struct + offset)
- end
- sendresponse("Reading Address " .. format("0x%08X", struct) .. " was a Success", executorPlayerId)
- if not match(datatype, "^bit%d+$") then
- if float then
- sendresponse("Float: " .. value, executorPlayerId)
- elseif type(value) == "number" then
- sendresponse("Decimal: " .. value .. (value >= 0 and (" Hex: " .. format("0x%X", value)) or ""), executorPlayerId)
- else
- sendresponse("Value: " .. value, executorPlayerId)
- end
- else
- sendresponse("Binary Val: " .. value, executorPlayerId)
- end
- end
- end
- },
- {
- arguments = {"Datatype", "Number", "Number", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, datatype, address, offset)
- local float, value
- if datatype == "bit8" then
- value = tobinary(readbyte(address + offset))
- elseif datatype == "bit16" then
- value = tobinary(readword(address + offset))
- elseif datatype == "bit32" then
- value = tobinary(readdword(address + offset))
- elseif datatype == "char" then
- value = readchar(address + offset)
- elseif datatype == "byte" then
- value = readbyte(address + offset)
- elseif datatype == "short" then
- value = readshort(address + offset)
- elseif datatype == "word" then
- value = readword(address + offset)
- elseif datatype == "int" then
- value = readint(address + offset)
- elseif datatype == "dword" then
- value = readdword(address + offset)
- elseif datatype == "float" then
- float = true
- value = readfloat(address + offset)
- elseif datatype == "string" then
- value = readstring(address + offset)
- elseif datatype == "widestring" then
- value = readwidestring(address + offset)
- end
- sendresponse("Reading Address " .. format("0x%08X", offset) .. " was a Success", executorPlayerId)
- if float then
- sendresponse("Float: " .. value, executorPlayerId)
- elseif value >= 0 then
- sendresponse("Decimal: " .. value .. " Hex: " .. format("0x%X", value), executorPlayerId)
- else
- sendresponse("Value: " .. value, executorPlayerId)
- end
- end
- },
- {
- arguments = {"Number", "Number", "Bit", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, address, offset, bit)
- sendresponse("Reading Address " .. format("0x%08X", address) .. " was a Success", executorPlayerId)
- sendresponse("Binary Val: " .. readbit(address + offset, bit) and 1 or 0, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "write",
- {
- help = [[-- Write
- -- Syntax: %s [Type] [Struct] [Offset] [Value] [Player]
- -- Read the Guide for info on this command]]
- },
- {
- arguments = {"Datatype", "Struct", "Whole Number", "Number", "Player", minArgs = 3, maxArgs = 5},
- func = function(executorPlayerId, datatype, struct, offset, value, playerId)
- --[[local address
- if count >= 5 and count <= 6 then
- if lower(sub(offset, 1, 2)) == "0x" then
- offset = tonumber(sub(offset, 3), 16)
- else
- offset = tonumber(offset) or tonumber(offset, 16)
- end
- local players = getvalidplayers(playerId, executorPlayerId)
- if players then
- local playerId
- for i = 1,#players do playerId = players[i]
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if struct == "player" then
- address = getplayer(playerId)
- elseif struct ~= "object" and struct ~= "weapon" and struct ~= "vehicle" then
- sendresponse("Invalid Struct. Valid structs are: playerId, object, weapon, and vehicle.", executorPlayerId)
- elseif m_playerObj then
- if struct == "object" then
- address = m_playerObj
- elseif struct == "weapon" then
- address = getplayerweapon(playerId)
- if not address then sendresponse(getname(playerId) .. " is not holding a weapon", executorPlayerId) end
- elseif struct == "vehicle" then
- address = getplayervehicle(playerId)
- if not address then sendresponse(getname(playerId) .. " is not in a vehicle", executorPlayerId) end
- elseif not struct then
- sendresponse("Invalid Struct. Valid structs are: playerId, object, weapon, and vehicle", executorPlayerId)
- end
- elseif struct ~= "object" and struct ~= "weapon" and struct ~= "vehicle" then
- sendresponse("Invalid Struct. Valid structs are: playerId, object, weapon, and vehicle.", executorPlayerId)
- else
- sendresponse("playerId object must exist to use struct: " .. struct)
- end
- if offset and address then
- if lower(sub(tostring(value), 2)) == "0x" then
- value = tonumber(sub(tostring(value), 3), 16)
- else
- value = tonumber(value) or tonumber(value, 16)
- end
- if value then
- if datatype == "char" then
- writechar(address + offset, value)
- elseif datatype == "byte" then
- writebyte(address + offset, value)
- elseif datatype == "short" then
- writeshort(address + offset, value)
- elseif datatype == "word" then
- writeword(address + offset, value)
- elseif datatype == "int" then
- writeint(address + offset, value)
- elseif datatype == "dword" then
- writedword(address + offset, value)
- elseif datatype == "float" then
- writefloat(address + offset, value)
- elseif datatype == "string" then
- writestring(address + offset, value)
- elseif datatype == "widestring" then
- writewidestring(address + offset, value)
- else
- sendresponse("Invalid datatype. Valid datatypes are 'char', 'byte', 'short', 'word', 'int', 'dword', 'float', 'string', and 'widestring'", executorPlayerId)
- end
- sendresponse("Writing " .. value .. " to address " .. format("0x%08X", offset) .. " was a success", executorPlayerId)
- else
- sendresponse("Value must be a number", executorPlayerId)
- end
- elseif not offset then
- sendresponse("Offset must be a number", executorPlayerId)
- end
- end
- elseif not playerId then
- if lower(sub(struct, 1, 2)) == "0x" then
- address = tonumber(sub(struct, 3), 16)
- else
- address = tonumber(struct) or tonumber(struct, 16)
- end
- if address then
- if offset then
- if lower(sub(value, 1, 2)) == "0x" then
- value = tonumber(sub(value, 3), 16)
- else
- value = tonumber(value) or tonumber(value, 16)
- end
- if value then
- if datatype == "char" then
- writechar(address + offset, value)
- elseif datatype == "byte" then
- writebyte(address + offset, value)
- elseif datatype == "short" then
- writeshort(address + offset, value)
- elseif datatype == "word" then
- writeword(address + offset, value)
- elseif datatype == "int" then
- writeint(address + offset, value)
- elseif datatype == "dword" then
- writedword(address + offset, value)
- elseif datatype == "float" then
- writefloat(address + offset, value)
- elseif datatype == "string" then
- writestring(address + offset, value)
- elseif datatype == "widestring" then
- writewidestring(address + offset, value)
- else
- sendresponse("Invalid datatype. Valid datatypes are 'char', 'byte', 'short', 'word', 'int', 'dword', 'float', 'string', and 'widestring'", executorPlayerId)
- return
- end
- sendresponse("Writing " .. value .. " to address " .. format("0x%08X", offset) .. " was a success", executorPlayerId)
- else
- sendresponse("Value must be a number.", executorPlayerId)
- end
- else
- sendresponse("Offset must be a number", executorPlayerId)
- end
- else
- sendresponse("Struct must be a number", executorPlayerId)
- end
- else
- sendresponse("Invalid Player", executorPlayerId)
- end
- end]]
- end
- }
- )
- Commands.Create(
- "resetplayer",
- {
- aliases = {"playerreset", "playereset"},
- help = [[-- Reset Player
- -- Syntax: %s [Player]
- -- Removes all troll settings from specified player]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- ResetPlayer(playerId)
- cmdreply[cmdreply()] = getname(playerId) .. " has been reset."
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "resetweapons",
- {
- scrimBlock = true,
- help = [[-- Reset Weapons
- -- Syntax: %s [Player]
- -- Reset the weapons of the specified players]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, iptable, m_playerObj
- for i = 1,#players do playerId = players[i]
- iptable = ip_table[getip(playerId)]
- if iptable.disarmed then
- iptable.disarmed = false
- resetweapons(playerId)
- cmdreply[cmdreply()] = getname(playerId) .. " had their weapons reset"
- else
- cmdreply[cmdreply()] = getname(playerId) .. " never had their weapons taken away"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "resp",
- {
- aliases = {"respplayer", "playerresp"},
- scrimBlock = true,
- help = [[-- Respawn Time for Player
- -- Syntax: %s [Player] {Time}
- -- Change the player's respawn time]]
- },
- {
- arguments = {"Player", "Time", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, time)
- local playerId, m_playerObj
- for i = 1,#players do playerId = players[i]
- m_playerObj = getplayerobject(playerId)
- if not m_playerObj then
- writedword(getplayer(playerId) + 0x2C, time)
- cmdreply[cmdreply()] = "Setting " .. getname(playerId) .. "'s respawn time to " .. timetoword(time)
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is alive. Setting their respawn time will do nothing."
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "rtvrequired",
- {
- aliases = {"rtvneeded"},
- help = [[-- RTV Needed
- -- Syntax: %s [Percent]
- -- Change the number of votes needed for RTV to change the map.]]
- },
- {
- arguments = {"Percent", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, percent)
- if percent then
- sendresponse("Votes required for RTV has been set to " .. percent .. "%", executorPlayerId)
- defaults.rtv_required = percent
- else
- sendresponse(defaults.rtv_required .. "% votes required for RTV", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "rtvtimeout",
- {
- help = [[-- RTV Timeout
- -- Syntax: %s {Time}
- -- The amount of time between each RTV attempt.]]
- },
- {
- arguments = {"Time", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, time)
- if time == -1 then
- sendresponse("RTV Timeout is currently " .. timetoword(defaults.rtv_timeout), executorPlayerId)
- else
- sendresponse("RTV Timeout has been set to " .. timetoword(time), executorPlayerId)
- defaults.rtv_timeout = time
- end
- end
- }
- )
- Commands.Create(
- "setammo",
- {
- aliases = {"ammo", "setammo", "ammoset"},
- scrimBlock = true,
- help = [[-- Set Ammo
- -- Syntax: %s [Player] [Type] [Ammo]
- -- Set the ammo of the players specified
- -- type means type of ammo, use 1 for unloaded ammo and 2 for loaded ammo]]
- },
- {
- arguments = {"Player", "String", "Whole Number", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, players, ammotype, ammo)
- local playerId, m_playerObj, playerObjId, m_weaponObj, weaponObjId
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is dead and cannot have ammo"
- goto continue
- end
- m_weaponObj, weaponObjId = getplayerweapon(playerId)
- if not m_weaponObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is not holding any weapons"
- goto continue
- end
- if ammotype == "unloaded" or ammotype == "1" then
- writeword(m_weaponObj + 0x2B6, ammo)
- cmdreply[cmdreply()] = getname(playerId) .. " had their unloaded ammo changed to " .. ammo
- elseif ammotype == "loaded" or ammotype == "2" then
- writeword(m_weaponObj + 0x2B8, ammo)
- updateammo(weaponObjId)
- cmdreply[cmdreply()] = getname(playerId) .. " had their loaded ammo changed to " .. ammo
- else
- cmdreply[cmdreply()] = "Invalid ammo type: 1 for unloaded, 2 for loaded ammo"
- end
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setcolor",
- {
- aliases = {"color", "colorset"},
- scrimBlock = true,
- help = [[-- Set Color
- -- Syntax: %s [Player] [Color]
- -- Change the color of the selected player. Works on FFA Only]]
- },
- {
- arguments = {"Player", "String", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, color)
- local colors = TM{[0] = "white", "black", "red", "blue", "grey", "yellow", "green", "pink", "purple", "cyan", "cobalt", "orange", "teal", "sage", "brown", "tan", "maroon", "salmon", white = 0, black = 1, red = 2, blue = 3, grey = 4, yellow = 5, green = 6, pink = 7, purple = 8, cyan = 9, cobalt = 10, orange = 11, teal = 12, sage = 13, brown = 14, tan = 15, maroon = 16, salmon = 17}
- if color then
- color = tonumber(color) and tonumber(color) or colors[color]
- if type(color) ~= "number" then
- sendresponse("Invalid Color", executorPlayerId)
- return
- end
- end
- local color_name = colors[color]
- local playerId, m_playerObj, playerObjId, ptable, x, y, z
- for i = 1,#players do playerId = players[i]
- if not color then
- cmdreply[cmdreply()] = getname(playerId) .. " is currently " .. (colors[readbyte(getplayer(playerId) + 0x60)] or "Invalid Color")
- goto continue
- end
- writebyte(getplayer(playerId) + 0x60, color)
- cmdreply[cmdreply()] = getname(playerId) .. " had their color changed to '" .. color_name .. "'"
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- goto continue
- end
- ptable = player_table[i]
- x,y,z = getobjectcoords(playerObjId)
- ptable.colorspawn = true
- ptable.x,ptable.y,ptable.z = x,y,z
- destroyobject(playerObjId)
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setassists",
- {
- aliases = {"assists", "assistset", "setassists"},
- scrimBlock = true,
- help = [[-- Set Assists
- -- Syntax: %s [Player] [Assists]
- -- Set the assists for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, assists)
- local playerId
- for i = 1,#players do playerId = players[i]
- writeshort(getplayer(playerId) + 0xA4, assists)
- cmdreply[cmdreply()] = getname(playerId) .. " had their assists set to " .. assists
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setdeaths",
- {
- aliases = {"deaths", "deathset", "setdeaths", "setdeath"},
- scrimBlock = true,
- help = [[-- Set Deaths
- -- Syntax: %s [Player] [Deaths]
- -- Set the deaths for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, deaths)
- local playerId
- for i = 1,#players do playerId = players[i]
- writeshort(getplayer(playerId) + 0xAE, deaths)
- cmdreply[cmdreply()] = getname(playerId) .. " had their deaths set to " .. deaths
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setkills",
- {
- aliases = {"kills", "killset"},
- scrimBlock = true,
- help = [[-- Set Kills
- -- Syntax: %s [Player] [Kills]
- -- Set the kills for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, kills)
- local playerId
- for i = 1,#players do playerId = players[i]
- writeshort(getplayer(playerId) + 0x9C, kills)
- cmdreply[cmdreply()] = getname(playerId) .. " had their kills set to " .. kills
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setscore",
- {
- aliases = {"scores", "score", "scoreset"},
- scrimBlock = true,
- help = [[-- Set Score
- -- Syntax: %s [Player] [Score]
- -- Set the score for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, score)
- local playerId
- for i = 1,#players do playerId = players[i]
- setscore(playerId, score)
- cmdreply[cmdreply()] = getname(playerId) .. " had their score set to " .. score
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setupright",
- {
- help = [[-- Set Vehicle Upright
- -- Syntax: %s {Player}
- -- Sets the player's vehicle upright if they are flipped]],
- },
- {
- arguments = {"Player", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, playerId)
- local playerId, m_vehicleObj
- for i = 1,#players do playerId = players[i]
- m_vehicleObj = getplayervehicle(playerId)
- if not m_vehicleObj then
- sendresponse(getname(playerId) .. " is not in a vehicle!", executorPlayerId)
- goto continue
- end
- writefloat(m_vehicleObj + 0x8A, 2.3 * (10 ^ -41))
- writefloat(m_vehicleObj + 0x8C, 2.3 * (10 ^ -41))
- writefloat(m_vehicleObj + 0x90, 2.3 * (10 ^ -41))
- writefloat(m_vehicleObj + 0x94, 2.3 * (10 ^ -41))
- writebit(m_vehicleObj + 0x10, 0, 0) -- Unset noCollisions bit.
- writebit(m_vehicleObj + 0x10, 5, 0) -- Unset ignorePhysics.
- sendresponse(getname(playerId) .. " had their vehicle set upright!", executorPlayerId)
- ::continue::
- end
- end
- }
- )
- Commands.Create(
- "setfrags",
- {
- aliases = {"setfrags", "frags", "fragset", "setfragnades"},
- scrimBlock = true,
- help = [[-- Set Frags
- -- Syntax: %s [Player] [Frags]
- -- Set the frags for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, frags)
- frags = frags > 7 and 7 or frags
- local playerId, m_playerObj, playerObjId
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- goto continue
- end
- writebyte(m_playerObj + 0x31E, frags)
- cmdreply[cmdreply()] = "Setting " .. getname(playerId) .. "'s frag grenades to " .. frags
- privatesay(playerId, "Your frag grenades were set to " .. frags)
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setplasmas",
- {
- aliases = {"setplasmas", "stickies", "plasmas", "plasmaset", "setplasmanades"},
- scrimBlock = true,
- help = [[-- Set Plasmas
- -- Syntax: %s [Player] [Plasmas]
- -- Set the plasmas for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, plasmas)
- plasmas = plasmas > 7 and 7 or plasmas
- local playerId, m_playerObj, playerObjId
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- goto continue
- end
- writebyte(m_playerObj + 0x31F, plasmas)
- cmdreply[cmdreply()] = "Setting " .. getname(playerId) .. "'s plasma grenades to " .. plasmas
- privatesay(playerId, "Your plasma grenades were set to " .. plasmas)
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "setprefix",
- {
- aliases = {"serverprefix"},
- help = [[-- Set Server Prefix
- -- Syntax: %s [Prefix]
- -- Will set the server prefix on sv_say messages to whatever you want (e.g. **SERVER** **MYCLAN** **PHASOR**)]]
- },
- {
- arguments = {"Remaining Arguments", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, prefix)
- if prefix == "default" then
- server_prefix = nil
- sendresponse("Prefix is now set to default.", executorPlayerId)
- elseif prefix then
- server_prefix = prefix
- sendresponse(server_prefix .. " is the new prefix.", executorPlayerId)
- else
- sendresponse(server_prefix .. " is the current prefix.", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "setmode",
- {
- aliases = {"modeset"},
- scrimBlock = true,
- help = [[-- mode
- -- Syntax: %s [Player] [Mode] {Object}
- -- destroy
- -- portalgun
- -- entergun
- -- spawngun
- -- normal]]
- },
- {
- arguments = {"Player", "String", "String", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, bulletmode)
- local playerId
- for i = 1,#players do playerId = players[i]
- if bulletmode == "destroy" then
- player_table[playerId].bulletmode = "destroy"
- cmdreply[cmdreply()] = getname(playerId) .. " is now in destroy mode"
- elseif bulletmode == "portalgun" then
- player_table[playerId].bulletmode = "portalgun"
- cmdreply[cmdreply()] = getname(playerId) .. " is now in portalgun mode"
- elseif bulletmode == "entergun" then
- player_table[playerId].bulletmode = "entergun"
- cmdreply[cmdreply()] = getname(playerId) .. " is now in entergun mode"
- elseif bulletmode == "normal" or bulletmode == "none" or bulletmode == "regular" then
- local ptable = player_table[playerId]
- ptable.objspawnid = false
- ptable.bulletmode = false
- cmdreply[cmdreply()] = getname(playerId) .. " is now in normal mode"
- else
- cmdreply[cmdreply()] = "Invalid mode"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- },
- {
- arguments = {"Player", "String", "String", "String", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, players, bulletmode, object)
- if bulletmode == "spawngun" then
- local thisObject = objects[object]
- if thisObject then
- local playerId, ptable
- for i = 1,#players do playerId = players[i]
- ptable = player_table[playerId]
- ptable.bulletmode = "spawngun"
- ptable.objspawnid = thisObject
- cmdreply[cmdreply()] = getname(playerId) .. " is now spawning " .. thisObject.name .. ""
- end
- else
- cmdreply[cmdreply()] = "Object does not exist. Make sure you are spelling it correctly."
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "pass",
- {
- aliases = {"password", "setpassword"},
- help = [[-- Set Server Password
- -- Syntax: %s {Password}]]
- },
- {
- arguments = {"Password", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, password)
- if not password then
- sendresponse(readstring(addresses.network_server_globals + 0x8, 8), executorPlayerId)
- elseif password == "" then
- writestring(addresses.network_server_globals + 0x8, 8, "")
- sendresponse("Password has been taken off", executorPlayerId)
- elseif password then
- writestring(addresses.network_server_globals + 0x8, 8, password)
- sendresponse("The password is now " .. password, executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "reloadadmins",
- {
- aliases = {"reloadadminlist", "adminlistreload", "adminsreload"},
- help = [[-- Reload Admin List
- -- Syntax: %s
- -- Loads all admins from the admin file.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- loadAllAdminFiles()
- -- We can now archive the other admin files without worrying about losing the data.
- os.rename(profilepath .. "ipadmins.txt", profilepath .. "archived_ipadmins.txt")
- os.rename(profilepath .. "admin.txt", profilepath .. "archived_admin.txt")
- sendresponse("All admins have been reloaded from the file.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "reloadbanlist",
- {
- aliases = {"reloadbans", "banlistreload", "reloadbanlist", "refreshipbans"},
- help = [[-- Reload Banlist
- -- Syntax: %s
- -- Loads all bans from the ban file.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- loadBanFile(profilepath .. "ipbans.txt", "ip") -- load sapp ip bans
- loadBanFile(profilepath .. "ipbanlist.txt", "ip") -- load ipbanlist file for backwards compatibility
- loadBanFile(profilepath .. "iprangebanlist.txt", "ip") -- load iprangebanlist file for backwards compatibility
- loadBanFile(profilepath .. "textbanlist.txt", "chat") -- load textbanlist file for backwards compatibility
- loadBanFile(profilepath .. "namebans.txt", "name") -- load textbanlist file for backwards compatibility
- loadBanFile(profilepath .. defaults.banlist_file .. ".txt")
- -- Check if a banned player is in the server.
- local hash, ip, ban_entry
- for playerId = 0,15 do
- if getplayer(playerId) then
- hash, ip = gethash(playerId), getip(playerId)
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.time ~= "Unbanned" and (ban_table.type == "hash" and hash == ban_table.hash or ban_table.type == "ip" and ban_table.ip == ip) then
- registertimer(0, "tempBanPlayer", resolveplayer(playerId))
- end
- end
- end
- end
- updateBanFiles()
- sendresponse("The Banlist has been reloaded.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "respawntime",
- {
- aliases = {"setresp"},
- help = [[-- Server Respawn Time
- -- Syntax: %s {Time}
- -- Sets the default respawn time for all players.]]
- },
- {
- arguments = {"Time", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, time)
- if time == -1 then
- sendresponse("Respawn time is currently: " .. (defaults.respawn_time ~= -1 and timetoword(defaults.respawn_time) or "Default"))
- else
- defaults.respawn_time = time
- sendresponse("Respawn time set to " .. (time ~= -1 and timetoword(time) or "Default"), executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "setspeed",
- {
- aliases = {"spd", "s", "speed", "speedset"},
- scrimBlock = true,
- help = [[-- Set Speed
- -- Syntax: %s [Player] {Speed}
- -- Allow you to view/change the selected players' speed]]
- },
- {
- arguments = {"Player", "Number", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, speed)
- local playerId, m_player
- if not speed then
- for i = 1,#players do playerId = players[i]
- speed = readfloat(getplayer(playerId) + 0x6C)
- sendresponse(getname(playerId) .. "'s speed is currently " .. speed, executorPlayerId)
- end
- else
- for i = 1,#players do playerId = players[i]
- setspeed(playerId, speed)
- sendresponse(getname(playerId) .. " had their speed changed to " .. speed, executorPlayerId)
- end
- end
- end
- }
- )
- Commands.Create(
- "setteleport",
- {
- aliases = {"teleportadd", "addteleport", "tadd", "st", "tpadd", "addtp", "addlocation", "locationadd"},
- help = [[--Set Teleport Location
- -- Syntax: %s [Location] [Player or X] {Y} {Z}
- -- Adds a teleport location wherever the specified player is standing.
- -- Or you can manually specify XYZ Coordinates for a location]]
- },
- {
- arguments = {"String", "Number", "Number", "Number", "String", minArgs = 4, maxArgs = 5},
- func = function(executorPlayerId, locname, x, y, z, map)
- locations[map or Map][locname] = TM{x, y, z}
- sendresponse("'" .. locname .. "' has been added as a teleport location!", executorPlayerId)
- end
- },
- {
- arguments = {"String", "Single Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, locname, playerId)
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- sendresponse("Cannot add teleport because the player is dead.", executorPlayerId)
- return
- end
- if locations[Map][locname] then
- sendresponse("Location '" .. locname .. "' already exists on this map!\nUse sv_teleport_del to remove it from the list first.", executorPlayerId)
- return
- end
- local x,y,z = getobjectcoords(playerObjId)
- locations[Map][locname] = TM{x, y, z}
- sendresponse("'" .. locname .. "' has been added as a teleport location!", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "teleportlist",
- {
- aliases = {"tlist", "listteleports", "locations", "teleports", "locs"},
- help = [[--List Teleport Locations
- -- Syntax: %s {Map}
- -- Lists all the teleport locations available for teleporting.]]
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId, map)
- sendresponse("Teleport Locations " .. (map and (" for map " .. map) or ""), executorPlayerId)
- cmdreply.header = "Map Location"
- cmdreply.align = true
- cmdreply.delim = " "
- for thisMap,mapLocations in next,locations do
- for locname,_ in next,mapLocations do
- if not map and Map == thisMap or map == thisMap then
- cmdreply[cmdreply()] = thisMap .. " " .. locname
- end
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- local function Spawn(players, amount, resp_time, bRecycle, obj_display_name, objtype, mapId, spawnmethod, executorPlayerId)
- amount = amount or 1
- bRecycle = bRecycle or false
- local playerId, m_playerObj, playerObjId, objectId, x, y, z, camera_x, camera_y
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- -- Spawn the object right where they are looking (should work for vehicles too)
- x,y,z = getobjectcoords(playerObjId)
- camera_x = readfloat(m_playerObj + 0x230)
- camera_y = readfloat(m_playerObj + 0x234)
- x = x + camera_x * 2
- y = y + camera_y * 2
- -- Check if they actually wanted to spawn something.
- if amount == 0 then sendresponse("You didn't spawn anything!", executorPlayerId) return end
- -- Create the object
- for i = 1,amount do
- objectId = createobject(mapId, 0, resp_time, bRecycle, x, y + i, z + i*2)
- end
- -- check if object was spawned correctly
- if objectId then
- if not spawnmethod then
- sendresponse(obj_display_name .. " spawned at " .. getname(playerId) .. "'s location.", executorPlayerId)
- elseif spawnmethod == "give" then
- assignweapon(playerId, objectId)
- sendresponse(obj_display_name .. " given to " .. getname(playerId), executorPlayerId)
- elseif spawnmethod == "enter" then
- local drones = player_table[playerId].drones
- drones[#drones+1] = objectId
- entervehicle(playerId, objectId, 0)
- sendresponse(getname(playerId) .. " was forced to enter a " .. obj_display_name, executorPlayerId)
- end
- else
- sendresponse("Error spawning object: " .. mapId, executorPlayerId)
- end
- else
- sendresponse("Player is dead", executorPlayerId)
- end
- end
- return objectId
- end
- Commands.Create(
- "spawn",
- {
- aliases = {"spawnobj", "create", "createobject", "spawnobject", "objspawn"},
- help = [[-- Spawn
- -- Syntax: %s [Object] [Player] {Amount} {Respawn Time} {Recycle Boolean}
- -- Spawns specified object near the specified player]]
- },
- {
- arguments = {"String", "Player", "Whole Number", "Number", "Boolean", minArgs = 1, maxArgs = 5},
- func = function(executorPlayerId, object, players, amount, resp_time, recycle, spawn_type)
- if not spawn_type then
- if object == "cyborg" or object == "bot" or object == "mastercheif" or object == "masterchief" then
- Spawn(players, amount, resp_time, recycle, "Cyborg", "bipd", gettag("bipd", "characters\\cyborg_mp\\cyborg_mp"), spawn_type, executorPlayerId)
- elseif object == "captain" or object == "keyes" then
- Spawn(players, amount, resp_time, recycle, "Captain Keyes", "bipd", gettag("bipd", "characters\\captain\\captain"), spawn_type, executorPlayerId)
- elseif object == "cortana" then
- Spawn(players, amount, resp_time, recycle, "Cortana", "bipd", gettag("bipd", "characters\\cortana\\cortana"), spawn_type, executorPlayerId)
- elseif object == "cortana2" then
- Spawn(players, amount, resp_time, recycle, "Cortana2", "bipd", gettag("bipd", "characters\\cortana\\halo_enhanced\\halo_enhanced"), spawn_type, executorPlayerId)
- elseif object == "crewman" then
- Spawn(players, amount, resp_time, recycle, "Crewman", "bipd", gettag("bipd", "characters\\crewman\\crewman"), spawn_type, executorPlayerId)
- elseif object == "elite" then
- Spawn(players, amount, resp_time, recycle, "elite", "bipd", gettag("bipd", "characters\\elite\\elite"), spawn_type, executorPlayerId)
- elseif object == "elite2" then
- Spawn(players, amount, resp_time, recycle, "Elite Special", "bipd", gettag("bipd", "characters\\elite\\elite special"), spawn_type, executorPlayerId)
- elseif object == "engineer" then
- Spawn(players, amount, resp_time, recycle, "Engineer", "bipd", gettag("bipd", "characters\\engineer\\engineer"), spawn_type, executorPlayerId)
- elseif object == "flood" then
- Spawn(players, amount, resp_time, recycle, "Flood Captain", "bipd", gettag("bipd", "characters\\flood_captain\\flood_captain"), spawn_type, executorPlayerId)
- elseif object == "flood2" then
- Spawn(players, amount, resp_time, recycle, "Flood Infection", "bipd", gettag("bipd", "characters\\flood_infection\\flood_infection"), spawn_type, executorPlayerId)
- elseif object == "flood3" then
- Spawn(players, amount, resp_time, recycle, "Flood Carrier", "bipd", gettag("bipd", "characters\\floodcarrier\\floodcarrier"), spawn_type, executorPlayerId)
- elseif object == "floodelite" then
- Spawn(players, amount, resp_time, recycle, "FloodCombat Elite", "bipd", gettag("bipd", "characters\\floodcombat elite\\floodcombat elite"), spawn_type, executorPlayerId)
- elseif object == "floodhuman" then
- Spawn(players, amount, resp_time, recycle, "FloodCombat Human", "bipd", gettag("bipd", "characters\\floodcombat_human\\floodcombat_human"), spawn_type, executorPlayerId)
- elseif object == "pedobear" or object == "grunt" then
- Spawn(players, amount, resp_time, recycle, "Pedobear", "bipd", gettag("bipd", "characters\\grunt\\grunt"), spawn_type, executorPlayerId)
- elseif object == "hunter" then
- Spawn(players, amount, resp_time, recycle, "Hunter", "bipd", gettag("bipd", "characters\\hunter\\hunter"), spawn_type, executorPlayerId)
- elseif object == "marine" then
- Spawn(players, amount, resp_time, recycle, "Marine", "bipd", gettag("bipd", "characters\\marine\\marine"), spawn_type, executorPlayerId)
- elseif object == "marinesuicide" or object == "marine2" then
- Spawn(players, amount, resp_time, recycle, "Marine Suicidal", "bipd", gettag("bipd", "characters\\marine_suicidal\\marine_suicidal"), spawn_type, executorPlayerId)
- elseif object == "monitor" then
- Spawn(players, amount, resp_time, recycle, "Monitor", "bipd", gettag("bipd", "characters\\monitor\\monitor"), spawn_type, executorPlayerId)
- elseif object == "sentinel" then
- Spawn(players, amount, resp_time, recycle, "Sentinel", "bipd", gettag("bipd", "characters\\sentinel\\sentinel"), spawn_type, executorPlayerId)
- elseif object == "johnson" then
- Spawn(players, amount, resp_time, recycle, "Sgt. Johnson", "bipd", gettag("bipd", "characters\\johnson\\johnson"), spawn_type, executorPlayerId)
- elseif object == "camo" or object == "camouflage" then
- Spawn(players, amount, resp_time, recycle, "Camouflage", "eqip", gettag("eqip", "powerups\\active camouflage"), spawn_type, executorPlayerId)
- elseif object == "dblspd" then
- Spawn(players, amount, resp_time, recycle, "Double Speed", "eqip", gettag("eqip", "powerups\\double speed"), spawn_type, executorPlayerId)
- elseif object == "fullspec" then
- Spawn(players, amount, resp_time, recycle, "Full-Spectrum Vision", "eqip", gettag("eqip", "powerups\\full-spectrum vision"), spawn_type, executorPlayerId)
- elseif object == "fnade" or object == "nades" then
- Spawn(players, amount, resp_time, recycle, "Frag Grenade", "eqip", gettag("eqip", "weapons\\frag grenade\\frag grenade"), spawn_type, executorPlayerId)
- elseif object == "pnade" then
- Spawn(players, amount, resp_time, recycle, "Plasma Grenade", "eqip", gettag("eqip", "weapons\\plasma grenade\\plasma grenade"), spawn_type, executorPlayerId)
- elseif object == "overshield" or object == "os" then
- Spawn(players, amount, resp_time, recycle, "Overshield", "eqip", gettag("eqip", "powerups\\over shield"), spawn_type, executorPlayerId)
- elseif object == "rifleammo" then
- Spawn(players, amount, resp_time, recycle, "Assault Rifle Ammo", "eqip", gettag("eqip", "powerups\\assault rifle ammo\\assault rifle ammo"), spawn_type, executorPlayerId)
- elseif object == "healthpack" then
- Spawn(players, amount, resp_time, recycle, "Health Pack", "eqip", gettag("eqip", "powerups\\health pack"), spawn_type, executorPlayerId)
- elseif object == "needlerammo" then
- Spawn(players, amount, resp_time, recycle, "Needler Ammo", "eqip", gettag("eqip", "powerups\\needler ammo\\needler ammo"), spawn_type, executorPlayerId)
- elseif object == "pistolammo" then
- Spawn(players, amount, resp_time, recycle, "Pistol Ammo", "eqip", gettag("eqip", "powerups\\pistol ammo\\pistol ammo"), spawn_type, executorPlayerId)
- elseif object == "rocketammo" then
- Spawn(players, amount, resp_time, recycle, "Rocket Ammo", "eqip", gettag("eqip", "powerups\\rocket launcher ammo\\rocket launcher ammo"), spawn_type, executorPlayerId)
- elseif object == "shottyammo" then
- Spawn(players, amount, resp_time, recycle, "Shotgun Ammo", "eqip", gettag("eqip", "powerups\\shotgun ammo\\shotgun ammo"), spawn_type, executorPlayerId)
- elseif object == "sniperammo" then
- Spawn(players, amount, resp_time, recycle, "Sniper Ammo", "eqip", gettag("eqip", "powerups\\sniper rifle ammo\\sniper rifle ammo"), spawn_type, executorPlayerId)
- elseif object == "flameammo" then
- Spawn(players, amount, resp_time, recycle, "Flamethrower Ammo", "eqip", gettag("eqip", "powerups\\flamethrower ammo\\flamethrower ammo"), spawn_type, executorPlayerId)
- end
- end
- if spawn_type ~= "enter" then
- if object == "energysword" or object == "esword" then
- Spawn(players, amount, resp_time, recycle, "Energy Sword", "weap", gettag("weap", "weapons\\energy sword\\energy sword"), spawn_type, executorPlayerId)
- elseif object == "ball" or object == "oddball" then
- Spawn(players, amount, resp_time, recycle, "Oddball", "weap", gettag("weap", "weapons\\ball\\ball"), spawn_type, executorPlayerId)
- elseif object == "flag" then
- Spawn(players, amount, resp_time, recycle, "Flag", "weap", gettag("weap", "weapons\\flag\\flag"), spawn_type, executorPlayerId)
- elseif object == "frg" or object == "fuelrod" or object == "rod" or object == "plasmacannon" then
- Spawn(players, amount, resp_time, recycle, "Fuel Rod", "weap", gettag("weap", "weapons\\plasma_cannon\\plasma_cannon"), spawn_type, executorPlayerId)
- elseif object == "ggun" or object == "gravitygun" then
- Spawn(players, amount, resp_time, recycle, "Gravity Gun", "weap", gettag("weap", "weapons\\gravity rifle\\gravity rifle"), spawn_type, executorPlayerId)
- elseif object == "needler" then
- Spawn(players, amount, resp_time, recycle, "Needler", "weap", gettag("weap", "weapons\\needler\\mp_needler"), spawn_type, executorPlayerId)
- elseif object == "pistol" then
- Spawn(players, amount, resp_time, recycle, "Pistol", "weap", gettag("weap", "weapons\\pistol\\pistol"), spawn_type, executorPlayerId)
- elseif object == "ppistol" or object == "plasmapistol" then
- Spawn(players, amount, resp_time, recycle, "Plasma Pistol", "weap", gettag("weap", "weapons\\plasma pistol\\plasma pistol"), spawn_type, executorPlayerId)
- elseif object == "prifle" or object == "plasmarifle" then
- Spawn(players, amount, resp_time, recycle, "Plasma Rifle", "weap", gettag("weap", "weapons\\plasma rifle\\plasma rifle"), spawn_type, executorPlayerId)
- elseif object == "rifle" or object == "arifle" or object == "assaultrifle" then
- Spawn(players, amount, resp_time, recycle, "Assault Rifle", "weap", gettag("weap", "weapons\\assault rifle\\assault rifle"), spawn_type, executorPlayerId)
- elseif object == "rocket" or object == "rocketlauncher" or object == "rox" then
- Spawn(players, amount, resp_time, recycle, "Rocket Launcher", "weap", gettag("weap", "weapons\\rocket launcher\\rocket launcher"), spawn_type, executorPlayerId)
- elseif object == "shotty" or object == "shotgun" then
- Spawn(players, amount, resp_time, recycle, "Shotgun", "weap", gettag("weap", "weapons\\shotgun\\shotgun"), spawn_type, executorPlayerId)
- elseif object == "sniper" or object == "sniperrifle" then
- Spawn(players, amount, resp_time, recycle, "Sniper Rifle", "weap", gettag("weap", "weapons\\sniper rifle\\sniper rifle"), spawn_type, executorPlayerId)
- elseif object == "flamer" or object == "flamethrower" then
- Spawn(players, amount, resp_time, recycle, "Flamethrower", "weap", gettag("weap", "weapons\\flamethrower\\flamethrower"), spawn_type, executorPlayerId)
- elseif spawn_type == "give" then
- goto objNotFound
- end
- if spawn_type == "give" then return end
- end
- if spawn_type ~= "give" then
- if object == "wraith" then
- Spawn(players, amount, resp_time, recycle, "Wraith", "vehi", gettag("vehi", "vehicles\\wraith\\wraith"), spawn_type, executorPlayerId)
- elseif object == "peli" or object == "pelican" then
- Spawn(players, amount, resp_time, recycle, "Pelican", "vehi", gettag("vehi", "vehicles\\pelican\\pelican"), spawn_type, executorPlayerId)
- elseif object == "ghost" then
- Spawn(players, amount, resp_time, recycle, "Ghost", "vehi", gettag("vehi", "vehicles\\ghost\\ghost_mp"), spawn_type, executorPlayerId)
- elseif object == "hog" or object == "warthog" then
- Spawn(players, amount, resp_time, recycle, "Warthog", "vehi", gettag("vehi", "vehicles\\warthog\\mp_warthog"), spawn_type, executorPlayerId)
- elseif object == "rhog" or object == "rocketwarthog" then
- Spawn(players, amount, resp_time, recycle, "Rocket Warthog", "vehi", gettag("vehi", "vehicles\\rwarthog\\rwarthog"), spawn_type, executorPlayerId)
- elseif object == "shee" or object == "banshee" then
- Spawn(players, amount, resp_time, recycle, "Banshee", "vehi", gettag("vehi", "vehicles\\banshee\\banshee_mp"), spawn_type, executorPlayerId)
- elseif object == "tank" or object == "scorpion" then
- Spawn(players, amount, resp_time, recycle, "Tank", "vehi", gettag("vehi", "vehicles\\scorpion\\scorpion_mp"), spawn_type, executorPlayerId)
- elseif object == "turret" or object == "shade" then
- Spawn(players, amount, resp_time, recycle, "Gun Turret", "vehi", gettag("vehi", "vehicles\\c gun turret\\c gun turret_mp"), spawn_type, executorPlayerId)
- else
- goto objNotFound
- end
- return
- end
- ::objNotFound::
- if spawn_type == "give" then
- sendresponse("Invalid Weapon", executorPlayerId)
- elseif spawn_type == "enter" then
- sendresponse("Invalid Vehicle", executorPlayerId)
- elseif not spawn_type then
- sendresponse("Invalid Object", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "enter",
- {
- aliases = {"entervehicle", "vehicleeneter", "vehienter", "entervehi"},
- scrimBlock = true,
- help = [[-- Enter Vehicle
- -- Syntax: %s [Player1 or Vehicle] [Player2]
- -- Force specified player into specified vehicle
- -- Or will put player1 into player2's vehicle, provided halo will let them.
- -- You cannot enter a vehicle of an enemy (unless sv_multiteam_vehicles is enabled in Free-For-All GameTypes)]]
- },
- {
- arguments = {"String", "Player", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, object, players) Commands.spawn[2].func(executorPlayerId, object, players, nil, nil, nil, "enter") end
- },
- {
- arguments = {"Player", "Single Player", "Whole Number", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, players, playerId2, seat)
- local m_vehicleObj, vehicleObjId = getplayervehicle(playerId2)
- if not m_vehicleObj then
- sendresponse(getname(playerId2) .. " is not in a vehicle!", executorPlayerId)
- return
- end
- local playerId
- for i = 1,#players do playerId = players[i]
- entervehicle(playerId, vehicleObjId, seat)
- sendresponse("Entering " .. getname(playerId) .. " into " .. getname(playerId2) .. "'s vehicle!", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "give",
- {
- aliases = {"giveweapon", "weapongive"},
- scrimBlock = true,
- help = [[-- Give
- -- Syntax: %s [Object] [Player]
- -- Gives specified player the specified weapon]]
- },
- {
- arguments = {"String", "Player", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, object, players) Commands.spawn[2].func(executorPlayerId, object, players, nil, nil, nil, "give") end
- }
- )
- Commands.Create(
- "spammax",
- {
- aliases = {"smax", "maxspam"},
- help = [[-- SpamMax
- -- Syntax: %s {Value or Boolean}
- -- Determines how many messages a player can send before a player is muted.
- -- Wizard recommends leaving this at the default, but you're welcome to change it
- -- Setting this to false or 0 will disable Spam Protection.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, boolean)
- if boolean == false and defaults.spam_max ~= false then
- defaults.spam_max = 0
- sendresponse("Spam protection is now disabled", executorPlayerId)
- elseif not boolean and defaults.spam_max == false then
- sendresponse("Spam protection is already disabled", executorPlayerId)
- elseif boolean then
- defaults.spam_max = 7
- sendresponse("Spam protection is now on!", executorPlayerId)
- end
- end
- },
- {
- arguments = {"Number", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, time)
- if time == -1 then
- sendresponse("The Spam max is currently '" .. defaults.spam_max .. "'", executorPlayerId)
- else
- defaults.spam_max = time
- sendresponse("The Spam max is now " .. time, executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "spamtimeout",
- {
- aliases = {"timeoutspam"},
- help = [[-- SpamTimeout
- -- Syntax: %s {Time}
- -- Changes the time you are muted for spamming]],
- },
- {
- arguments = {"Time", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, time)
- if time == -1 then
- sendresponse("Spam timeout is currently " .. timetoword(defaults.spam_timeout), executorPlayerId)
- else
- defaults.spam_timeout = time
- sendresponse("The Spam timeout is now " .. timetoword(time), executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "specs",
- {
- aliases = {"serverspecs", "machineinfo"},
- help = [[-- Specs
- -- Syntax: %s
- -- Display the server specifications (like processor, RAM, model, etc)]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- sendresponse("The server specs are: " .. readstring(addresses.computer_specs_address), executorPlayerId)
- end
- }
- )
- Commands.Create(
- "mc",
- {
- aliases = {"mcbegin", "startcycle", "cyclestart", "mapcyclebegin"},
- is_alias = true,
- help = [[-- Start MapCycle
- -- Syntax: %s
- -- Shortcut for sv_mapcycle_begin]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- sendresponse(halo_svcmd("sv_mapcycle_begin", true), executorPlayerId)
- end
- }
- )
- Commands.Create(
- "statusmore",
- {
- aliases = {"serverinfo", "sinfo", "sinfo"},
- help = [[-- Status
- -- Syntax: %s
- -- Shows a list of all the init.txt commands and their status.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- for key,value in next,defaults do
- cmdreply(capitalizeWords(key .. ": " .. value))
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "superban",
- {
- aliases = {"ultraban"},
- help = [[-- Superban
- -- Syntax: %s [Player] {Time}
- -- Bans a person via their Name, IP, and Hash
- -- Most likely overkill in most situations
- -- This command does the same as doing the following,
- -- where player is the player being banned, and time is a time if specified
- -- sv_ipban player time sv_nameban player sv_ban player time]],
- usesBanCounts = true,
- },
- {
- arguments = {"Player", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, players, time, reason)
- local exname = getname(executorPlayerId)
- local playerId, name, b
- for i = 1,#players do playerId = players[i]
- name = getname(playerId)
- if not checkAdminBlockerAccess(executorPlayerId, playerId) then
- sendresponse("You cannot use this command on " .. name, executorPlayerId)
- privatesay(playerId, exname .. " attemped to use SuperBan on you!")
- goto continue
- end
- reason = reason == "None Given" and "SuperBan" or reason
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", name .. " was Super-Banned by " .. exname .. " Reason: " .. reason .. " Type: All Bans")
- say(name .. " was Super Banned from the server! Reason: " .. reason)
- local b = TM.New()
- b.name,b.type,b.reason = name,"name","SuperBan"
- ban_table[#ban_table+1] = b
- addBan(name, nil, getip(playerId) .. "/24", time, "ip", reason)
- svcmd("sv_ban " .. resolveplayer(playerId) .. " " .. timetoword(time))
- ::continue::
- end
- end
- }
- )
- Commands.Create(
- "suspend",
- {
- aliases = {"suspendplayer", "playersuspend", "suspendpl", "sleep"},
- scrimBlock = true,
- help = [[-- Suspend Player
- -- Syntax: %s [Player] {Time}
- -- Kills a player and prevents them from respawning.]]
- },
- {
- arguments = {"Player", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, players, time, reason)
- reason = reason or "None Given"
- local playerId, iptable
- for i = 1,#players do playerId = players[i]
- iptable = ip_table[getip(playerId)]
- if iptable.suspended then
- cmdreply[cmdreply()] = getname(playerId) .. " has already been suspended."
- goto continue
- end
- local m_player = getplayer(playerId)
- kill(playerId)
- writedword(m_player + 0x2C, (time ~= -1 and time or 2880) * 30)
- iptable.suspended = time ~= -1 and time or true
- cmdreply[cmdreply()] = getname(playerId) .. " was suspended by an admin " .. (time ~= -1 and ("for " .. timetoword(time)) or "") .. " Reason: " .. reason
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "unsuspend",
- {
- aliases = {"unsuspendplayer", "unsuspendpl", "playerunsuspend"},
- help = [[-- Unsuspend player
- -- Syntax: %s [Player]
- -- Unsuspend the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- if not ip_table[getip(playerId)].suspended then
- sendresponse(getname(playerId) .. " has never been suspended.", executorPlayerId)
- goto continue
- end
- writedword(getplayer(playerId) + 0x2C, 0)
- sendresponse(getname(playerId) .. " has been unsuspended", executorPlayerId)
- ::continue::
- end
- end
- }
- )
- Commands.Create(
- "takeweapons",
- {
- aliases = {"removeweapons", "takeweaponspl", "takeweps"},
- scrimBlock = true,
- help = [[-- Take Weapons
- -- Syntax: %s [Player]
- -- Take all the weapons away from the specified player.]]
- },
- {
- arguments = {"Player", "Time", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, iptable, m_playerObj, playerObjId
- for i = 1,#players do playerId = players[i]
- ip_table[getip(playerId)].disarmed = true
- m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- for j = 1,4 do
- local m_weapon, weaponObjId = getplayerweapon(playerId, j)
- if m_weapon then
- destroyobject(weaponObjId)
- end
- end
- end
- cmdreply[cmdreply()] = getname(playerId) .. " now cannot pickup weapons"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "teleportdel",
- {
- aliases = {"tdel", "delteleport", "dellocation", "locationdel", "tpdel", "rmtel", "teldel", "deltel"},
- help = [[--Delete Teleport Location
- -- Syntax: %s [Location]
- -- Deletes the specified teleport location
- -- Use 'sv_teleport_list' to get a list of teleport locations.]]
- },
- {
- arguments = {"String", "String", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, locname, map)
- if map and not locations[map] then
- sendresponse("Invalid Map!", command, executorPlayerId)
- return
- end
- if map and locations[map][locname] then
- locations[map][locname] = nil
- sendresponse("Location '" .. locname .. "' on map '" .. map .. "' has been removed from the teleport locations list!", executorPlayerId)
- elseif Map and locations[Map][locname] then
- locations[Map][locname] = nil
- sendresponse("Location '" .. locname .. "' on map '" .. map .. "' has been removed from the teleport locations list!", executorPlayerId)
- else
- sendresponse("'" .. locname .. "' is not a teleport location\nUse sv_teleport_list for current teleport locations.", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "teleport",
- {
- aliases = {"tp", "t", "teletolocation", "tele"},
- help = [[--Teleport Player
- -- Syntax: %s [Player] [Player2 or Location or X] {Y} {Z}
- -- Teleports the specified players' to a location.
- -- Use 'sv_teleport_list' to get a list of teleport locations.
- -- You can also use this command to teleport to a set of XYZ coordinates]]
- },
- {
- arguments = {"Player", "Single Player", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, playerId2)
- local m_player2Obj, player2ObjId = getplayerobject(playerId2)
- if not m_player2Obj then
- sendresponse("The player you are trying to teleport to is dead!", executorPlayerId)
- return
- end
- local teletoname = getname(playerId2)
- local x,y,z = getobjectcoords(player2ObjId)
- local playerId, m_playerObj, playerObjId, m_vehicleObj, vehicleObjId
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = "The players you are trying to teleport are dead"
- goto continue
- end
- m_vehicleObj, vehicleObjId = getplayervehicle(playerId)
- movobjectcoords(m_vehicleObj and vehicleObjId or playerObjId, x, y, z+1)
- cmdreply[cmdreply()] = getname(playerId) .. " was teleported to " .. teletoname
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- },
- {
- arguments = {"Player", "String", minArgs = 2, maxArgs = 2},
- func = function(executorPlayerId, players, location)
- local thisLocation = locations[Map][location]
- if not thisLocation then
- sendresponse("Location '" .. location .. "' doesn't exist on this map!", executorPlayerId)
- return
- end
- -- A player can never exist unless the game is started on a map.
- local x,y,z = thisLocation[1], thisLocation[2], thisLocation[3]
- local playerId, m_playerObj, playerObjId, m_vehicleObj, vehicleObjId
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = getname(playerId) .. " is dead and cannot be teleported."
- goto continue
- end
- m_vehicleObj, vehicleObjId = getplayervehicle(playerId)
- movobjectcoords(m_vehicleObj and vehicleObjId or playerObjId, x, y, z+1)
- cmdreply[cmdreply()] = getname(playerId) .. " was teleported to " .. location
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- },
- {
- arguments = {"Player", "Number", "Number", "Number", minArgs = 4, maxArgs = 4},
- func = function(executorPlayerId, players, x, y, z)
- local playerId, m_playerObj, playerObjId, m_vehicleObj, vehicleObjId
- for i = 1,#players do playerId = players[i]
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- cmdreply[cmdreply()] = "The players you are trying to teleport are dead"
- goto continue
- end
- m_vehicleObj, vehicleObjId = getplayervehicle(playerId)
- movobjectcoords(m_vehicleObj and vehicleObjId or playerObjId, x, y, z+1)
- cmdreply[cmdreply()] = getname(playerId) .. " was teleported to " .. teletoname
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "textban",
- {
- aliases = {"mute", "muteplayer", "textbanplayer", "textban", "tban", "chatban", "playermute"},
- help = [[-- Text Ban
- -- Syntax: %s [Player] {Time}]],
- },
- {
- arguments = {"Player", "Time And Reason", minArgs = 1, maxArgs = 3},
- func = function(executorPlayerId, players, time, reason)
- local exname = getname(executorPlayerId)
- local playerId, name, ip, hash, ban_entry, iptable
- for i = 1,#players do playerId = players[i]
- name = getname(playerId)
- ip = getip(playerId)
- hash = gethash(playerId)
- iptable = ip_table[ip]
- if player_table[playerId].admin_entry then
- sendresponse("Admins cannot be banned from the chat!", executorPlayerId)
- else
- if iptable.muted then
- sendresponse(name .. " is already textbanned!", executorPlayerId)
- goto continue
- end
- iptable.muted = true
- addBan(name, hash, ip .. "/24", time, "chat", reason)
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", name .. " was text banned by " .. exname .. " Reason: " .. reason)
- say(name .. " was text banned from the server by an admin! Reason: " .. reason)
- sendresponse(time == -1 and (name .. " has been banned from the chat indefinitely") or (name .. " has been banned from the chat for " .. timetoword(time)), executorPlayerId)
- end
- ::continue::
- end
- end
- }
- )
- Commands.Create(
- "timecur",
- {
- aliases = {"curtime"},
- scrimBlock = true,
- help = [[-- Current Time
- -- Syntax: %s {Time}]]
- },
- {
- arguments = {"Time", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, time)
- if time == -1 then
- local time_passed = readdword(readdword(addresses.gameinfo_header) + 0xC) / 30
- local timelimit = timelimit_set_value or (readdword(addresses.gametype_base + 0x78) / 30)
- local time_left = timelimit - time_passed
- sendresponse("Current Timelimit is " .. timetoword(timelimit) .. ". Time remaining: " .. timetoword(time_left), executorPlayerId)
- else
- timelimit_set_value = time
- writedword(readdword(addresses.gameinfo_header) + 0xC, 0) -- set time passed to 0
- writedword(addresses.gametype_base + 0x78, readdword(readdword(addresses.gameinfo_header) + 0xC) + 30*time)
- sendresponse("Timelimit set to " .. timetoword(time), executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "unbos",
- {
- aliases = {"removebos", "bosremove", "unbanbos", "bosunban"},
- help = [[-- Remove from Ban on Sight List
- -- Syntax: %s [ID]
- -- Remove selected index off of the ban on sight list]]
- },
- {
- arguments = {"Positive Number", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, ID)
- local entry = bos_table[ID]
- if not entry then
- sendresponse("Invalid Entry", executorPlayerId)
- else
- sendresponse("Removing " .. entry.name .. " - " .. entry.hash .. " from BoS.", executorPlayerId)
- remove(bos_table, ID)
- end
- end
- }
- )
- Commands.Create(
- "ungod",
- {
- aliases = {"unsetgod", "removegod", "godunset", "godremove"},
- help = [[-- Ungod
- -- Syntax: %s [Player]
- -- Ungods the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, ptable
- for i = 1,#players do playerId = players[i]
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- ptable = player_table[playerId]
- if ptable.godmode then
- ptable.godmode = nil
- sendresponse(getname(playerId) .. " is no longer in godmode", executorPlayerId)
- else
- sendresponse(getname(playerId) .. " is not in godmode", executorPlayerId)
- end
- else
- sendresponse("The selected playerId is dead", executorPlayerId)
- end
- end
- end
- }
- )
- Commands.Create(
- "cheat_unhax",
- {
- aliases = {"unhax"},
- help = [[-- Cheat Unhax
- -- Syntax: %s [Player]
- -- Unhaxs the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId
- for i = 1,#players do playerId = players[i]
- local m_player = getplayer(playerId)
- setscore(playerId, 0)
- writeshort(m_player + 0x9C, 0)
- writeshort(m_player + 0xA4, 0)
- writeshort(m_player + 0xAC, 0)
- writeshort(m_player + 0xAE, 0)
- writeshort(m_player + 0xB0, 0)
- sendresponse(getname(playerId) .. " has been unhaxed", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "unhide",
- {
- aliases = {"removehide"},
- help = [[-- Unhide
- -- Syntax: %s [Player]
- -- Unhides the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, ptable
- for i = 1,#players do playerId = players[i]
- ptable = player_table[playerId]
- if ptable.hidden then
- sendresponse(getname(playerId) .. " is no longer hidden", executorPlayerId)
- ptable.hidden = false
- else
- sendresponse(getname(playerId) .. " was never hidden", executorPlayerId)
- end
- end
- end
- }
- )
- Commands.Create(
- "uninvis",
- {
- aliases = {"uncamo", "removeinvis", "removecamo"},
- help = [[-- Uninvis
- -- Syntax: %s [Player]
- -- Removes camouflage from the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, ptable
- for i = 1,#players do playerId = players[i]
- ptable = player_table[playerId]
- if not ptable.invisible then
- sendresponse(getname(playerId) .. " is not invisible", executorPlayerId)
- else
- ptable.invisible = false
- sendresponse(getname(playerId) .. " is no longer invisible", executorPlayerId)
- end
- end
- end
- }
- )
- Commands.Create(
- "unmute",
- {
- aliases = {"removemute"},
- help = [[-- Unmute
- -- Syntax: %s [Player]
- -- Unmutes the specified player.
- -- Will also remove their chat ban from the banlist]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, ip, iptable, ban_entry, found
- for i = 1,#players do playerId = players[i]
- ip = getip(playerId)
- iptable = ip_table[ip]
- if iptable.muted then
- iptable.muted = nil
- -- remove them from the textbanlist
- for id = 1,#ban_table do ban_entry = ban_table[i]
- if ban_entry.time ~= "Unbanned" and ban_entry.type == "chat" and netMatch(ban_entry.ip, ip) then
- sendresponse(getname(playerId) .. " has been unmuted", executorPlayerId)
- ban_table[id].time = "Unbanned"
- updateBanFiles()
- return
- end
- end
- if iptable.spamcounter < 0 then
- sendresponse(getname(playerId) .. " has been forgiven for spamming.", executorPlayerId)
- iptable.spamcounter = 0
- else
- sendresponse(getname(playerId) .. " is not found in any entries???", executorPlayerId)
- iptable.muted = false
- end
- else
- sendresponse(getname(playerId) .. " has not been muted.", executorPlayerId)
- end
- end
- end
- }
- )
- Commands.Create(
- "viewadmins",
- {
- aliases = {"curadmins", "adminscur"},
- help = [[-- Viewadmins
- -- Syntax: %s
- -- Shows Current Admins in the Server]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- sendresponse("The current admins in the server are listed below:", executorPlayerId)
- cmdreply.header = "[Level | Nickname | Name | Admin Type]"
- cmdreply.align = true
- cmdreply.delim = "|"
- local admin_entry
- for playerId = 0,15 do
- admin_entry = player_table[playerId].admin_entry
- if admin_entry then
- cmdreply[cmdreply()] = format("%s | %s | %s | %s", admin_entry.level, admin_entry.name, getname(playerId), (admin_entry.type == "ip" and "IP Admin" or "Hash Admin"))
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "votekick_action",
- {
- aliases = {"votekickaction"},
- help = [[-- Vote Kick Action
- -- Syntax: %s [Kick/Ban]
- -- Allows you to either ban or kick the player that has been voted out.]]
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, action)
- if not action then
- sendresponse("The current action for people who are votekicked is '" .. defaults.votekick_action .. "'", executorPlayerId)
- sendresponse("Valid actions are 'kick' and 'ban'", executorPlayerId)
- else
- sendresponse("The current VoteKick action has been changed to '" .. action .. "'", executorPlayerId)
- defaults.votekick_action = action
- end
- end
- }
- )
- Commands.Create(
- "votekick_timeout",
- {
- help = [[-- VoteKick Timeout
- -- Syntax: %s [Time]
- -- The amount of time between each votekick.]]
- },
- {
- arguments = {"Time", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, time)
- if time == -1 then
- sendresponse("VoteKick Timeout is currently " .. timetoword(defaults.votekick_timeout), executorPlayerId)
- else
- sendresponse("VoteKick Timeout has been set to " .. timetoword(time), executorPlayerId)
- defaults.votekick_timeout = time
- end
- end
- }
- )
- Commands.Create(
- "votekick_required",
- {
- aliases = {"votekickneeded"},
- help = [[-- Vote Kick Needed
- -- Syntax: %s [Percent]
- -- Allow you to change the number of votes needed for VoteKick to kick the player.]]
- },
- {
- arguments = {"Percent", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, percent)
- if not percent then
- sendresponse(defaults.votekick_required .. "% votes required for VoteKick", executorPlayerId)
- else
- sendresponse("Votes required for VoteKick has been set to " .. percent .. "%", executorPlayerId)
- defaults.votekick_required = percent
- end
- end
- }
- )
- function GetRequiredVersion()
- return 200
- end
- function OnScriptLoad(process, game, persistent)
- processid = process
- Persistent = persistent
- profilepath = getprofilepath()
- Game = game
- GetGameAddresses(game)
- writeword(addresses.special_chars_patch, 0x9090)
- writeword(addresses.gametype_patch, 0xEB)
- writeword(addresses.devmode_patch1, 0x9090)
- writeword(addresses.devmode_patch2, 0x9090)
- writebyte(addresses.color_patch, 0xEB)
- gametype = readbyte(addresses.gametype_base + 0x30)
- team_play = readbyte(addresses.gametype_base + 0x34) == 1
- -- This bit of code fixes the stupidness that is sv_public.
- -- Usually if sv_public is disabled, no one can join the server (or weird things start happening)
- -- This bit of code will fix that.
- --[[local public_status = readdword(addresses.public_value_address) == 0x10101
- if not public_status then
- writedword(addresses.public_value_address, 0x101)
- writestring(addresses.version_address, "01.23.45.6789") -- write a bad version string so it will never show in the lobby. (only if sv_public is false)
- end--]]
- local file = io.open("changelog_" .. script_version .. ".txt")
- if file then
- changelog = true
- file:close()
- else
- WriteChangeLog()
- end
- file = io.open("temp_" .. process .. ".tmp")
- if not file then
- file = io.open "defaults.txt"
- end
- local temp_commands_executed = TM.New()
- local words
- registertimer(0, "turnAdminCheckOff")
- -- don't worry, this isn't malicious code, this simply removes all of halo's bans so I can override them with my system (it's much better, I promise)
- -- No bans will be deleted, anything in banned.txt will be formatted exactly the same as it was before.
- writedword(addresses.banlist_header, 0) -- writing the number of bans to 0 seems to remove all bans, sweet
- local gameinfo_base = readdword(addresses.gameinfo_header)
- -- if game_info_base is nil, then this script is being loaded from the persistent folder, so we don't need to do anything (loading from the init now :D)
- if gameinfo_base and file then
- for line in file:lines() do
- if match(line, "[%w_]+%s+[%w%p]+") then
- -- used to call svcmd but I hate it using halo's servercommand call
- -- no need when I only want it to execute scripted commands anyway.
- OnServerCommand(nil, line)
- end
- words = tokenizecmdstring(line)
- temp_commands_executed[#temp_commands_executed+1] = words[1]
- end
- file:close()
- if filename == "temp_" .. processid .. ".tmp" then
- os.remove(filename)
- end
- elseif file then
- file:close()
- else
- file = io.open("defaults.txt", "a")
- hprintf " >> Defaults.txt not found. File will be created..."
- local command
- for command,value in next,defaults do
- file:write("sv_" .. command .. " " .. tostring(value) .. "\n")
- end
- file:close()
- end
- hprintf "-------------------------------------------------------------------------------"
- hprintf(" >> Command Script Version: " .. script_version .. " <<")
- if not changelog then
- hprintf(" >> [!] Change log Version " .. script_version .. " is being written [!] <<")
- end
- hprintf " >> Credit: Creator Wizard, Updater Aelite_Prime <<"
- hprintf " >> Xfire: th3w1zard3 <<"
- hprintf " >> Support: http://phasor.proboards.com/ <<"
- hprintf "-------------------------------------------------------------------------------"
- maintimer = registertimer(33, "MainTimer")
- file = io.open(defaults.sharedhash_file .. ".txt")
- if file then
- sharedhashes = TM.deleteEntries(sharedhashes)
- local iter = 0
- for line in file:lines() do
- iter = iter + 1
- sharedhashes[iter] = line
- end
- else
- file = io.open(defaults.sharedhash_file .. ".txt", "w")
- if file then
- file:write(concat(sharedhashes, "\n"))
- end
- end
- loadBanFile(profilepath .. "ipbans.txt", "ip") -- load sapp ip bans
- loadBanFile(profilepath .. "ipbanlist.txt", "ip") -- load ipbanlist file for backwards compatibility
- loadBanFile(profilepath .. "iprangebanlist.txt", "ip") -- load iprangebanlist file for backwards compatibility
- loadBanFile(profilepath .. "textbanlist.txt", "chat") -- load textbanlist file for backwards compatibility
- loadBanFile(profilepath .. "namebans.txt", "name") -- load textbanlist file for backwards compatibility
- loadBanFile(profilepath .. defaults.banlist_file .. ".txt")
- updateBanFiles()
- -- we're not going to remove the files, let's just rename them so we don't upset anyone.
- local timestamp = os.date "%Y_%m_%d_%H_%M_%S"
- os.rename(profilepath .. "ipbans.txt", profilepath .. "old_ipbans_" .. timestamp .. ".txt")
- os.rename(profilepath .. "ipbanlist.txt", profilepath .. "old_ipbanlist_" .. timestamp .. ".txt")
- os.rename(profilepath .. "iprangebanlist.txt", profilepath .. "old_iprangebanlist_" .. timestamp .. ".txt")
- os.rename(profilepath .. "textbanlist.txt", profilepath .. "old_textbanlist_" .. timestamp .. ".txt")
- os.rename(profilepath .. "namebans.txt", profilepath .. "old_namebans_" .. timestamp .. ".txt")
- -- Check if a banned player is in the server.
- local hash, ip
- for playerId = 0,15 do
- if getplayer(playerId) then
- hash, ip = gethash(playerId), getip(playerId)
- for i = 1,#ban_table do
- if ban_entry.time ~= "Unbanned" and ban_table.type == "hash" and hash == ban_table.hash or ban_table.type == "ip" and ban_table.ip == ip then
- registertimer(0, "tempBanPlayer", resolveplayer(playerId))
- end
- end
- end
- end
- loadAllAdminFiles()
- -- We can now archive the other admin files without worrying about losing the data.
- os.rename(profilepath .. "ipadmins.txt", profilepath .. "archived_ipadmins.txt")
- os.rename(profilepath .. "admin.txt", profilepath .. "archived_admin.txt")
- file = io.open(profilepath .. "access.ini")
- if file then
- local commands, lvlMatch, level, thisCommand
- local iter = 0
- for line in file:lines() do
- -- ignore blank lines
- if match(line, "%g%g%g+") then
- lvlMatch = tonumber(match(line, "%[([0-9]+)%]"))
- commands = match(line, "data=(.+)")
- if iter % 2 == 0 and lvlMatch then
- level = lvlMatch
- elseif iter % 2 ~= 0 and commands then
- if commands == "-1" then
- access_table[level] = -1
- else
- -- String full of commands this access level can execute.
- access_table[level] = TM{commands = commands}
- -- We want to set each access_table[level][command] to equal the actual true name of the command (e.g. Display Admins List).
- -- Doing this will allow command aliases like sv_rcon_add, /rcon_add, add_rcon etc to work without using AccessMerging anymore (yuck)
- commands = tokenizestring(commands, ",")
- for i = 1,#commands do
- thisCommand = Commands[getvalidformat(commands[i])]
- if thisCommand then
- access_table[level][thisCommand] = true
- end
- end
- end
- else
- error(profilepath .. "access.ini is formatted incorrectly! Line: " .. line)
- end
- iter = iter + 1
- end
- end
- file:close()
- end
- file = io.open(profilepath .. "data\\bos.data")
- if file then
- local name, hash, ip
- for line in file:lines() do
- name, hash, ip = match(line, "^(.-),(%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+),(%g+)$")
- ip = validate_ipv4(ip)
- bos_table[#bos_table+1] = TM{name = name, hash = hash, ip = ip}
- end
- file:close()
- end
- file = io.open(profilepath .. "data\\locations.txt")
- if file then
- local map, locname, x, y, z
- for line in file:lines() do
- map,locname,x,y,z = match(line, "^(%g+),(%g+),([%d%.%-]+),([%d%.%-]+),([%d%.%-]+)")
- x,y,z = tonumber(x), tonumber(y), tonumber(z)
- if locname and x and y and z then
- locations[map] = locations[map] or TM{}
- locations[map][locname] = TM{x, y, z}
- end
- end
- file:close()
- end
- -- Code for script reload.
- local gameinfo_base = readdword(addresses.gameinfo_header)
- -- If this script loads as a persistent script (in the persistent folder) this will sometimes be nil/0.
- if gameinfo_base and gameinfo_base ~= 0 then
- local gameinfo_time_passed = readdword(gameinfo_base + 0xC)
- -- Seems to not work when starting at 0.
- if gameinfo_time_passed >= 30 then
- gameend = false
- Map = readstring(addresses.map_name_address2)
- locations[Map] = locations[Map] or TM{}
- team_play = readbyte(addresses.gametype_base + 0x34) == 1
- LoadTags()
- local m_player, iptable
- for playerId = 0,15 do
- m_player = _G.getplayer(playerId)
- if m_player then
- cur_players = cur_players + 1
- -- Add player in the script's tables.
- player_table(playerId)
- iptable = ip_table(_G.getip(playerId), true)
- end
- end
- end
- end
- collectgarbage()
- end
- function turnAdminCheckOff(id, count)
- halo_svcmd "sv_admin_check false" -- stupid phasor :(
- -- Load Maplist and Gamelist.
- --[[local gmatch = string.gmatch
- for gametype in gmatch(concat(halo_svcmd("sv_maplist", true)), "%w+") do
- valid_maps[gametype] = true
- end
- for gametype in gmatch(concat(halo_svcmd("sv_gamelist", true)), "%w+") do
- valid_gametypes[gametype] = true
- end--]]
- return false
- end
- function OnScriptUnload()
- local writetbl = TM.New()
- local file = io.open(profilepath .. "data\\bos.data", "w")
- local bos_entry
- for id = 1,#bos_table do bos_entry = bos_table[id]
- writetbl[#writetbl+1] = bos_entry.name .. "," .. bos_entry.hash .. "," .. bos_entry.ip
- end
- file:write(concat(writetbl, "\n"))
- file:close()
- file = io.open(profilepath .. "data\\locations.txt", "w")
- local start = #writetbl+1
- for map,mapLocations in next,locations do
- for locname,thisLocation in next,mapLocations do
- writetbl[#writetbl+1] = map .. "," .. locname .. "," .. thisLocation[1] .. "," .. thisLocation[2] .. "," .. thisLocation[3]
- end
- end
- file:write(concat(writetbl, "\n", start))
- file:close()
- -- Continue to write these onscriptunload because they aren't as important as admins/bans and they're written to a lot more.
- file = io.open(profilepath .. "uniques.txt", "w")
- start = #writetbl+1
- for k,unique_entry in next,unique_table do
- if k ~= "total" then
- writetbl[#writetbl+1] = k .. "," .. unique_entry.joincount .. "," .. concat(unique_entry.names, ",")
- end
- end
- writetbl[#writetbl+1] = unique_table.total
- file:write(concat(writetbl, "\n", start))
- file:close()
- -- Write all script game variables to temp file
- file = io.open("temp_" .. processid .. ".tmp", "w")
- start = #writetbl+1
- for command,value in next,defaults do
- writetbl[#writetbl+1] = command .. " " .. tostring(value)
- end
- for rcon,level in next,rcon_passwords do
- writetbl[#writetbl+1] = "sv_rcon_add " .. rcon .. " " .. level
- end
- file:write(concat(writetbl, "\n", start))
- file:close()
- -- Clean up drones.
- for i = 0,15 do
- if getplayer(i) then
- cleanupdrones(i)
- end
- end
- end
- local isMuted
- function OnBanCheck(hash, ip)
- -- Do not let anyone with hacked hashes (they did some serious hacking and memory modding to change it to something like 'myfakehashlolz') into the game ever.
- if not match(hash, "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x+") then return false end
- local bos_entry
- for i = 1,#bos_table do bos_entry = bos_table[i]
- if bos_entry.ip == ip then
- for i = 0,15 do
- if player_table[i].admin_entry then
- sendconsoletext(i, bos_entry.name .. " banned from BoS.\nEntry: " .. bos_entry.name .. "- " .. bos_entry.ip)
- end
- end
- hprintf(bos_entry.name .. " banned from BoS.\nEntry: " .. bos_entry.name .. "- " .. bos_entry.ip)
- WriteLog(profilepath .. "logs\\" .. defaults.kickbans_file .. ".log", bos_entry.name .. " was Banned on Sight")
- addBan(bos_entry.name, nil, ip, nil, "ip", "Ban on Sight")
- return false
- end
- end
- local bReturn
- local ban_entry
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.time ~= "Unbanned" then
- if ban_entry.type == "ip" then
- if netMatch(ban_entry.ip, ip) then
- if ban_entry.time == -1 or ban_entry.time > os.time() then
- bReturn = false
- break
- end
- end
- elseif ban_entry.type == "hash" and hash == ban_entry.hash then
- bReturn = false
- break
- elseif ban_entry.type == "chat" and (ban_entry.hash == hash or ban_entry.ip == ip) then
- isMuted = true
- end
- end
- end
- return bReturn
- end
- function OnNameRequest(hash, name)
- hprintf(name .. " (" .. hash .. ") is attempting to join the server")
- local ban_entry
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.time ~= "Unbanned" and ban_entry.type == "name" then
- if ban_entry.name == name then
- return false, "NameBanned"
- end
- end
- end
- return nil
- end
- function OnPlayerJoin(playerId)
- local ptable = player_table(playerId)
- local ip = getip(playerId)
- local iptable = ip_table[ip] or ip_table(ip)
- -- write the team colors to the player (required since we are using the color patch)
- if team_play then
- writeword(getplayer(playerId) + 0x60, getteam(playerId)+2)
- end
- cur_players = cur_players + 1
- local name = getname(playerId)
- local hash = gethash(playerId)
- local iprange = match(ip, "^%d+%.%d+%.%d+")
- iptable.muted = iptable.muted or isMuted or false
- isMuted = nil
- if iptable.suspended then
- kill(playerId)
- writeword(getplayer(playerId) + 0x2C, tonumber(iptable.suspended) or 3000)
- end
- if defaults.uniques_enabled then
- if unique_table[hash] or unique_table[ip] or unique_table[iprange] then
- if defaults.wb_message then
- privatesay(playerId, "Welcome back " .. name .. "")
- end
- unique_table[hash] = unique_table[hash] or TM.New()
- unique_table[hash].joincount = (unique_table[hash].joincount or 0) + 1
- unique_table[ip] = unique_table[ip] or TM.New()
- unique_table[ip].joincount = (unique_table[ip].joincount or 0) + 1
- unique_table[iprange] = unique_table[iprange] or TM.New()
- unique_table[iprange].joincount = (unique_table[iprange].joincount or 0) + 1
- else
- unique_table[hash] = TM{joincount = 1, names = TM{name}}
- unique_table[ip] = TM{joincount = 1, names = TM{name}}
- unique_table[iprange] = TM{joincount = 1, names = TM{name}}
- unique_table.total = unique_table.total + 1
- if defaults.firstjoin_message then
- say("This is " .. name .. "'s first time in the server unique player #: " .. unique_table.total)
- end
- end
- end
- if defaults.sa_message then
- if player_table[playerId].admin_entry then
- hprintf("Server Admin: " .. name)
- Say("Server Admin: " .. name)
- end
- end
- if defaults.multiteam_vehicles then
- writebyte(getplayer(playerId) + 0x20, 0)
- end
- hprintf(name .. " has joined the game")
- end
- function OnPlayerLeave(playerId)
- cleanupdrones(playerId)
- cur_players = cur_players - 1
- local name = getname(playerId)
- local ip = getip(playerId)
- local iptable = ip_table[ip]
- if not gameend and iptable.tempadmin then
- iptable.tempadmin = false
- end
- if votekickPlayerId == playerId then
- votekicktimer = nil
- votekickPlayerId = nil
- votekick_counter = -defaults.votekick_timeout
- for i = 0,15 do
- if getplayer(i) then
- ip_table[getip(i)].used_votekick = false
- end
- end
- say "Votekick ending because votekicked player left the server!"
- end
- ResetPlayer(playerId)
- local left_entry = TM.New()
- left_entry.name = name
- left_entry.hash = gethash(playerId)
- left_entry.ip = ip
- leave_table[resolveplayer(playerId)] = left_entry
- hprintf(name .. " is leaving the game")
- player_table[playerId].player_struct = nil
- player_table[playerId].objectId = 0xFFFFFFFF
- player_table[playerId].object_struct = nil
- player_table[playerId].m_vehicleObj = nil
- player_table[playerId].vehicleObjId = 0xFFFFFFFF
- end
- function OnTeamChange(playerId, old_team, new_team, relevant)
- if team_play then
- writeword(getplayer(playerId) + 0x60, new_team+2)
- end
- end
- function OnPlayerSpawn(playerId)
- local ip = getip(playerId)
- local ptable = player_table[playerId]
- ptable.objectId = readdword(ptable.player_struct + 0x34)
- ptable.object_struct = getobject(ptable.objectId)
- local iptable = ip_table[ip]
- if defaults.noweapons or iptable.disarmed then
- local m_weapon, weaponObjId
- for slot = 1,4 do
- m_weapon, weaponObjId = getplayerweapon(playerId, slot)
- if m_weapon then
- destroyobject(weaponObjId)
- end
- end
- end
- if defaults.multiteam_vehicles then
- writebyte(ptable.player_struct + 0x20, 0)
- end
- if ptable.colorspawn then
- movobjectcoords(ptable.objectId, ptable.x, ptable.y, ptable.z)
- ptable.colorspawn = false
- end
- if iptable.suspended then iptable.suspended = false end
- if ptable.ghostmode then ptable.ghostmode = false end
- --writebit(m_playerObj + 0x10, 0, 1) -- both for ghostmode
- --writebit(m_playerObj + 0x10, 24, 0)
- end
- -- screw you phasor
- local mode = 1
- function OnNewGame(map)
- if Persistent then
- rtv_counter = 0
- for _,entry in next,ip_table do
- entry.rtv_rocked = false
- end
- end
- Map = map
- locations[map] = locations[map] or TM{}
- gameend = false
- team_play = readbyte(addresses.gametype_base + 0x34) == 1
- LoadTags()
- mode = 1
- -- reset cache on memoized functions.
- getObjType = memoize(getObjType) -- memoized
- tobinary = memoize(tobinary) -- memoized
- --tokenizestring = memoize(tokenizestring) -- memoized
- --tokenizecmdstring = memoize(tokenizecmdstring) -- memoized
- trim = memoize(trim) -- memoized
- capitalizeWords = memoize(capitalizeWords) -- memoized
- --formatOutput = memoize(formatOutput) -- memoized
- wildstring = memoize(wildstring) -- memoized
- getvalidformat = memoize(getvalidformat) -- memoized
- netMatch = memoize(netMatch) -- memoized
- long2ip = memoize(long2ip) -- memoized
- convertSign = memoize(convertSign) -- memoized
- ip2long = memoize(ip2long) -- memoized
- check_ip = memoize(check_ip) -- memoized
- validate_ipv4 = memoize(validate_ipv4) -- memoized
- getTimeAndReason = memoize(getTimeAndReason) -- memoized
- timetoword = memoize(timetoword) -- memoized
- wordtotime = memoize(wordtotime) -- memoized
- formatTime = memoize(formatTime) -- memoized
- objectidtoplayer = memoize(objectidtoplayer) -- memoized
- collectgarbage()
- end
- function OnGameEnd(mode_that_sometimes_lies)
- if mode == 1 then
- gameend = true
- for i = 0,15 do
- cleanupdrones(i)
- end
- collectgarbage()
- end
- mode = mode + 1
- end
- local function votekick()
- say("Removing " .. getname(votekickPlayerId) .. " from the server")
- if defaults.votekick_action == "ban" then
- svcmd("sv_ban " .. resolveplayer(votekickPlayerId) .. " 5m Votekicked with " .. votekick_counter .. " number of votes")
- else
- svcmd("sv_kick " .. resolveplayer(votekickPlayerId) .. " Votekicked with " .. votekick_counter .. " number of votes")
- end
- votekickPlayerId = nil
- if votekicktimer then
- removetimer(votekicktimer)
- votekicktimer = nil
- end
- votekick_counter = -defaults.votekick_timeout
- end
- function OnServerChat(playerId, chattype, message)
- local AllowChat, found, receiverPlayer
- if chattype == 4 then
- -- don't do anything if the server is private messaging someone.
- hprintf(gsub(message, "**SERVER**", "\n**SERVER TO " .. (playerId and getname(playerId)) .. "**"))
- if server_prefix then
- return true, gsub(message, "**SERVER**", server_prefix)
- end
- return nil
- elseif not playerId then
- -- do nothing here if the server is globally talking to everyone.
- hprintf("\n" .. message)
- if server_prefix then
- return true, gsub(message, "**SERVER**", server_prefix)
- end
- return nil
- end
- local name, hash, ip = getname(playerId), gethash(playerId), getip(playerId)
- local ptable = player_table[playerId]
- local iptable = ip_table[ip]
- if iptable.muted or iptable.spamcounter < 0 then
- return false
- end
- local t = tokenizestring(message, " ")
- local count = #t
- local cmd = t[1]
- if cmd == "rtv" or cmd == "skip" then
- if count ~= 1 then
- goto endchat
- end
- AllowChat = false
- if not defaults.rtv_enabled then
- privatesay(playerId, "Rockthevote is disabled.")
- goto endchat
- end
- if rtv_counter < 0 then
- privatesay(playerId, "You cannot initiate rtv at this time")
- goto endchat
- end
- local total_votes_required = round(cur_players * defaults.rtv_required * 0.01)
- if iptable.rtv_rocked then
- privatesay(playerId, "You have already voted for rtv")
- goto endchat
- end
- rtv_counter = rtv_counter + 1
- if rtv_counter == 1 then
- say(name .. " has initiated rtv")
- say('Type "rtv" to join the vote')
- rtvtimer = registertimer(defaults.rtv_timeout * 1000, "rtvTimer")
- else
- say(name .. " has voted for rtv")
- say(rtv_counter .. " of " .. total_votes_required .. " votes required for rtv")
- end
- iptable.rtv_rocked = true
- if rtv_counter >= total_votes_required then
- if rtvtimer then
- removetimer(rtvtimer)
- rtvtimer = nil
- end
- rtv_counter = -defaults.rtv_timeout
- say("Enough votes for rtv, game is now ending...")
- halo_svcmd "sv_map_next"
- end
- elseif cmd == "votekick" then
- if count ~= 2 then
- goto endchat
- end
- AllowChat = false
- if not defaults.votekick_enabled then
- privatesay(playerId, "Votekick is disabled")
- goto endchat
- end
- if iptable.used_votekick then
- privatesay(playerId, "You have already voted for a votekick!")
- goto endchat
- end
- if votekick_counter < 0 then
- privatesay(playerId, "Votekick will be available in " .. -votekick_counter .. " seconds")
- goto endchat
- elseif votekick_counter > 0 then
- privatesay(playerId, "There is already a votekick in progress.")
- goto endchat
- end
- local players = getvalidplayers(t[2])
- if not players then
- privatesay(playerId, "Invalid Player!")
- goto endchat
- end
- if players[2] then
- privatesay(playerId, "You can only votekick one player at a time!")
- goto endchat
- end
- receiverPlayer = players[1]
- if playerId == receiverPlayer then
- privatesay(playerId, "You cannot votekick yourself noob.")
- goto endchat
- end
- if player_table[receiverPlayer].admin_entry then
- privatesay(playerId, "Admins cannot be votekicked")
- goto endchat
- end
- local total_votes_required = round(cur_players*(defaults.votekick_required*0.01))
- votekickPlayerId = receiverPlayer
- iptable.used_votekick = true
- votekick_counter = votekick_counter + 1
- say(name .. ' has initiated a votekick on ' .. getname(receiverPlayer) .. '\n Type "kick" to join the vote\n 1 of ' .. total_votes_required .. ' votes required to kick')
- if votekick_counter >= total_votes_required then
- votekick()
- end
- elseif cmd == "kick" then
- if count ~= 1 then
- goto endchat
- end
- AllowChat = false
- if not defaults.votekick_enabled then
- privatesay(playerId, "Votekick is disabled")
- goto endchat
- end
- if iptable.used_votekick then
- privatesay(playerId, "You have already voted for a votekick!")
- goto endchat
- end
- if votekick_counter <= 0 then
- privatesay(playerId, "There is no votekick in progress. Use 'votekick (playerIndex)' to start one!")
- goto endchat
- end
- if playerId == votekickPlayerId then
- privatesay(playerId, "You cannot vote for yourself to be kicked noob")
- goto endchat
- end
- local total_votes_required = round(cur_players*(defaults.votekick_required*0.01))
- iptable.used_votekick = true
- votekick_counter = votekick_counter + 1
- say(name .. " has voted to kick " .. getname(votekickPlayerId))
- say(votekick_counter .. " of " .. total_votes_required .. " votes required to kick")
- if votekick_counter >= total_votes_required then
- votekick()
- end
- end
- receiverPlayer = match(cmd, "^@(%g+)$")
- if defaults.pm_enabled and receiverPlayer then
- AllowChat = false
- local players = getvalidplayers(receiverPlayer, playerId)
- if not players then
- privatesay(playerId, "There is no player identified as '" .. receiverPlayer .. "'")
- goto endchat
- end
- if #players > 4 then
- privatesay(playerId, "You cannot privatemessage more than 4 people at once!")
- goto endchat
- end
- local privatemessage = concat(t, " ", 2, #t)
- local names = TM.New()
- for i = 1,#players do receiverPlayer = players[i]
- if playerId == receiverPlayer then
- goto nextPlayer
- end
- names[i] = getname(receiverPlayer) .. " (" .. resolveplayer(receiverPlayer) .. ")"
- sendconsoletext(receiverPlayer, getname(playerId) .. ": (" .. resolveplayer(playerId) .. ") " .. privatemessage)
- ::nextPlayer::
- end
- sendconsoletext(playerId, "PM to " .. concat(names, ", ") .. " " .. privatemessage)
- end
- if sub(cmd, 1, 1) == "/" then
- output_environment = 2
- found = true
- AllowChat = true
- elseif sub(cmd, 1, 1) == "\\" then
- output_environment = 3
- found = true
- AllowChat = false
- end
- if found then
- if defaults.chatcommands then
- if cmd == "/e" then
- cmd = concat(t, " ", 2)
- sendresponse("Executed " .. cmd, playerId)
- sendresponse(svcmdplayer(cmd, playerId, true), playerId)
- --[[elseif cmd == "/l" or cmd == "/login" then
- remove(t, 1) -- command is not an argument
- Commands[cmd](t, cmd, playerId)--]]
- else
- sendresponse(svcmdplayer(message, playerId, true), playerId)
- end
- else
- privatesay(playerId, "Chat commands are currently disabled")
- end
- end
- ::endchat::
- if AllowChat ~= false and defaults.spam_max > 0 and (defaults.antispam == "all" or (defaults.antispam == "players" and not getaccess(playerId))) then
- iptable.spamcounter = iptable.spamcounter + 1
- end
- if AllowChat and defaults.anticaps then
- return true, lower(message)
- end
- -- Print a message to the console of the chat.
- hprintf("\nOnServerChat(" .. playerId .. ", " .. tostring(chattype) .. ") " .. getname(playerId) .. ": (" .. resolveplayer(playerId) .. ") " .. message)
- if AllowChat ~= false and defaults.chatids then
- return true, " (" .. resolveplayer(playerId) .. ") " .. message
- end
- return AllowChat
- end
- function rtvTimer(id, count)
- if rtv_counter > 0 then
- rtv_counter = -defaults.rtv_timeout
- for i = 0,15 do
- ip_table[getip(i)].rtv_rocked = false
- end
- say "The current rtv has expired"
- end
- return false
- end
- function rconBruteForceTimeout(id, count, iptable)
- if iptable.rcon_fails == 0 then
- iptable.rconfail_timer = nil
- return false
- end
- iptable.rcon_fails = iptable.rcon_fails - 1
- return true
- end
- local command_attempt
- -- this function is horrendously named, would you believe it's only SUPPOSED to be called when BAD rcon passwords are given?
- function OnServerCommandAttempt(playerId, command, password)
- command_attempt = true
- local t = tokenizecmdstring(command)
- local cmd = getvalidformat(t[1])
- -- EVEN IF the server is executing a command, we don't want it executing commands during scrimmode.
- if defaults.scrim_mode then
- -- Format our command.
- if Commands[cmd].scrim == false then
- sendresponse("This command is currently disabled.\nTurn Scrim mode off to reenable this command.", playerId)
- cmdlog(getname(playerId) .. " attempted to use " .. cmd .. " during scrim mode.")
- return false
- end
- end
- -- Do nothing if the server is executing a command
- if not playerId then return nil end
- -- If the player has gotten the password wrong too many times, stop them from executing any more commands for 5 minutes
- local iptable = ip_table[getip(playerId)]
- if iptable.rcon_fails == 10 then
- if iptable.rconfail_timer then
- iptable.rcon_fails = iptable.rcon_fails + 1
- else
- iptable.rconfail_timer = registertimer(1000, "rconBruteForceTimeout", iptable)
- end
- return false
- end
- if password then
- output_environment = 1
- end
- -- We now have several cases here.
- -- If there are no admins, anyone can use the generic rcon
- -- If there are admins, then only admins can use the generic rcon
- -- If there is no generic rcon (sv_rcon_password set to "any"), admins can use any rcon password they want.
- -- If there is no password given, it is a chatcommand and we need to check their access.
- -- Everyone can use global rcons (in the rcon_passwords table).
- local permission = false
- local access
- -- Check out global passwords (sv_rcon_add)
- local level = password and rcon_passwords[password]
- if level then
- permission = checkaccess(Commands[cmd], level)
- else
- access = next(admin_table) and getaccess(playerId)
- local generic_rcon = readstring(addresses.network_server_globals + 0x128)
- -- Check if a password wasn't given (chat command), there is no generic rcon (sv_rcon_password is DISABLED), or if the generic rcon = the password given
- -- Only does this check if they are admin
- if access and (not password or generic_rcon == "any" or generic_rcon == password) then
- permission = checkaccess(Commands[cmd], access)
- end
- end
- if not permission then
- local admin_entry = player_table[playerId].admin_entry
- if level then
- cmdlog(" >>Security Alert: " .. getname(playerId) .. " (Nickname: " .. (admin_entry and admin_entry.name or "N/A") .. " Hash:" .. gethash(playerId) .. " IP: " .. getip(playerId) .. ") tried to execute: '" .. command .. "'")
- sendresponse("This Rcon does not have access to that command. This will be reported.", playerId)
- elseif password then
- if not access then
- cmdlog(getname(playerId) .. " (Nickname: " .. (admin_entry and admin_entry.name or "N/A") .. " Hash:" .. gethash(playerId) .. " IP: " .. getip(playerId) .. ") tried to use '" .. password .. "' as an rcon password")
- sendresponse("You are not an admin. This will be reported", playerId)
- elseif not level then
- cmdlog(getname(playerId) .. " (Nickname: " .. (admin_entry and admin_entry.name or "N/A") .. " Hash:" .. gethash(playerId) .. " IP: " .. getip(playerId) .. ") tried to use '" .. password .. "' as an rcon password")
- sendresponse("That is not an rcon password", playerId)
- end
- else
- cmdlog(getname(playerId) .. " (Nickname: " .. (admin_entry and admin_entry.name or "N/A") .. " Hash:" .. gethash(playerId) .. " IP: " .. getip(playerId) .. ") tried to execute: '" .. command .. "'")
- sendresponse("You cannot execute this command.", playerId)
- goto ReturnPermission
- end
- iptable.rcon_fails = iptable.rcon_fails + 1
- ::ReturnPermission::
- command_attempt = false
- end
- return permission
- end
- function OnServerCommand(playerId, command)
- -- this is to prevent infinite loops from when I want to execute a halo command
- -- without creating infinite loops (continually calling my sv_unban which will then continually call this etc)
- if dont_call_onservercommand then return nil end
- -- this means that a valid password was given so oncommandattempt was never actually called.
- -- It also means the command came using the console, and not the chat
- if not command_attempt then
- if OnServerCommandAttempt(playerId, command, readstring(addresses.network_server_globals + 0x128)) == false then
- return false
- elseif playerId then
- output_environment = 1
- end
- else
- command_attempt = nil
- end
- local response, thisCommand
- local t = tokenizecmdstring(command)
- local count = #t
- -- Format our command.
- local cmd = getvalidformat(t[1])
- if cmd == "help" or cmd == "gethelp" then
- response = false
- thisCommand = Commands[getvalidformat(t[2])] or count == 3 and Commands[getvalidformat(t[2] .. " " .. t[3])]
- if thisCommand and thisCommand.help then
- sendresponse(thisCommand.help, playerId)
- else
- sendresponse("No help topics for command '" .. tostring(t[2]) .. "'", playerId)
- end
- else
- -- this is a bit hacky, but I've made hackier stuff before, plus this will always work :D
- -- Code for commands with spaces in it.
- local testCmd
- while count >= 2 do
- testCmd = getvalidformat(concat(t, " ", 1, 2))
- thisCommand = Commands[testCmd]
- if thisCommand then
- t[1] = testCmd
- cmd = getvalidformat(testCmd)
- remove(t, 2)
- count = count - 1
- -- we done
- else
- break
- end
- end
- thisCommand = Commands[cmd]
- -- First possibility: a command gets truncated in a valid format, and this function recognizes it as a script command
- if thisCommand then
- response = false
- local origCommand = t[1]
- remove(t, 1) -- the command isn't an argument.
- thisCommand:Execute(t, origCommand, playerId)
- -- this means it is NOT one of my scripted commands.
- else
- local message
- local newcmd = command
- local cmdWeirdFormat
- if sub(newcmd, 1, 1) == "/" or sub(newcmd, 1, 1) == "\\" then
- newcmd = sub(newcmd, 2)
- cmdWeirdFormat = command
- end
- -- Second Possibility: the command needs an appended sv_ at the beginning
- if sub(newcmd, 1, 3) ~= "sv_" then
- cmdWeirdFormat = cmdWeirdFormat or "sv_" .. newcmd
- message = halo_svcmd(newcmd, true)
- if type(message) ~= "table" or type(message[1]) ~= "string" or find(concat(message), "Requested function \"") then
- message = halo_svcmd("sv_" .. newcmd, true)
- end
- response = false
- end
- -- Send back the message from the non-scripted command.
- if type(message) == "table" and type(message[1]) == "string" and not find(concat(message), "Requested function \"") then
- message[1] = "RESPONSE: " .. message[1]
- sendresponse(message, playerId)
- elseif response == false then
- sendresponse("Command \"" .. t[1] .. "\" not found.", playerId)
- end
- end
- end
- if playerId and response == false then
- cmdlog(format("%s (Nickname: %s Hash: %s IP: %s) has executed: %s", (player_table[playerId].admin_entry and player_table[playerId].admin_entry.name or "N/A"), getname(playerId), gethash(playerId), getip(playerId), command))
- end
- -- Third Possibility: if this was a chat command that was trying to execute a non-scripted command, then execute that command (returning false will do nothing)
- if output_environment >= 2 and response ~= false then
- halo_svcmd(cmd)
- end
- return response
- end
- function OnPlayerKill(killerPlayerId, victimPlayerId, mode)
- cleanupdrones(victimPlayerId)
- local vtable = player_table[victimPlayerId]
- local ktable = player_table[killerPlayerId]
- vtable.godmode = false
- if defaults.respawn_time then
- writedword(getplayer(victimPlayerId) + 0x2C, defaults.respawn_time * 30)
- end
- if mode == 4 then
- if defaults.tbag_detection then
- ktable.tbagname = getname(victimPlayerId)
- ktable.tbagcount = 0
- vtable.tbagcount = 0
- vtable.x,
- vtable.y,
- vtable.z = getobjectcoords(vtable.objectId)
- end
- if defaults.killing_spree then
- local m_kplayer = getplayer(killerPlayerId)
- local kname = getname(killerPlayerId)
- local multikill = readword(m_kplayer + 0x98)
- if multikill == 2 then
- sendconsoletext(killerPlayerId, "Double Kill")
- elseif multikill == 3 then
- sendconsoletext(killerPlayerId, "Triple Kill")
- elseif multikill == 4 then
- sendconsoletext(killerPlayerId, "OverKill")
- elseif multikill == 5 then
- sendconsoletext(killerPlayerId, "Killtacular")
- elseif multikill == 6 then
- sendconsoletext(killerPlayerId, "Killtrocity")
- elseif multikill == 7 then
- sendconsoletext(killerPlayerId, "Killimanjaro")
- elseif multikill == 8 then
- sendconsoletext(killerPlayerId, "Killtastrophe")
- elseif multikill == 9 then
- sendconsoletext(killerPlayerId, "Killpocalypse")
- elseif multikill >= 10 then
- sendconsoletext(killerPlayerId, "Killionaire")
- end
- local spree = readword(m_kplayer + 0x96)
- if spree == 5 then
- Say(kname .. " is on a Killing Spree", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "Killing Spree")
- elseif spree == 10 then
- Say(kname .. " is on a Killing Frenzy", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "Killing Frenzy")
- elseif spree == 15 then
- Say(kname .. " is on a Running Riot", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "Running Riot")
- elseif spree == 20 then
- Say(kname .. " is on a Rampage", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "Rampage")
- elseif spree == 25 then
- Say(kname .. " is Untouchable", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "Untouchable")
- elseif spree == 30 then
- Say(kname .. " is Invincible", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "Invincible")
- elseif spree == 35 then
- Say(kname .. " is Inconceivable", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "Inconceivable")
- elseif spree >= 40 and spree%2 == 0 then
- Say("OMFGWTFBBQWAFFLES " .. kname .. " is Unfrigginbelievable", 1, killerPlayerId)
- sendconsoletext(killerPlayerId, "OMFGWTFBBQWAFFLES Unfrigginbelievable")
- end
- end
- end
- vtable.objectId = 0xFFFFFFFF
- vtable.object_struct = nil
- end
- function playerWeaponCheckTimer(id, count)
- for playerId = 0,15 do
- if not getplayer(playerId) then
- goto continue
- end
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- goto continue
- end
- local pweaptable = player_table[playerId].weapons
- local m_weaponObj, weaponObjId
- for slot = 1,4 do
- weaponObjId = readdword(m_playerObj + 0x2F8+(slot-1)*4)
- m_weaponObj = getobject(weaponObjId)
- if m_weaponObj and weaponObjId ~= pweaptable[slot] then
- writeshort(m_weaponObj + 0x2B6, 0x7CFF)
- writeshort(m_weaponObj + 0x2B8, 0x7CFF)
- updateammo(weaponObjId)
- pweaptable[slot] = weaponObjId
- end
- end
- ::continue::
- end
- return true
- end
- function OnClientUpdate(playerId)
- if not defaults.tbag_detection then
- return
- end
- local ptable = player_table[playerId]
- if ptable.m_vehicleObj then
- return
- end
- local playerObjId = getplayerobjectid(playerId)
- local m_playerObj = getobject(playerObjId)
- if not m_playerObj then
- return
- end
- if ptable.tbagname == "" then
- return
- end
- local crouching = readbyte(m_playerObj + 0x2A0) == 3
- if not ptable.crouch and crouching then
- ptable.tbagcount = (ptable.tbagcount or 0) + 1
- if ptable.tbagcount == 4 then
- ptable.tbagcount = 0
- ptable.tbagname = ""
- say(getname(playerId) .. " is T-Bagging " .. ptable.tbagname)
- end
- ptable.crouch = true
- elseif ptable.crouch and not crouching then
- ptable.crouch = false
- end
- end
- function OnObjectInteraction(playerId, objectId, mapId)
- if defaults.noweapons or ip_table[getip(playerId)].disarmed then
- if getObjType(objectId) == 2 then
- return false
- end
- end
- return nil
- end
- function OnVehicleEntry(playerId, vehicleObjId, seat, mapId, relevant)
- local ptable = player_table[playerId]
- ptable.m_vehicleObj = getobject(vehicleObjId)
- ptable.vehicleObjId = vehicleObjId
- end
- function OnVehicleEject(playerId, voluntary)
- local ptable = player_table[playerId]
- ptable.m_vehicleObj = nil
- ptable.vehicleObjId = 0xFFFFFFFF
- end
- function OnDamageApplication(receiverObjId, causerObjId, tagId, hit, backtap)
- if getobject(causerObjId) then
- local playerId = objectidtoplayer(causerObjId)
- if playerId then
- local ptable = player_table[playerId]
- if ptable.bulletmode == "destroy" then
- destroyobject(receiverObjId)
- elseif ptable.bulletmode == "entergun" then
- local m_receiverObj = getobject(receiverObjId)
- if m_receiverObj then
- local objtype = readword(m_receiverObj + 0xB4)
- if objtype == 1 then -- check if object is a vehicle
- entervehicle(playerId, receiverObjId, 0)
- end
- end
- end
- end
- end
- end
- function OnDamageLookup(receiverObjId, causerObjId, mapId, tagdata)
- local receivingPlayerId = objectidtoplayer(receiverObjId)
- if not defaults.falldamage and (mapId == gettag("jpt!", "globals\\falling") or mapId == gettag("jpt!", "globals\\distance")) then
- odl_multiplier(0.001)
- elseif defaults.deathless or (receivingPlayerId and player_table[receivingPlayerId].godmode) then
- odl_multiplier(0.001)
- local dmg_side_effect = readword(tagdata + 0x1C4)
- if dmg_side_effect == 2 or dmg_side_effect == 3 then
- writeword(tagdata + 0x1C4, 0)
- registertimer(0, "DamageAddressReset", TM{tagdata, 0x1C4, dmg_side_effect})
- end
- elseif causerObjId and receivingPlayerId then
- local causingPlayerId = objectidtoplayer(causerObjId)
- local m_causingPlayer, m_receivingPlayer = getplayer(causingPlayerId), getplayer(receivingPlayerId)
- if m_receivingPlayer and m_causingPlayer and causingPlayerId ~= receivingPlayerId then
- local ptable = player_table[causingPlayerId]
- if ptable.dmgmultiplier ~= 1 then
- odl_multiplier(ptable.dmgmultiplier)
- end
- if defaults.multiteam_vehicles then
- local count = getteam(receivingPlayerId)
- while getteam(causingPlayerId) == count do
- count = count + 1
- end
- writebyte(m_receivingPlayer + 0x20, count)
- registertimer(0, "multiteamtimer", receivingPlayerId)
- end
- end
- end
- return nil
- end
- function multiteamtimer(id, count, playerId)
- local m_player = getplayer(playerId)
- if m_player and defaults.multiteam_vehicles then
- writebyte(m_player + 0x20, 0)
- end
- return false
- end
- function DamageAddressReset(id, count, userdata)
- local address = userdata[1]
- local offset = userdata[2]
- local orig_value = userdata[3]
- writeword(address + offset, orig_value)
- return false
- end
- local TempObjectTable = {}
- function OnObjectCreationAttempt(mapId, parentObjId, playerId)
- TempObjectTable[1] = mapId
- TempObjectTable[2] = playerId
- return nil
- end
- function OnObjectCreation(objectId)
- if defaults.infinite_ammo then
- local m_object = getobject(objectId)
- if m_object then
- local obj_type = readword(m_object, 0xB4)
- if obj_type == 2 then -- check if it is a weapon
- writeshort(m_object + 0x2B6, 0x7CFF)
- writeshort(m_object + 0x2B8, 0x7CFF)
- end
- return -- we can safely return here
- end
- end
- local mapId, playerId = TempObjectTable[1], TempObjectTable[2]
- if getplayer(playerId) then
- if mapId ~= gettag("proj", "weapons\\flamethrower\\flame")
- and mapId ~= gettag("proj", "weapons\\needler\\mp_needle")
- and mapId ~= gettag("proj", "weapons\\frag grenade\\frag grenade")
- and mapId ~= gettag("proj", "weapons\\plasma grenade\\plasma grenade") then
- local ptable = player_table[playerId]
- if ptable.bulletmode == "portalgun" then
- registertimer(100, "portalgunTimer", TM{getplayerobjectid(playerId), objectId})
- elseif ptable.bulletmode == "spawngun" then
- registertimer(100, "spawngunTimer", TM{playerId, objectId})
- end
- end
- end
- end
- function portalgunTimer(id, count, arg)
- local playerObjId = arg[1]
- local bulletObjId = arg[2]
- local m_bulletObj = getobject(bulletObjId)
- if count < 100 and getobject(bulletObjId) then
- if readfloat(m_bulletObj + 0x68) == 0 then
- local x,y,z = getobjectcoords(bulletObjId)
- if getobject(playerObjId) then
- movobjectcoords(playerObjId, x, y, z)
- end
- else
- return true
- end
- end
- return false
- end
- function spawngunTimer(id, count, arg)
- local playerId = arg[1]
- local playerObjId = arg[2]
- if getobject(playerObjId) then
- local x,y,z = getobjectcoords(playerObjId)
- createobject(player_table[playerId].objspawnid, 0, 60, false, x, y, z+0.6)
- end
- return false
- end
- function MainTimer(id, count)
- -- For hiding.
- local m_player
- for i = 0,15 do
- if player_table[i].hidden then
- m_player = getplayer(i)
- if m_player then
- writefloat(m_player + 0x100, -100)
- end
- end
- end
- -- will run every second
- if count % 30 == 0 then
- -- local variables used
- local ip, name, ptable, iptable
- -- For invisible timer, suspended timer, and message spamming.
- for i = 0,15 do
- if getplayer(i) then
- ptable = player_table[i]
- if ptable.invisible == -1 then
- applycamo(i, 1)
- elseif ptable.invisible then
- applycamo(i, 1)
- ptable.invisible = ptable.invisible - 1
- if ptable.invisible <= 0 then
- ptable.invisible = false
- end
- end
- iptable = ip_table[getip(i)]
- if type(iptable.suspended) == "number" and iptable.suspended ~= 0 then
- iptable.suspended = iptable.suspended - 1
- end
- -- Player is currently muted for spamming, add 1 second from their timeout_table until they are at 0 (or above).
- if iptable.spamcounter < 0 then
- iptable.spamcounter = iptable.spamcounter + 1
- if iptable.spamcounter > 0 then
- say(getname(i) .. " has been unmuted")
- iptable.spamcounter = 0
- end
- -- Player has spammed too many messages, mute them for spamming
- elseif iptable.spamcounter > defaults.spam_max then
- say(getname(i) .. " has been muted for " .. defaults.spam_timeout .. " seconds for spamming")
- iptable.spamcounter = -defaults.spam_timeout
- -- Player has sent a message within 1 second, will take 4 seconds to remove from spam counter.
- elseif iptable.spamcounter > 0 then
- iptable.spamcounter = iptable.spamcounter - 0.25
- end
- end
- end
- -- RTV Counter
- if rtv_counter < 0 then
- rtv_counter = rtv_counter + 1
- if rtv_counter == 0 then
- say "RTV can be started again."
- end
- end
- -- VoteKick Counter
- if votekick_counter < 0 then
- votekick_counter = votekick_counter + 1
- if votekick_counter == 0 then
- say "VoteKick can be started again!"
- end
- end
- end
- return true
- end
Recent Pastes