- --Creator: Wizard
- --Script Name: Command Script
- --Website: http://phasorscripts.wordpress.com/
- --Xfire: th3w1zard3
- --Check Change Log for information on the updates
- --Thank you AElite 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
- --
- -- Counts
- local cur_players = 0
- local rtv_counter = 0
- local votekick_counter = 0
- local scorelimit = 50
- -- Strings
- local script_version = "5.2 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 http
- local flameId
- local Map
- local output_environment = -1
- local Persistent
- local processid
- local profilepath
- local server
- local server_prefix
- local someoneHidden = false
- local socket
- local team_play
- local team_play_temp
- local time_passed_value
- local timelimit_set_value
- local votekickPlayerId
- -- Local variables defined for decreased execution time (but mostly 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 = "{ "
- if next(t) then
- for k,v in next,t do
- if v == t then goto nextVal end
- k = type(k) ~= "number" 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
- -- Tables
- local access_table = {}
- --local addresses
- local admin_table = {}
- local ban_table = {}
- local ban_penalty = {}
- local bos_table = {}
- local Commands = {commandAliases = {}}
- Commands.__index = Commands -- class setup
- local commandAliases = Commands.commandAliases
- local connections = {}
- local cmdreply = setmetatable({index = 0}, {
- __mode = "v", -- weak table
- __len = function(self) return (rawget(self, "index") or 0) end,
- --old method
- --[[
- __newindex = function(self, key, value)
- if not tonumber(key) then
- return
- end
- local index = rawget(self, "index")
- rawset(self, "index", value and (index+1) or (index-1)) -- update the index.
- rawset(self, key, value or rawget(self, index))
- 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
- })
- local clients = {}
- local debug_players = {}
- -- REM: change back cobalthidden before release.
- local player_colors = {[0] = "white", "black", "red", "blue", "grey", "yellow", "green", "pink", "purple", "cyan", "cobalthidden", "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, cobalthidden = 10, orange = 11, teal = 12, sage = 13, brown = 14, tan = 15, maroon = 16, salmon = 17}
- local team_colors = {[0] = "red", "blue", "white", "black", "pink", "yellow", "cobalthidden", "orange", "purple", "cyan", "maroon", "teal", "green", "sage", "brown", "salmon"}
- local player_scores = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
- local team_scores = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
- -- 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",
- remote_bansystem = false,
- remotecontrol = false,
- --tkban_type = "ip",
- adminblocker = 0,
- anticaps = false,
- antispam = "players",
- chatcommands = true,
- chatids = true,
- crouch_camo = false,
- deathless = false,
- debug_mode = 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 = -1,
- 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 identities = {}
- identities.__index = identities
- local leave_table = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}
- local locations = {} -- map = {locname = {x, y, z}}
- local spawnWeapons = {}
- local tag_table = {}
- local objects
- local playerMT = {}
- local PlayerClass = {
- [0]={drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}},
- {drones = TM{}, weapons = {}}
- }
- PlayerClass.__index = PlayerClass
- for i = 0,15 do
- setmetatable(PlayerClass[i], PlayerClass)
- end
- local randomNames = {
- Butcher = 1,
- Caboose = 2,
- Crazy = 3,
- Cupid = 4,
- Darling = 5,
- Dasher = 6,
- Disco = 7,
- Donut = 8,
- Dopey = 9,
- Ghost = 10,
- Goat = 11,
- Grumpy = 12,
- Hambone = 13,
- Hollywood = 14,
- Howard = 15,
- Jack = 16,
- Killer = 17,
- King = 18,
- Mopey = 19,
- Noodle = 20,
- Penguin = 21,
- Pirate = 22,
- Prancer = 23,
- Saucy = 24,
- Shadow = 25,
- Sleepy = 26,
- Snake = 27,
- Sneak = 28,
- Stompy = 29,
- Stumpy = 30,
- ["The Bear"] = 31,
- ["The Big L"] = 32,
- Tooth = 33,
- ["Walla Walla"] = 34,
- Weasel = 35,
- Wheezy = 36,
- Whicker = 37,
- Whisp = 38,
- Wilshire = 39
- }
- local rcon_passwords = {}
- local sharedhashes = {
- ["f443106bd82fd6f3c22ba2df7c5e4094"] = 1,
- ["c702226e783ea7e091c0bb44c2d0ec64"] = 2,
- ["d72b3f33bfb7266a8d0f13b37c62fddb"] = 3,
- ["55d368354b5021e7dd5d3d1525a4ab82"] = 4,
- ["3d5cd27b3fa487b040043273fa00f51b"] = 5,
- ["b661a51d4ccf44f5da2869b0055563cb"] = 6,
- ["740da6bafb23c2fbdc5140b5d320edb1"] = 7,
- ["10440b462f6cbc3160c6280c2734f184"] = 8,
- ["7503dad2a08026fc4b6cfb32a940cfe0"] = 9,
- ["4486253cba68da6786359e7ff2c7b467"] = 10,
- ["f1d7c0018e1648d7d48f257dc35e9660"] = 11,
- ["40da66d41e9c79172a84eef745739521"] = 12,
- ["2863ab7e0e7371f9a6b3f0440c06c560"] = 13,
- ["34146dc35d583f2b34693a83469fac2a"] = 14,
- ["b315d022891afedf2e6bc7e5aaf2d357"] = 15,
- ["81f9c914b3402c2702a12dc1405247ee"] = 16,
- ["63bf3d5a51b292cd0702135f6f566bd1"] = 17,
- ["6891d0a75336a75f9d03bb5e51a53095"] = 18,
- ["325a53c37324e4adb484d7a9c6741314"] = 19,
- ["0e3c41078d06f7f502e4bb5bd886772a"] = 20,
- ["fc65cda372eeb75fc1a2e7d19e91a86f"] = 21,
- ["f35309a653ae6243dab90c203fa50000"] = 22,
- ["50bbef5ebf4e0393016d129a545bd09d"] = 23,
- ["a77ee0be91bd38a0635b65991bc4b686"] = 24,
- ["3126fab3615a94119d5fe9eead1e88c1"] = 25,
- ["d41d8cd98f00b204e9800998ecf8427e"] = 26
- }
- local threads = {} -- list of all live threads
- local unique_table = TM(setmetatable({total = 0}, {__len = function(self) return self.total end}))
- local valid_maps = {}
- local valid_gametypes = {}
- -- Send Debug Messages
- local function sendDebugMessage(message)
- local playerId
- for playerId = 0,15 do
- if debug_players[playerId] then
- sendconsoletext(playerId, message)
- end
- end
- end
- -- Private Functions
- -- 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 read 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
- local 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 read 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
- -- crash prevention code.
- local function createobject(mapId, ...)
- if mapId and mapId ~= 0 and mapId ~= -1 then
- return _G.createobject(mapId, ...)
- end
- end
- local function getteam(playerId)
- if defaults.multiteam_vehicles or not team_play then
- return playerId
- end
- return _G.getteam(playerId)
- end
- -- 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
- 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 an 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
- 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
- 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
- local function convertSign(num, maxSize)
- return num - bit32.band(num, maxSize)*2
- end
- 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
- local function netMatch(network, ip)
- network = validate_ipv4(network)
- if not network then return end
- -- 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
- local function iptoplayer(ip)
- for playerId = 0,15 do
- if getplayer(playerId) and netMatch(getip(playerId) .. "/24", ip) then
- return playerId
- end
- end
- end
- local function getobject(objectId)
- return objectId and _G.getobject(objectId) or nil
- end
- -- hides a phasor bug where player 1 gets output from privatesay in their console...
- local function privatesay(playerId, message, appendServer)
- _G.privatesay(playerId, message, appendServer)
- 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 privateSayAdmins(message)
- for playerId = 0,15 do
- if getplayer(playerId) and PlayerClass[playerId].admin_entry then
- sendconsoletext(playerId, message)
- privatesay(playerId, message)
- end
- end
- end
- local function getname(playerId)
- return playerId and _G.getname(playerId) or "the Server"
- end
- local function getMorePowerfulAdmin(adminEntry1, adminEntry2)
- local access1 = #access_table[adminEntry1.level]
- local access2 = #access_table[adminEntry2.level]
- return access1 > access2 and adminEntry1 or access1 < access2 and adminEntry2 or access1 > 0
- end
- local function lookupAdminEntry(playerId)
- local ip = getip(playerId)
- local retIndex = gethash(playerId)
- local highestEntry = admin_table[retIndex]
- local morePowerfulAdmin
- for index,thisAdmin in next,admin_table do
- if thisAdmin.type == "ip" and netMatch(index, ip) then
- morePowerfulAdmin = highestEntry and getMorePowerfulAdmin(thisAdmin, highestEntry) or thisAdmin
- if type(morePowerfulAdmin) == "table" then
- highestEntry = morePowerfulAdmin
- retIndex = index
- end
- end
- end
- return highestEntry, highestEntry and retIndex
- end
- -- Table Methods and Metamethods.
- function getOrCreateIdentities(hash, ip, name, playerId) -- arguments: hash, ip, name, playerId
- local length, probably_unique_name, ip_addresses, names, hash_identity, ip_identity, name_identity
- hash_identity = identities[hash]
- ip_identity = identities[ip]
- name_identity = identities[name]
- -- check the ip range to see if it matches an already existing entry.
- if not ip_identity then
- for ip_key,v in next,identities do
- if validate_ipv4(ip_key) and netMatch(ip, ip_key) then
- ip_identity = identities[ip_key]
- break
- end
- end
- end
- if hash_identity then
- if not ip_identity then
- ip_addresses = hash_identity.ip_addresses
- length = #ip_addresses+1
- ip_addresses[length] = ip
- ip_addresses[ip] = length
- for i = 1,#ip_addresses do
- ip_identity = identities[ip_addresses[i]]
- if ip_identity then
- identities[ip] = ip_identity
- break
- end
- end
- end
- if not name_identity then
- names = hash_identity.names
- length = #names+1
- names[length] = name
- names[name] = length
- for i = 1,#names do
- name_identity = identities[names[i]]
- if name_identity then
- identities[name] = name_identity
- break
- end
- end
- end
- hash_identity.playerId = playerId
- end
- if ip_identity then
- if not hash_identity and not sharedhashes[hash] then
- hash_identity = identities[ip]
- identities[hash] = hash_identity
- identities[ip].hash = hash
- end
- if not name_identity and not randomNames[name] then
- names = ip_identity.names
- length = #names+1
- names[length] = name
- names[name] = length
- for i = 1,#names do
- name_identity = identities[names[i]]
- if name_identity then
- identities[name] = name_identity
- break
- end
- end
- end
- ip_identity.playerId = playerId
- end
- if name_identity then
- if not hash_identity and not sharedhashes[hash] then
- hash = name_identity.hash
- hash_identity = identities[hash]
- identities[hash] = hash_identity
- end
- if not ip_identity then
- ip_addresses = hash_identity.ip_addresses
- length = #ip_addresses+1
- ip_addresses[length] = ip
- ip_addresses[ip] = length
- for i = 1,#ip_addresses do
- ip_identity = identities[ip_addresses[i]]
- if ip_identity then
- identities[ip] = ip_identity
- break
- end
- end
- end
- name_identity.playerId = playerId
- end
- ::CreateIdentity::
- --Create a new identity for this new player.
- if not ip_identity then
- identity = {playerId = playerId}
- --identity.index = identifier
- identity.hash = sharedhashes[hash] and {} or hash
- identity.ip_addresses = {ip, [ip] = 1}
- identity.names = randomNames[name] and {} or {name, [name] = 1}
- identities[hash] = identity
- identities[ip] = identity
- identities[name] = identity
- identity.disarmed = false
- identity.tempadmin = false
- identity.spamcounter = 0
- identity.rcon_fails = 0
- identity.rconfail_timer = -1
- identity.muted = false
- identity.playerId = playerId
- -- Calculate unique identity id by count.
- identities[#identities+1] = identity
- --registered_names[name] = identity -- automatically register this name to this Hash/IP
- return identity, identity, identity
- end
- return hash_identity, ip_identity, name_identity
- end
- -- Not currently using this, if I remember correctly.
- --[[function PlayerClass:__newindex(key, value)
- if rawget(self, key) ~= nil then
- rawset(self, key, value)
- return
- end
- local hash_identity = identities[rawget(self, "hash")]
- if hash_identity then rawset(hash_identity, key, value) end
- local ip_identity = identities[rawget(self, "ip")]
- if ip_identity then rawset(ip_identity, key, value) end
- local name_identity = identities[rawget(self, "name")]
- if name_identity then rawset(name_identity, key, value) end
- end--]]
- function PlayerClass:__index(key)
- --hprintf(TM.__tostring(PlayerClass[2]))
- local identity = rawget(self, "hash_identity") or rawget(identities, rawget(self, "hash"))
- if identity then
- return rawget(identity, key)
- end
- local fallback_identity = rawget(self, "ip_identity") or rawget(identities, rawget(self, "ip"))
- if fallback_identity then
- return rawget(fallback_identity, key)
- end
- identity = rawget(self, "name_identity") or rawget(identities, rawget(self, "name"))
- if identity then
- return rawget(identity, key)
- end
- -- This will be used if all player identifiers are not unique
- return rawget(fallback_identity, key)
- end
- function PlayerClass:Initialize(playerId)
- local player = rawget(PlayerClass, playerId)
- local hash, ip, name = gethash(playerId), getip(playerId), getname(playerId)
- rawset(player, "admin_entry", lookupAdminEntry(playerId) or false)
- player.drones:deleteEntries()
- rawset(player, "hash", hash)
- rawset(player, "ip", ip)
- rawset(player, "name", name)
- -- Update our identities.
- local hash_identity, ip_identity, name_identity = getOrCreateIdentities(hash, ip, name, playerId)
- rawset(player, "hash_identity", hash_identity)
- rawset(player, "ip_identity", ip_identity)
- rawset(player, "name_identity", name_identity)
- rawset(player, "afk", false)
- rawset(player, "bulletmode", false)
- rawset(player, "colorspawn", false)
- rawset(player, "crouch", false)
- rawset(player, "dmgmultiplier", 1)
- rawset(player, "godmode", false)
- rawset(player, "ghostmode", false)
- rawset(player, "invisible", false)
- rawset(player, "hidden", false)
- rawset(player, "objspawnid", false)
- rawset(player, "player_struct", getplayer(playerId) or false)
- rawset(player, "playerId", playerId)
- rawset(player, "playerIndex", resolveplayer(playerId) or -1)
- rawset(player, "tbagname", "")
- rawset(player, "x", 0)
- rawset(player, "y", 0)
- rawset(player, "z", 0)
- return player
- end
- local function GetGameAddresses(game)
- if _SERVERAPP == "Sapp" then
- addresses = { -- check these against the module to confirm they're all the same (these should take preference)
- stats_globals = read_dword(sig_scan("33C0BF??????00F3AB881D") + 0x3), -- Confirmed. (Thanks Giraffe)
- ctf_globals = read_dword(sig_scan("C6000083C0303D??????00")+8), -- Confirmed.
- slayer_globals = read_dword(sig_scan("5733C0B910000000BFE8E05B00F3ABB910000000") + 19), -- Confirmed,
- oddball_globals = read_dword(sig_scan("BF??????00F3ABB951000000")+0x1), -- Confirmed.
- koth_globals = read_dword(sig_scan("BF??????00F3ABB96B000000")+0x1), -- Confirmed.
- race_globals = read_dword(sig_scan("BF??????00F3ABB952000000")+0x1), -- Confirmed.
- race_locs = 0x5F5078,
- gametype_base = read_dword(sig_scan("B9360000008BF3BF78545F00")+0x8), -- Confirmed.
- network_struct = read_dword(sig_scan("F3ABA1????????BA????????C740??????????E8????????668B0D") + 3),
- player_header_pointer = read_dword(sig_scan("DDD8A1??????008944244835") + 0x3), -- Confirmed (Thanks Giraffe)
- object_header_pointer = read_dword(sig_scan("8B0D????????8B513425FFFF00008D") + 2), -- Confirmed. (Thanks 002)
- collideable_objects_pointer = 0x6C69F4,
- map_header_base = 0x6E2C84,
- banlist_header = read_dword(sig_scan("A3??????00A1??????0033DB3BC3")+1), -- Confirmed.
- game_globals = nil, -- Don't care.
- gameinfo_header = read_dword(sig_scan("A1????????8B480C894D00") + 0x1), -- Confirmed. (Thanks Wizard)
- mapcycle_header = 0x598A8C,
- network_server_globals = 0x61FB44,
- hash_table_base = 0x5AFB14, -- Untested.
- -- Strings (Thanks to Giraffe for all the sigs in this section!)
- broadcast_version_address = read_dword(sig_scan("751768??????0068??????00BA") + 0x3), -- Confirmed.
- version_info_address = nil, -- Don't care.
- broadcast_game_address = read_dword(sig_scan("CCCCBA??????002BD08A08") + 0x3), -- Confirmed (halor = PC, halom = CE)
- server_ip_argument = read_dword(sig_scan("BA??????008BC72BD78A08880C024084C975F68B442404") + 0x1), -- Confirmed.
- server_port_address = read_dword(sig_scan("668B0D??????000BF2C605") + 0x3), -- Confirmed.
- server_path_address = read_dword(sig_scan("0000BE??????005657C605") + 0x3), -- Confirmed.
- computer_name_address = read_dword(sig_scan("68??????0068??????0068000401006A00") + 0x1), -- Confirmed
- profile_path_address = read_dword(sig_scan("68??????008D54245468") + 0x1), -- Confirmed.
- map_name_address =read_dword(sig_scan("66A3??????00890D??????00C3") + 0x2), -- Confirmed. (Full name)
- hardware_info_address = read_dword(sig_scan("BE??????008BC68B4DF064890D000000005F5E5B8BE55DC36A0C") + 0x1), -- Confirmed.
- map_name_address2 = read_dword(sig_scan("B8??????00E8??????0032C983F813") + 0x1), -- Confirmed. (File name)
- server_password_address = read_dword(sig_scan("F3ABA3??????00A3??????00A2??????00C705") + 0x3), -- Confirmed.
- logfile_path_address = read_dword(sig_scan("740ABB????5C00E8????0300") + 0x3), -- Confirmed. (CE Only)
- banlist_path_address = read_dword(sig_scan("68??????00E8??????0083C41068") + 0x1), -- Confirmed.
- banlist_path_address2 = read_dword(sig_scan("CCCCC605??????0000E8??????0085C0") + 0x4), -- Confirmed.
- --Patches
- rcon_password_address = read_dword(sig_scan("7740BA??????008D9B000000008A01") + 0x3), -- Confirmed.
- rcon_failed_address = read_dword(sig_scan("B8????????E8??000000A1????????55") + 1), -- Found by 002
- kill_message_address = read_dword(sig_scan("8B42348A8C28D500000084C9") + 3), -- Found by sehe (Write to 0x03EB01B1)
- color_patch1 = read_dword(sig_scan("741F8B482085C9750C")), -- Found by 002 (Write to 235 if not 0)
- color_patch2 = read_dword(sig_scan("EB1F8B482085C9750C")), -- Found by 002 (Write to 235)
- nonslayer_score_patch = sig_scan("8B??3883C404????74??57FFD0")+0x8, -- 0xEB = patched, 0x74 = normal
- slayer_score_patch = sig_scan("74178B94242808000052518B8C24280800005157FFD083C4108B8424240800003BF8530F94C383FFFF") -- 0xEB = patched, 0x74 = normal
- }
- --[[while true do
- cprint("nonslayer: " .. tostring(addresses.nonslayer_score_patch) .. " slayer: " .. tostring(addresses.slayer_score_patch))
- end--]]
- elseif game == "PC" then
- addresses = {
- -- Structs/headers.
- stats_header = 0x639720,
- stats_globals = 0x639898,
- ctf_globals = 0x639B98,
- slayer_globals = 0x63A0E8,
- oddball_globals = 0x639E58,
- koth_globals = 0x639BD0,
- race_globals = 0x639FA0,
- race_locs = 0x670F40,
- 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,
- mapcycle_timeout = 0x614AC0,
- 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
- nonslayer_score_patch = 0x47F382, -- 0xEB = patched, 0x74 = normal
- slayer_score_patch = 0x47F5D5, -- 0xEB = patched, 0x74 = normal
- ctf_msgs_patch = 0x481545, -- 0xEB = patched, 0x74 = normal
- color_patch = 0x4828FE, -- 0xEB = patched, 0x74 = normal
- devmode_patch1 = 0x4A4DBF, -- 0xEB = patched, 0x74 = normal
- devmode_patch2 = 0x4A4E7F, -- 0xEB = patched, 0x74 = normal
- servername_patch = 0x517D6B, -- 0x9090 = patched, 0x4B74 = normal
- hash_duplicate_patch = 0x59C518, -- 0x9090 = patched, 0xFD3B = normal
- hashcheck_patch = 0x59c280, -- 0xEB = patched, 0x74 = normal
- versioncheck_patch = 0x5152E7 -- 0xEB = patched, 0x7D = normal
- }
- 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,
- 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,
- mapcycle_timeout = 0x598A00,
- 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
- nonslayer_score_patch = 0x45BCB0, -- 0xEB = patched, 0x74 = normal
- slayer_score_patch = 0x45BE15, -- 0xEB = patched, 0x74 = normal
- ctf_msgs_patch = 0x45DA95, -- 0xEB = patched, 0x74 = normal
- color_patch = 0x45EB5E, -- 0xEB = patched, 0x74 = normal
- devmode_patch1 = 0x47DF0C, -- 0xEB = patched, 0x74 = normal
- devmode_patch2 = 0x47DFBC, -- 0xEB = patched, 0x74 = normal
- servername_patch = 0x4CE0CD, -- 0x9090 = patched, 0x4B74 = normal
- hash_duplicate_patch = 0x5302E8, -- 0x9090 = patched, 0xFD3B = normal
- hashcheck_patch = 0x530130, -- 0xEB = patched, 0x74 = normal
- versioncheck_patch = 0x4CB587, -- 0xEB = patched, 0x7D = normal
- }
- 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) or ""
- 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 = assert(tonumber(low), "bad argument #1 to 'rand' (number expected, got " .. type(low) .. ")")
- high = assert(tonumber(high), "bad argument #2 to 'rand' (number expected, got " .. type(high) .. ")")
- return getsuckyrand(low, high)
- end
- local getrandomnumber = rand
- -- I am having weird issues with resolveplayer not working correctly, so I'm overriding it.
- local function resolveplayer(playerId)
- return playerId and PlayerClass[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.
- local 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
- -- This is the same as getplayerobjectid except it returns BOTH the player's object struct and playerObjId
- -- Returns the object struct and the object ID, or nil.
- local function getplayerobject(playerId)
- local playerObjId = playerObjId or getplayerobjectid(playerId)
- return getobject(playerObjId), playerObjId
- end
- -- Gets the object ID of the player's vehicle.
- -- Accepts argument 'playerId' (memory ID)
- -- Returns the vehicle's object ID, or nil
- local function getplayervehicleid(playerId)
- local m_playerObj = getplayerobject(playerId)
- return m_playerObj and readdword(m_playerObj + 0x11C)
- 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 vehicleObjId = getplayervehicleid(playerId)
- return getobject(vehicleObjId), vehicleObjId
- 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.
- -- 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)
- local m_playerObj = getplayerobject(playerId)
- 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
- -- This function will determine if the given playerId is currently in a vehicle or not.
- -- This function will return a boolean.
- -- This function was created because I was having problems with Phasor's isinvehicle function.
- local function isinvehicle(playerId)
- return not not getplayervehicle(playerId)
- end
- local function cleanupdrones(playerId)
- local player = PlayerClass[playerId]
- local vehicleObjId
- for i = 1,#player.drones do vehicleObjId = player.drones[i]
- if getobject(vehicleObjId) then
- destroyobject(vehicleObjId)
- end
- player.drones[i] = nil
- end
- end
- local function setspeed(playerId, speed)
- local m_player = assert(getplayer(playerId), "bad argument #1 to 'setspeed' (valid playerId expected, got '" .. type(playerId) .. "')")
- speed = assert(tonumber(speed), "bad argument #2 to 'setspeed' (number expected, got '" .. type(speed) .. "')")
- writefloat(m_player + 0x6C, speed and speed < 999999999999999999999999999999 and speed or 999999999999999999999999999999)
- end
- -- This function will set a player's color
- -- Accepts playerId, and color carried as a number enumerator.
- local function setcolor(playerId, color)
- local m_player = assert(getplayer(playerId), "bad argument #1 to 'setspeed' (valid playerId expected, got '" .. type(playerId) .. "')")
- color = assert(tonumber(color), "bad argument #2 to 'setcolor' (number expected, got '" .. type(color) .. "')")
- writebyte(m_player + 0x60, color)
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- return
- end
- local player = PlayerClass[playerId]
- local x,y,z = getobjectcoords(playerObjId)
- player.colorspawn = true
- player.x,player.y,player.z = x,y,z
- destroyobject(playerObjId)
- end
- -- This local function gets the player's memory ID from their object struct
- -- Accepts the object ID of the player 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 = getplayer(playerId)
- if m_player then
- return playerId
- end
- 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
- 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
- local function timetoword(time)
- time = 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 ~= "" and returntime or "0 seconds"
- end
- end
- local function getTimeAndReason(timeandreason)
- 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
- 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
- local function resetweapons(playerId)
- if getplayerweapon(playerId) then
- for slot = 0,3 do
- local m_weapon, weaponObjId = getplayerweapon(playerId, slot)
- if m_weapon then
- destroyobject(weaponObjId)
- end
- end
- end
- local obj_tag_id = readdword(true and getplayerobject(playerId)) -- Confirmed with HMT. Tag Meta ID / MapID / TagID.
- local tag_address = gettagaddress(obj_tag_id)
- local address_tag_data = readdword(tag_address + 0x14)
- local number_of_starting_weapons = readdword(address_tag_data, 0x2D8)
- local tagdata_unit_weapons = readdword(address_tag_data + 0x2D8+0x4)
- for i = 0,3 do
- local weapon_mapId = readdword(tagdata_unit_weapons + i*0x24 + 0xC)
- if weapon_mapId and weapon_mapId ~= 0 then
- assignweapon(playerId, createobject(weapon_mapId, 0, 60, false, 3, 2, 1))
- end
- end
- --[[local address_starting_profile = readdword(address_tag_data + 0x348 + 0x4)
- local primary_weapon_mapId = readdword(address_tag_data + 0x348 + 0x4 + 0x28 + 0xC)
- local secondary_weapon_mapId = readdword(address_tag_data + 0x348 + 0x4 + 0x3C + 0xC)
- say(tostring(primary_weapon_mapId))
- if primary_weapon_mapId then
- assignweapon(playerId, createobject(primary_weapon_mapId, 0, 60, false, 3, 2, 1))
- end
- if secondary_weapon_mapId then
- assignweapon(playerId, createobject(secondary_weapon_mapId, 0, 60, false, 1, 2, 3))
- end--]]
- end
- local function ResetPlayer(playerId)
- local player = PlayerClass[playerId]
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if playerObjId ~= 0xFFFFFFFF and m_playerObj then
- player.godmode = false
- cleanupdrones(playerId)
- resetweapons(playerId)
- end
- player.bulletmode = false
- player.disarmed = false
- player.dmgmultiplier = 1
- player.ghostmode = false
- player.hidden = false
- player.objspawnid = false
- player.suspended = false
- end
- local function remoteBanCheck(ban_entry)
- local centralbanlist = defaults.remote_bansystem
- return not centralbanlist or (ban_entry.remote and centralbanlist.mode >= 1 or not ban_entry.remote and centralbanlist.mode ~= 2)
- end
- local function findBanlistEntry(name, hash, ip, bantype)
- local retBanEntry
- local cur_time = os.time()
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if remoteBanCheck(ban_entry) then
- if not ban_entry.time or (ban_entry.time == -1 or ban_entry.time > cur_time) then
- if not bantype or bantype == ban_entry.type then
- if ban_entry.type == "hash" and ban_entry.hash == hash or ban_entry.type == "ip" and netMatch(ban_entry.ip, ip) then
- --hprintf("NAME: " .. tostring(ban_entry.name) .. " REMOTECHECK: " .. tostring(remoteBanCheck(ban_entry)) .. " BANENTRY TIME: " .. tostring(ban_entry.time) .. " CURTIME: " .. tostring(cur_time))
- return ban_entry
- elseif (ban_entry.type == "name" and ban_entry.name == name) or ban_entry.type == "chat" and (ban_entry.hash == hash or netMatch(ban_entry.ip, ip)) then
- retBanEntry = ban_entry
- end
- end
- end
- end
- end
- if retBanEntry then
- --hprintf("NAME: " .. tostring(retBanEntry.name) .. " REMOTECHECK: " .. tostring(remoteBanCheck(retBanEntry)) .. " BANENTRY TIME: " .. tostring(retBanEntry.time) .. " CURTIME: " .. tostring(cur_time))
- end
- return retBanEntry
- end
- local function punishIfOnBanlist(playerId)
- local ban_entry = findBanlistEntry(getname(playerId), gethash(playerId), getip(playerId))
- if ban_entry then
- if ban_entry.type == "hash" or ban_entry.type == "ip" then
- tempBanPlayer(resolveplayer(playerId))
- elseif ban_entry.type == "chat" then
- PlayerClass[playerId].muted = true
- elseif ban_entry.type == "name" and ban_entry.name == name then
- svcmd("sv_kick " .. resolveplayer(playerId) .. " Found on the Name Banlist.")
- end
- return true
- end
- return false
- end
- local function loadBanTextEntry(line, bantype, filename)
- -- Sometimes a random blank line appears in the file, let's make sure not to error for those
- if not match(line, "%g%g%g+") or sub(line, 1, 1) == "#" then
- return
- end
- local t = {}--TM.New()
- local pos, endline, timestr, formatBantype, count, unique_index
- -- create a new table for the ban entry
- local 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,2015-03-27 04:10:52,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 == "" 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
- -- sapp's ipbans.txt
- 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+),?([%d%s%-:]*),?(%w*),?(.-)$")
- b.reason = b.reason and b.reason ~= "" and gsub(b.reason, ",", "") or "None Given"
- -- 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
- assert(not b.type or b.type == formatBantype, filename .. " is formatted incorrectly! expected bantype " .. formatBantype .. " instead got " .. tostring(b.type) .. " on line: " .. line)
- assert(not bantype or bantype == formatBantype, filename .. " should only have '" .. tostring(bantype) .. "' bans. Ban of type '" .. formatBantype .. "' was found in the line: " .. line)
- b.type = formatBantype
- 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)
- else
- b.time = -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
- b.name = b.name == "" and "Unnamed" or gsub(b.name, ",", "")
- return b, unique_index
- end
- local function toBanTextEntry(entry)
- local time, bantype = entry.time, entry.type
- time = time == -1 and "--" or os.date("%Y-%m-%d %X", time)
- if bantype == "chat" then
- return entry.name..","..entry.hash..":"..(entry.ip or "1.2.3.4")..","..entry.count..","..time..","..bantype..","..entry.reason
- elseif bantype == "hash" then
- return entry.name..","..entry.hash..","..entry.count..","..time..","..bantype..","..entry.reason
- elseif bantype == "ip" then
- return entry.name..","..entry.ip..","..entry.count..","..time..","..bantype..","..entry.reason
- elseif bantype == "name" then
- return entry.name..",,,,"..bantype--..","..reason reasons don't exist for namebans.. yet
- end
- end
- local function download(host, file, port, output)
- port = port or 80
- local client = socket.tcp()
- client:settimeout(1, 'b')
- client:settimeout(1, 't')
- local status, status2, err = pcall(client.connect, client, host, port)
- if not status or not status2 then
- print("Connection failed with error : " .. err)
- return
- end
- coroutine.yield(client)
- -- Stop luasocket from blocking. You can play with these values
- client:settimeout(0.01, 'b')
- client:settimeout(0.01, 't')
- client:send("GET " .. file .. " HTTP/1.1\r\nHOST: " .. host .. ":" .. port .. "\r\n\r\n")
- local count = 0 -- counts number of bytes read
- local buffer, status, overflow
- while true do
- coroutine.yield(client)
- buffer, status, overflow = client:receive(65536)
- -- If buffer is not nil the call was a success (changed in LuaSocket 2.0)
- if buffer then
- --print("Successfully received " .. #buffer .. " without timeout.")
- output[#output+1] = buffer
- count = count + #buffer
- else
- --print('"' .. status .. '" with ' .. #overflow .. ' bytes of ' .. file)
- output[#output+1] = overflow
- count = count + #overflow
- end
- if status == "closed" then break end
- end
- client:close()
- end
- local function OnHttpReceive(output)
- local entry, unique_index, hash, ip, name, bantype
- local cur_time = os.time()
- for line in string.gmatch(output, "[^\r\n]*") do
- entry, unique_index = loadBanTextEntry(line, nil, "remote banlist")
- if entry and not ban_table[unique_index] then
- entry.remote = true
- ban_table[#ban_table+1] = entry
- ban_table[unique_index] = #ban_table
- if not entry.time or entry.time > cur_time then
- for playerId = 0,15 do
- if getplayer(playerId) then
- hash, ip, name = gethash(playerId), getip(playerId), getname(playerId)
- bantype = entry.type
- if bantype == "hash" and hash == entry.hash or entry.type == "ip" and netMatch(entry.ip, ip) then
- tempBanPlayer(resolveplayer(playerId))
- break
- elseif bantype == "chat" and (entry.hash == hash or netMatch(entry.ip, ip)) then
- PlayerClass[playerId].muted = true
- elseif bantype == "name" and entry.name == name then
- svcmd("sv_kick " .. resolveplayer(playerId) .. " Found in a Remote Ban Entry during a reload.")
- break
- end
- end
- end
- end
- end
- end
- end
- function handleHttpRequest(id, count, userdata) -- userdata = {[1] = coroutine thread, [2] = extraArg}
- --local start = os.clock()
- local status, res = coroutine.resume(userdata[1])
- --local finish = os.clock()
- --print("TIME: " .. (finish - start) * 1000 .. " ms")
- if not res then -- thread finished its task?
- --print("Finished")
- output = concat(userdata[3])
- local sizeOfFile = match(output, "Content%-Length: (%d+)")
- OnHttpReceive(sizeOfFile and sub(output, -sizeOfFile, -2) or output, userdata[2])
- http_receiving = false
- return false
- end
- return true
- end
- local function HTTPGET(host, file, port, extraArg)
- if http_receiving then
- return
- end
- local output = {}
- -- create coroutine, and return the handle for the timer.
- local timerID = registertimer(
- 1000,
- "handleHttpRequest",
- {
- coroutine.create(
- function()
- download(host, file, port, output)
- end
- ),
- extraArg,
- output
- }
- )
- http_receiving = true
- return timerID
- end
- local function reloadRemoteBanlist()
- local args = defaults.remote_bansystem
- HTTPGET(args.host, args.banfile, args.port)
- end
- local function loadBanFile(filename, bantype)
- local file = io.open(filename)
- if not file then
- return
- end
- local ban_entry, unique_index
- for line in file:lines() do
- ban_entry, unique_index = loadBanTextEntry(line, bantype, filename)
- -- Make sure this entry hasn't already been added before we add it.
- if ban_entry and not ban_table[unique_index] then
- ban_table[#ban_table+1] = ban_entry
- ban_table[unique_index] = #ban_table
- end
- end
- file:close()
- end
- -- Save all bans to banned.txt
- local function updateBanFiles(bantype)
- local writetbl = {}--TM.New()
- local entry
- local file, err = io.open(profilepath .. defaults.banlist_file .. ".txt", "w")
- local time, type
- local args = defaults.remote_bansystem
- for id = 1,#ban_table do entry = ban_table[id]
- if not args or (entry.remote and args.mode >= 1 or not entry.remote and args.mode ~= 2) then
- writetbl[#writetbl+1] = toBanTextEntry(entry)
- end
- end
- local output = concat(writetbl, "\n")
- file:write(output)
- file:close()
- -- Update the remote banlist.
- if args and args.mode >= 2 then
- http.request(args.http_source, "&bans=" .. output .. ",&unban=false")
- end
- 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] = {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] = {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)
- assert(ip, defaults.admin_file .. ".txt is incorrectly formatted! Line: " .. line)
- admin_table[ip] = {name = name, level = tonumber(level), type = "ip"}
- 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] = {name = name, level = tonumber(level), type = "ip"}
- end
- end
- file:close()
- os.rename(profilepath .. "ipadmins.txt", profilepath .. "old_ipadmins_" .. timestamp .. ".txt")
- end
- updateAdminFiles()
- end
- function remoteTimer(id, count)
- -- This code will check if someone is trying to login to this TCP server.
- local client, err = server:accept()
- local length = #clients
- if not err then
- client:send"Welcome to the Remote Control interface provided in Wizard's Command Script!\r\n Type 'rcon password command' to execute a command. The Rcon password you use MUST be a global rcon (with sv_rcon_add)\r\n"
- length = length + 1
- clients[length] = {socket = client, info = client:getpeername(), client.logged_in}
- client:settimeout(0)
- elseif err ~= "timeout" then
- hprintf("There was an error accepting a client.\r\nError: " .. err)
- end
- local command, rcon
- for i = 1,length do client = clients[i]
- command, err = client.socket:receive()
- -- Problem getting response from client.
- if err == "timeout" then
- goto continue
- elseif err then
- client.socket:close()
- hprintf("Remote client '" .. client.info .. "' disconnected with error: " .. err)
- remove(clients, i)
- goto continue
- -- Logout code.
- elseif command == "logout" or command == "quit" or command == "exit" or command == "close" then
- client.socket:send"You have been disconnected. Have a good day"
- client.socket:close()
- remove(clients, i)
- goto continue
- end
- rcon, command = match(command, "^rcon (%w%w%w%w%w%w%w%w) (%g+)%c*$")
- -- Validate the command.
- if not rcon or not command then
- client.socket:send"Invalid Command attempt.\r\nrcon <password> <command>\r\n"
- goto continue
- elseif OnServerCommandAttempt(-1, command, rcon) == false then
- client.socket:send"Bad rcon password given. This will be reported."
- goto continue
- end
- hprintf("Remote client '" .. client.info .. "' executed '" .. command .. "'")
- local response
- if command ~= "sv_script_unload" and command ~= "sv_script_reload" and command ~= "sv_script_load" and command ~= "reload" and command ~= "load" and command ~= "unload" and command ~= "lua_load" and command ~= "lua_unload" then
- response = svcmd(command, true)
- end
- response = type(response) == "table" and response[1] and concat(response) or "Failed to receive output for command."
- client.socket:send(response .. "\r\nType your command here:")
- ::continue::
- end
- return true
- end
- -- changes 'sv_myCommand', '/myCommand', and '\myCommand' into 'myCommand'
- local function getvalidformat(command)
- if not command then return end
- local sv_found, slash_found, both_found = sub(command, 1, 3), sub(command, 1, 1), sub(command, 1, 4)
- command = gsub(gsub(command, "_", ""), " ", "")
- if sv_found == "sv_" then
- return sub(command, 3)
- elseif slash_found == "\\" or slash_found == "/" then
- return sub(command, 2)
- elseif both_found == "\\sv_" or both_found == "/sv_" then
- return sub(command, 4)
- end
- return command
- end
- local function getaccess(playerId)
- if playerId then
- local adminEntry = PlayerClass[playerId].admin_entry
- return adminEntry and adminEntry.level
- else
- return 0
- end
- end
- local function SelectRandomPlayer(team)
- local t = {}--TM.New()
- local size = 0
- for playerId = 0,15 do
- if getplayer(playerId) and (not team or getteam(playerId) == team) then
- size = size + 1
- t[size] = playerId
- 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(gsub(gsub(wild, "?", "."), "*", ".*"), " ", "%s")
- local found = match(origstring, wild)
- if found and #found == #origstring then
- return true
- end
- return false
- end
- local function getvalidplayers(expression, executorPlayerId)
- local players = {}--TM.New()
- if cur_players ~= 0 and expression then
- if expression == "*" then
- for playerId = 0,15 do
- if getplayer(playerId) then
- players[#players+1] = playerId
- end
- end
- elseif expression == "me" then
- if executorPlayerId then
- players[1] = executorPlayerId
- end
- elseif player_colors[expression] then
- local color = player_colors[expression]
- local m_player
- for playerId = 0,15 do
- m_player = getplayer(playerId)
- if m_player then
- if color == readword(m_player + 0x60) then
- players[#players+1] = playerId
- end
- end
- end
- elseif expression == "red" then
- for playerId = 0,15 do
- if getplayer(playerId) and getteam(playerId) == 0 then
- players[#players+1] = playerId
- end
- end
- elseif expression == "blue" then
- for playerId = 0,15 do
- if getplayer(playerId) and getteam(playerId) == 1 then
- players[#players+1] = playerId
- 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 playerId = tonumber(expression)
- if getplayer(rresolveplayer(playerId)) then
- players[1] = rresolveplayer(playerId)
- end
- elseif expression == "rand" or expression == "random" then
- players[1] = SelectRandomPlayer()
- elseif expression == "admins" then
- for playerId = 0,15 do
- if getplayer(playerId) and getaccess(playerId) then
- players[#players+1] = playerId
- end
- end
- elseif expression == "nearest" or expression == "closest" then
- local m_playerObj, playerObjId = getplayerobject(executorPlayerId)
- local m_playerObj2, X, Y, Z, dist, closest_player
- if m_playerObj then
- local x,y,z = getobjectcoords(playerObjId)
- local min_dist = 9001
- for playerId = 0,15 do
- if playerId ~= executorPlayerId then
- m_playerObj2, playerObjId2 = getplayerobject(playerId)
- if m_playerObj2 then
- X,Y,Z = getobjectcoords(playerObjId2)
- dist = (X - x)^2 + (Y - y)^2 + (Z - z)^2 -- dont need square root since its a comparison
- if min_dist > dist then
- min_dist = dist
- closest_player = playerId
- end
- end
- end
- end
- players[1] = closest_player
- end
- elseif expression == "farthest" then
- local m_playerObj, playerObjId = getplayerobject(executorPlayerId)
- local m_playerObj2, X, Y, Z, dist, farthest_player
- if m_playerObj then
- local x,y,z = getobjectcoords(playerObjId)
- local max_dist = 0
- for playerId = 0,15 do
- if playerId ~= executorPlayerId then
- m_playerObj2, playerObjId2 = getplayerobject(playerId)
- if m_playerObj2 then
- X,Y,Z = getobjectcoords(playerObjId2)
- dist = (X - x)^2 + (Y - y)^2 + (Z - z)^2 -- dont need square root since its a comparison
- if max_dist < dist then
- max_dist = dist
- farthest_player = playerId
- end
- end
- end
- end
- players[1] = farthest_player
- end
- else
- for playerId = 0,15 do
- if getplayer(playerId) and wildstring(getname(playerId), expression) then
- players[#players+1] = playerId
- end
- end
- end
- return next(players) and players
- end
- return false
- end
- local tag_vehi_types = { -- 0x2F4
- [0] = "Human Tank",
- "Human Jeep",
- "Human Boat",
- "Human Plane",
- "Alien Scout",
- "Alien Fighter",
- "Turret",
- }
- local tag_weap_types = { -- 0x30C
- [0] = "None",
- [1694528097] = "AI: Sentinel Beam (ar)",
- [98] = "Special: Skull Ball (b)",
- [1811939430] = "Special: Flag (f)",
- [7239015] = "Vehicle (Covenant): Type-26 Banshee; Type-32 RAV Ghost; Type-25 (and Type-52?) Wraith (gun)",
- [29799] = "Vehicle (Covenant): Type-26 ASG Shade Gun Turret; DX-class Spirit Dropship (gt)",
- [26467] = "Vehicle (Human): M12 Warthog (cg)",
- [1852727651] = "Vehicle (Human): M808B MBT Scorpion (cannon)",
- [1811968609] = "Weapon (Human): MA5 Assault Rifle; Gravity Rifle (ar)",
- [1811969126] = "Weapon (Human): M7057 Flamethrower (ft)",
- [28776] = "Weapon (Human): M6 Pistol (hp)",
- [1811967090] = "Weapon (Human): M19 SSM / M41 SSR Rocket Launcher (rl)",
- [1811965811] = "Weapon (Human): M90 CAWS Shotgun (sg)",
- [1811968627] = "Weapon (Human): 99D-S2 Sniper Rifle (sr)",
- [25190] = "Weapon, Melee (Covenant): Energy Sword (fb)",
- [1811968614] = "Weapon (Covenant): Type-33 Fuel Rod Gun (fr)",
- [1811965294] = "Weapon (Covenant): Type-33 GML Needler (ne)",
- [1811968112] = "Weapon (Covenant): Plasma Pistol (pp)",
- [1811968624] = "Weapon (Covenant): Plasma Rifle (pr)",
- [1811964784] = "Weapon (Covenant): Plasma Cannon (pc)"
- }
- local function LoadTags()
- local map_base = 0x40440000
- 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, address_tag_data, vehi_type, weap_type
- 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 {tag_id}
- tag_table[tag_class][tag_name] = tag_id
- tag_table[tag_class][#tag_table[tag_class]+1] = tag_id
- tag_table[tag_id] = {}--{}--TM.New()
- tag_table[tag_id].tag_name = tag_name
- tag_table[tag_id].tag_class = tag_class
- tag_address = readdword(map_base) + i * tag_table_size -- 0x40440028
- if tag_class == "vehi" then
- address_tag_data = readdword(tag_address, 0x14)
- vehi_type = readword(address_tag_data + 0x2F4)
- tag_table[tag_id].vehi_type = tag_vehi_types[vehi_type]
- if vehi_type and vehi_type >= 0 and vehi_type <= 6 and not tag_table[vehi_type] then
- tag_table[vehi_type] = tag_id
- end
- elseif tag_class == "weap" then
- address_tag_data = readdword(tag_address, 0x14)
- weap_type = readword(address_tag_data + 0x2F4)
- tag_table[tag_id].weap_type = tag_weap_types[weap_type]
- if not weap_type or not tag_table[weap_type] then
- tag_table[weap_type] = tag_id
- end
- end
- end
- hprintf("Found " .. tostring(#tag_table.vehi) .. " vehicles and " .. tostring(#tag_table.weap) .. " weapons")
- flameid = gettagid("proj", "weapons\\flamethrower\\flame")
- objects = {
- cyborg = {"bot, masterchief", type = "bipd", mapId = gettag("bipd", "characters\\cyborg_mp\\cyborg_mp"), name = "Cyborg"},
- captain = {"keyes", type = "bipd", mapId = gettag("bipd", "characters\\captain\\captain"), name = "Captain Keyes"},
- cortana = {type = "bipd", mapId = gettag("bipd", "characters\\cortana\\cortana"), name = "Cortana"},
- cortana2 = {type = "bipd", mapId = gettag("bipd", "characters\\cortana\\halo_enhanced\\halo_enhanced"), name = "Cortana2"},
- crewman = {type = "bipd", mapId = gettag("bipd", "characters\\crewman\\crewman"), name = "Crewman"},
- elite = {type = "bipd", mapId = gettag("bipd", "characters\\elite\\elite"), name = "Elite"},
- elite2 = {type = "bipd", mapId = gettag("bipd", "characters\\elite\\elite special"), name = "Elite Special"},
- engineer = {type = "bipd", mapId = gettag("bipd", "characters\\engineer\\engineer"), name = "Engineer"},
- flood = {type = "bipd", mapId = gettag("bipd", "characters\\flood_captain\\flood_captain"), name = "Flood Captain"},
- flood2 = {type = "bipd", mapId = gettag("bipd", "characters\\flood_infection\\flood_infection"), name = "Flood Infection"},
- flood3 = {type = "bipd", mapId = gettag("bipd", "characters\\floodcarrier\\floodcarrier"), name = "Flood Carrier"},
- floodelite = {type = "bipd", mapId = gettag("bipd", "characters\\floodcombat elite\\floodcombat elite"), name = "FloodCombat Elite"},
- floodhuman = {type = "bipd", mapId = gettag("bipd", "characters\\floodcombat_human\\floodcombat_human"), name = "FloodCombat Human"},
- grunt = {"pedobear", type = "bipd", mapId = gettag("bipd", "characters\\grunt\\grunt"), name = "Pedobear"},
- hunter = {type = "bipd", mapId = gettag("bipd", "characters\\hunter\\hunter"), name = "Hunter"},
- marine = {type = "bipd", mapId = gettag("bipd", "characters\\marine\\marine"), name = "Marine"},
- marine2 = {"marinesuicide", type = "bipd", mapId = gettag("bipd", "characters\\marine_suicidal\\marine_suicidal"), name = "Marine Suicidal"},
- monitor = {type = "bipd", mapId = gettag("bipd", "characters\\monitor\\monitor"), name = "Monitor"},
- sentinel = {type = "bipd", mapId = gettag("bipd", "characters\\sentinel\\sentinel"), name = "Sentinel"},
- johnson = {type = "bipd", mapId = gettag("bipd", "characters\\johnson\\johnson"), name = "Sgt. Johnson"},
- camouflage = {"camo", type = "eqip", mapId = gettag("eqip", "powerups\\active camouflage"), name = "Camouflage"},
- doublespeed = {"dblspd", type = "eqip", mapId = gettag("eqip", "powerups\\double speed"), name = "Double Speed"},
- fullspec = {"fullspectrum", type = "eqip", mapId = gettag("eqip", "powerups\\full-spectrum vision"), name = "Full-Spectrum Vision"},
- fnade = {"nades", "frag", "frags", type = "eqip", mapId = gettag("eqip", "weapons\\frag grenade\\frag grenade"), name = "Frag Grenade"},
- pnade = {"plasmas", "plasma", type = "eqip", mapId = gettag("eqip", "weapons\\plasma grenade\\plasma grenade"), name = "Plasma Grenade"},
- overshield = {"os", type = "eqip", mapId = gettag("eqip", "powerups\\over shield"), name = "Overshield"},
- rifleammo = {type = "eqip", mapId = gettag("eqip", "powerups\\assault rifle ammo\\assault rifle ammo"), name = "Assault Rifle Ammo"},
- healthpack = {"health", type = "eqip", mapId = gettag("eqip", "powerups\\health pack"), name = "Health Pack"},
- needlerammo = {"needleammo", type = "eqip", mapId = gettag("eqip", "powerups\\needler ammo\\needler ammo"), name = "Needler Ammo"},
- pistolammo = {type = "eqip", mapId = gettag("eqip", "powerups\\pistol ammo\\pistol ammo"), name = "Pistol Ammo"},
- rocketammo = {type = "eqip", mapId = gettag("eqip", "powerups\\rocket launcher ammo\\rocket launcher ammo"), name = "Rocket Ammo"},
- shottyammo = {"shotgunammo", type = "eqip", mapId = gettag("eqip", "powerups\\shotgun ammo\\shotgun ammo"), name = "Shotgun Ammo"},
- sniperammo = {type = "eqip", mapId = gettag("eqip", "powerups\\sniper rifle ammo\\sniper rifle ammo"), name = "Sniper Ammo"},
- flameammo = {type = "eqip", mapId = gettag("eqip", "powerups\\flamethrower ammo\\flamethrower ammo"), name = "Flamethrower Ammo"},
- energysword = {"esword", type = "weap", mapId = gettag("weap", "weapons\\energy sword\\energy sword"), name = "Energy Sword"},
- oddball = {"ball", type = "weap", mapId = gettag("weap", "weapons\\ball\\ball"), name = "Oddball"},
- flag = {type = "weap", mapId = gettag("weap", "weapons\\flag\\flag"), name = "Flag"},
- fuelrod = {"frg", "rod", "plasmacannon", type = "weap", mapId = gettag("weap", "weapons\\plasma_cannon\\plasma_cannon"), name = "Fuel Rod"},
- gravitygun = {"ggun", type = "weap", mapId = gettag("weap", "weapons\\gravity rifle\\gravity rifle"), name = "Gravity Gun"},
- needler = {type = "weap", mapId = gettag("weap", "weapons\\needler\\mp_needler"), name = "Needler"},
- pistol = {type = "weap", mapId = gettag("weap", "weapons\\pistol\\pistol"), name = "Pistol"},
- plasmapistol = {"ppistol", type = "weap", mapId = gettag("weap", "weapons\\plasma pistol\\plasma pistol"), name = "Plasma Pistol"},
- plasmarifle = {"prifle", type = "weap", mapId = gettag("weap", "weapons\\plasma rifle\\plasma rifle"), name = "Plasma Rifle"},
- assaultrifle = {"rifle", "arifle", "assault", type = "weap", mapId = gettag("weap", "weapons\\assault rifle\\assault rifle"), name = "Assault Rifle"},
- rocketlauncher = {"rocket", "rox", type = "weap", mapId = gettag("weap", "weapons\\rocket launcher\\rocket launcher"), name = "Rocket Launcher"},
- shotgun = {"shotty", type = "weap", mapId = gettag("weap", "weapons\\shotgun\\shotgun"), name = "Shotgun"},
- sniper = {"sniperrifle", type = "weap", mapId = gettag("weap", "weapons\\sniper rifle\\sniper rifle"), name = "Sniper Rifle"},
- flamethrower = {"flamer", type = "weap", mapId = gettag("weap", "weapons\\flamethrower\\flamethrower"), name = "Flamethrower"},
- wraith = {type = "vehi", mapId = gettag("vehi", "vehicles\\wraith\\wraith"), name = "Wraith"},
- pelican = {"peli", type = "vehi", mapId = gettag("vehi", "vehicles\\pelican\\pelican"), name = "Pelican"},
- ghost = {type = "vehi", type = "vehi", mapId = gettag("vehi", "vehicles\\ghost\\ghost_mp"), name = "Ghost"},
- warthog = {"hog", type = "vehi", mapId = gettag("vehi", "vehicles\\warthog\\mp_warthog"), name = "Warthog"},
- rocketwarthog = {"rhog", type = "vehi", mapId = gettag("vehi", "vehicles\\rwarthog\\rwarthog"), name = "Rocket Warthog"},
- banshee = {"shee", type = "vehi", mapId = gettag("vehi", "vehicles\\banshee\\banshee_mp"), name = "Banshee"},
- tank = {"scorpion", type = "vehi", mapId = gettag("vehi", "vehicles\\scorpion\\scorpion_mp"), name = "Tank"},
- turret = {"shade", type = "vehi", mapId = gettag("vehi", "vehicles\\c gun turret\\c gun turret_mp"), name = "Gun Turret"},
- sheebolt = {type = "proj", mapId = gettag("proj", "vehicles\\banshee\\banshee bolt"), name = "Shee Bolt"},
- sheerod = {type = "proj", mapId = gettag("proj", "vehicles\\banshee\\mp_banshee fuel rod"), name = "Shee Rod"},
- turretbolt = {type = "proj", mapId = gettag("proj", "vehicles\\c gun turret\\mp gun turret"), name = "Turret Bullet"},
- ghostbolt = {type = "proj", mapId = gettag("proj", "vehicles\\ghost\\ghost bolt"), name = "Ghost Bolt"},
- tankshot = {type = "proj", mapId = gettag("proj", "vehicles\\scorpion\\bullet"), name = "Tank Bullet"},
- tankshell = {type = "proj", mapId = gettag("proj", "vehicles\\scorpion\\tank shell"), name = "Tank Shell"},
- hogshot = {type = "proj", mapId = gettag("proj", "vehicles\\warthog\\bullet"), name = "Hog Bullet"},
- rifleshot = {type = "proj", mapId = gettag("proj", "weapons\\assault rifle\\bullet"), name = "Rifle Bullet"},
- flame = {type = "proj", mapId = gettag("proj", "weapons\\flamethrower\\flame"), name = "Flame Projectile"},
- needlershot = {type = "proj", mapId = gettag("proj", "weapons\\needler\\mp_needle"), name = "Needler Shard"},
- pistolshot = {type = "proj", mapId = gettag("proj", "weapons\\pistol\\bullet"), name = "Pistol Bullet"},
- priflebolt = {type = "proj", mapId = gettag("proj", "weapons\\plasma pistol\\bolt"), name = "Plasma Rifle Bolt"},
- ppistolbolt = {type = "proj", mapId = gettag("proj", "weapons\\plasma rifle\\bolt"), name = "Plasma Pistol Bolt"},
- ppistolcbolt = {type = "proj", mapId = gettag("proj", "weapons\\plasma rifle\\charged bolt"), name = "Plasma Pistol Charged Bolt"},
- rocketproj = {type = "proj", mapId = gettag("proj", "weapons\\rocket launcher\\rocket"), name = "Rocket Projectile"},
- shottyshot = {type = "proj", mapId = gettag("proj", "weapons\\shotgun\\pellet"), name = "Shotgun Pellet"},
- snipershot = {type = "proj", mapId = gettag("proj", "weapons\\sniper rifle\\sniper bullet"), name = "Sniper Bullet"},
- fuelrodshot = {type = "proj", mapId = gettag("proj", "weapons\\plasma_cannon\\plasma_cannon"), name = "Fuel Rod Bolt"},
- }
- -- Use enum in vehi_type as a backup way to determine default vehicles tag ids without their tagnames.
- objects.tank.mapId = objects.tank.mapId or tag_table[0] and tag_table[0]
- objects.warthog.mapId = objects.warthog.mapId or tag_table[1] and tag_table[1]
- objects.rocketwarthog.mapId = objects.rocketwarthog.mapId or tag_table[1] and tag_table[1]
- objects.pelican.mapId = objects.pelican.mapId or tag_table[3] and tag_table[3]
- objects.ghost.mapId = objects.ghost.mapId or tag_table[4] and tag_table[4]
- objects.banshee.mapId = objects.banshee.mapId or tag_table[5] and tag_table[5]
- objects.turret.mapId = objects.turret.mapId or tag_table[6] and tag_table[6]
- objects.oddball.mapId = objects.oddball.mapId or tag_table[98] and say("Oddball: USING BACKUP TAG") or tag_table[98]
- objects.energysword.mapId = objects.energysword.mapId or tag_table[25190] and say("Energy Sword: USING BACKUP TAG") or tag_table[25190]
- objects.pistol.mapId = objects.pistol.mapId or tag_table[28776] and say("Pistol: USING BACKUP TAG") or tag_table[28776]
- objects.flag.mapId = objects.flag.mapId or tag_table[1811939430] and say("Flag: USING BACKUP TAG") or tag_table[1811939430]
- objects.needler.mapId = objects.needler.mapId or tag_table[1811965294] and say("Needler: USING BACKUP TAG") or tag_table[1811965294]
- objects.plasmapistol.mapId = objects.plasmapistol.mapId or tag_table[1811968112] and say("Plasma Pistol: USING BACKUP TAG") or tag_table[1811968112]
- objects.fuelrod.mapId = objects.fuelrod.mapId or tag_table[1811968614] and say("Fuelrod: USING BACKUP TAG") or tag_table[1811968614]
- objects.plasmarifle.mapId = objects.plasmarifle.mapId or tag_table[1811968624] and say("Plasma Rifle: USING BACKUP TAG") or tag_table[1811968624]
- objects.assaultrifle.mapId = objects.assaultrifle.mapId or tag_table[1811968609] and say("Assault Rifle: USING BACKUP TAG") or tag_table[1811968609]
- objects.rocketlauncher.mapId = objects.rocketlauncher.mapId or tag_table[1811967090] and say("Rocket Launcher: USING BACKUP TAG") or tag_table[1811967090]
- objects.shotgun.mapId = objects.shotgun.mapId or tag_table[1811965811] and say("Shotgun: USING BACKUP TAG") or tag_table[1811965811]
- objects.sniper.mapId = objects.sniper.mapId or tag_table[1811968627] and say("Sniper: USING BACKUP TAG") or tag_table[1811968627]
- objects.flamethrower.mapId = objects.flamethrower.mapId or tag_table[1811969126] and say("Flamethrower: USING BACKUP TAG") or tag_table[1811969126]
- -- Set Object Aliases.
- for name,thisObject in next,objects do
- for i = 1,#thisObject do
- objects[thisObject[i]] = thisObject
- end
- objects[name] = thisObject
- end
- end
- function votekickTimer(id, count)
- say("The VoteKick on " .. getname(votekickPlayerId) .. " has expired!")
- votekicktimer = nil
- votekickPlayerId = nil
- votekick_counter = -defaults.votekick_timeout
- for playerId = 0,15 do
- PlayerClass[playerId].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
- maxlines = maxlines or 9001
- maxlinesize = maxlinesize or 9001
- local newOutput = type(output) == "string" and tokenizestring(output, "\n") or output
- -- Get number of lines from our output. Respects __len metamethod.
- local mt = type(output) == "table" and getmetatable(output)
- local len = mt and mt.__len
- local numOfLines = len and len(newOutput) or #newOutput
- local function insert(t, pos, v)
- if v then
- assert(type(pos) == "number", "bad argument #2 to 'insert' expected number, got " .. type(pos))
- for i = numOfLines+1,pos+1,-1 do
- rawset(t, i, rawget(t, i-1))
- end
- t[pos] = v
- else
- t[numOfLines+1] = pos
- end
- numOfLines = numOfLines + 1
- end
- local function remove(t, key)
- t = type(t) == "table" and t or error("bad argument #1 to 'remove' expected table, got " .. type(t))
- key = key or numOfLines
- t[key] = nil
- if type(key) == "number" then
- for i = key,numOfLines do
- rawset(t, i, rawget(t, i+1))
- end
- end
- numOfLines = numOfLines - 1
- end
- local header = newOutput.header
- local linesCombined = ceil((numOfLines + (header and 1 or 0))/maxlines)
- -- duplicate the header by linesCombined times.
- if header then
- assert(type(header) == "string", "Output header needs to be a string, got " .. type(header))
- for i = 1,linesCombined do
- insert(newOutput, 1, header)
- 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
- -- This loop gets the largest possible size for each line part.
- 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
- -- This loop will make all line parts the same size (by adding spaces). string.format makes this easy for us.
- 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, then we now need to combine lines until we are within maxlines
- local lineIter = 1
- local numOfLinesToCombine = floor(numOfLines / linesCombined)
- while numOfLines > maxlines do
- -- combine 'linesCombined' lines into 1 line.
- 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)
- end
- lineIter = lineIter + 1
- -- Check if we need to increase the number of lines to combine per iteration.
- -- Also checks if we're done
- if numOfLinesToCombine == 1 then
- linesCombined = linesCombined - 1
- if linesCombined < 2 then break end
- numOfLinesToCombine = floor(numOfLines / linesCombined)
- -- This is our counter.
- else
- numOfLinesToCombine = numOfLinesToCombine - 1
- end
- 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
- 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, false)
- elseif output_environment == 3 then
- privatesay(playerId, msg, false)
- 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", {message, playerId})
- end
- if log and playerCheck then
- cmdlog("Response to " .. getname(playerId) .. " (" .. PlayerClass[playerId].admin_entry.name .. "): " .. message)
- end
- -- this will reset all the properties of cmdreply
- if tempmessage == cmdreply then cmdreply(true) end
- end
- local function getscorelimit()
- if gametype == 1 then
- return readint(addresses.ctf_globals + 0x18)
- elseif gametype == 2 then
- return scorelimit
- --return readbyte(addresses.gametype_base + 0x58, score)
- elseif gametype == 3 then
- return readint(addresses.oddball_globals)
- elseif gametype == 4 then
- return readint(addresses.koth_globals + team*4)
- elseif gametype == 5 then
- return readint(addresses.race_globals + team*4 + 0x88)
- else
- return readbyte(addresses.gametype_base + 0x58)
- end
- end
- local function setscorelimit(score)
- if gametype == 1 then
- writeint(addresses.ctf_globals + 0x18, score)
- elseif gametype == 2 then
- scorelimit = score
- --writebyte(addresses.gametype_base + 0x58, score)
- elseif gametype == 3 then
- writeint(addresses.oddball_globals, score)
- elseif gametype == 4 then
- writeint(addresses.koth_globals + team*4, score)
- elseif gametype == 5 then
- writeint(addresses.race_globals + team*4 + 0x88, score)
- else
- writebyte(addresses.gametype_base + 0x58, score)
- end
- end
- local function getscore(playerId)
- if gametype == 1 then
- return readshort(getplayer(playerId) + 0xC8)
- elseif gametype == 2 then
- return player_scores[playerId]
- --return readint(addresses.slayer_globals + 0x40 + playerId*4)
- elseif gametype == 3 then
- local oddball_game = readbyte(addresses.gametype_base + 0x8C)
- if oddball_game == 0 or oddball_game == 1 then
- return readint(addresses.oddball_globals + 0x84 + playerId*4)
- else
- return readint(addresses.oddball_globals + player*4 + 0x104)
- end
- elseif gametype == 4 then
- return readshort(getplayer(playerId) + 0xC4)
- elseif gametype == 5 then
- return readshort(getplayer(playerId) + 0xC6)
- end
- end
- local function setscore(playerId, score)
- if gametype == 1 then
- writeshort(getplayer(playerId)+0xC8, score)
- elseif gametype == 2 then
- if team_play then
- local curscore = player_scores[playerId]
- local diff = math.abs(score - curscore)
- if curscore > score then
- team_scores[getteam(playerId)] = team_scores[getteam(playerId)] + curscore
- elseif curscore < score then
- team_scores[getteam(playerId)] = team_scores[getteam(playerId)] - curscore
- end
- end
- player_scores[playerId] = score
- writeshort(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
- writeshort(getplayer(playerId) + 0xC4, score * 30)
- elseif gametype == 5 then
- writeshort(getplayer(playerId) + 0xC6, score)
- end
- end
- local function getteamscore(team)
- if gametype == 1 then
- return readint(addresses.ctf_globals + team*4 + 0x10)
- elseif gametype == 2 then
- return team_scores[team]
- --return readint(addresses.slayer_globals + team*4)
- elseif gametype == 3 then
- return readint(addresses.oddball_globals + team*4 + 0x4)
- elseif gametype == 4 then
- return readint(addresses.koth_globals + team*4)
- elseif gametype == 5 then
- return readint(addresses.race_globals + team*4 + 0x88)
- end
- end
- local function setteamscore(team, score)
- if gametype == 1 then
- writeint(addresses.ctf_globals + team*4 + 0x10, score)
- elseif gametype == 2 then
- team_scores[team] = score
- --writeint(addresses.slayer_globals + team*4, score)
- elseif gametype == 3 then
- writeint(addresses.oddball_globals + team*4 + 0x4, score)
- elseif gametype == 4 then
- writeint(addresses.koth_globals + team*4, score)
- elseif gametype == 5 then
- writeint(addresses.race_globals + team*4 + 0x88, 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.2 The 'Nimbus' Release (Released __, 2015)"
- changelog[#changelog+1] = "--Added a firefist command, to be explained later."
- changelog[#changelog+1] = "--Readded the ghost and unghost commands due to many requests"
- changelog[#changelog+1] = "--Added a central (remote) banlist feature. Please check out the readme for information on how to use it."
- changelog[#changelog+1] = "--Ban reasons will now show 'unbanned by (admin name)' when they have been unbanned."
- changelog[#changelog+1] = "--Even more bug fixes and small features, including compatibility with Sapp."
- changelog[#changelog+1] = "--Removed all the memoizing crap that I put in the previous version. It was causing a lot of rare issues, and probably wasn't helping performance much"
- changelog[#changelog+1] = "--Fixed an issue that happened onload that was caused by people using windows default notepad to edit the init.txt"
- changelog[#changelog+1] = "--Added 'farthest' expression for player arguments, so you can now do things like /kill farthest to kill the farthest player to you."
- changelog[#changelog+1] = "--Added 'nearest' expression for player arguments, so you can now do things like /kill nearest to kill the nearest player to you."
- changelog[#changelog+1] = "--Added colors as player arguments, you can now pass colors as player expressions like /kill yellow will kill all yellow people in the server"
- changelog[#changelog+1] = "--Improved the killingspree feature. It will now announce when someone's spree has ended, and how many kills they racked up."
- changelog[#changelog+1] = "--Removed 'log' as an alias for the login command so as not to interfere with the already existing 'log' command from Sapp."
- changelog[#changelog+1] = "--Fixed a bug that would cause the 'list' command to crash if there were no admins on the server."
- changelog[#changelog+1] = "--Fixed a bug with the Noweapons command."
- changelog[#changelog+1] = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = "Commands Version 5.13 The 'Nimbus' Release (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[#changelog+1] = "Commands Version 5.01 The 'Nimbus' Release (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/bans 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' bans 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 EventPlayerJoin. 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 EventPlayerJoin"
- 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 player 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 2012)"
- changelog[#changelog+1] = "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
- changelog[#changelog+1] = ""
- changelog[#changelog+1] = "--Script Created"
- file:write(concat(changelog, "\n"))
- file:close()
- end
- function tempBanPlayer(playerIndex)
- halo_svcmd("sv_ban " .. playerIndex .. " 1s")
- return false
- end
- local function addBan(player_name, player_hash, player_ip, ban_time, ban_type, ban_reason)
- local banid, ban_entry, bancount, name, reason
- local args = defaults.remote_bansystem
- -- check if they've already been banned before
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if not args or (ban_entry.remote and args.mode >= 1 or not ban_entry.remote and args.mode ~= 2) then
- if ban_type == 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
- end
- if banid then
- bancount = ban_entry.count + 1
- name = ban_entry.name
- reason = ban_entry.reason
- else
- bancount = 1
- banid = #ban_table+1
- ban_entry = {}--TM.New()
- end
- ban_entry.count = bancount
- ban_entry.name = (name and not find(name, player_name) and (name .. " / ") or "") .. player_name
- ban_entry.hash = player_hash
- ban_entry.ip = player_ip
- ban_entry.time = ban_time > 0 and ban_time + os.time() or ban_time == -1 and -1 or ban_penalty[bancount]
- ban_entry.type = ban_type
- ban_entry.reason = (reason and not find(reason, ban_reason) and (reason .. " / ") or "") .. ban_reason
- ban_table[banid] = ban_entry
- if args and args.mode >= 2 then
- --print("ADDING TO REMOTE BANLIST. Host: " .. tostring(args.http_source) .. " Body: " .. tostring("&bans=" .. toBanTextEntry(ban_entry)))
- print(http.request(args.http_source, "&bans=" .. toBanTextEntry(ban_entry)) .. ",&unban=false")
- end
- updateBanFiles(bantype)
- end
- local function checkaccess(command, access)
- command = Commands[command] or command
- local access_entry = access_table[access]
- return access_entry and (access_entry.allcommands or access_entry[command]) or false
- end
- -- Returns true if equal, false if both not admin, or the playerId more powerful.
- -- It's important to note that if the Server is being compared as a playerId, it's value is nil.
- local function getMorePowerfulPlayer(playerId1, playerId2)
- -- the Server is the most powerful admin.
- if not playerId1 then
- return not playerId2 or playerId1
- elseif not playerId2 then
- return not playerId1 or playerId2
- end
- local access1 = access_table[getaccess(playerId1)]
- access1 = access1 and #access1 or -1
- local access2 = access_table[getaccess(playerId2)]
- access2 = access2 and #access2 or -1
- return access1 > access2 and playerId1 or access1 < access2 and playerId2 or access1 > 0
- end
- local function checkAdminBlockerAccess(executorPlayerId, playerId)
- local allowed = getMorePowerfulPlayer(executorPlayerId, playerId)
- return defaults.adminblocker == "Unsafe" or defaults.adminblocker == "Lenient" and (allowed == executorPlayerId or allowed == true) or defaults.adminblocker == "Moderate" and allowed == executorPlayerId or access_table[getaccess(executorPlayerId)] == -1
- end
- local function Say(message)
- for playerId = 0,15 do
- if getplayer(playerId) then
- sendconsoletext(playerId, message)
- end
- end
- end
- local function capitalizeWords(str, amount)
- return gsub(str, '(%a)(%a+)', function(cap, rest) return ('%1'):upper() .. '%2' end)
- end
- local function trim(str)
- return gsub(str, "^%s*(.-)%s*$", "%1")
- end
- 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)
- elseif find(strPart, " ") then
- strPart = '"' .. strPart .. '"' -- keep quotes around em
- end
- pos = newPos
- strParts[#strParts+1] = strPart
- until not strPart
- ::returnSplits::
- return strParts
- end
- 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
- -- This function is responsible for creating a command.
- -- I am using table functions in this manner because it is easier to parse commands in groups, it saves me from copying and pasting already existing code.
- -- It also allows me to check to see if the command was coded correctly (before LUA sends an unhelpful error message)
- -- This also allows me to use command aliases, merge help info. It basically keeps all information about a command in one place.
- -- To an average joe reading this script, it may be harder to use this method if you aren't familiar with table structures, but it's better in the end because it is more organized.
- -- Arguements are the name of the command, the commandInfo (as a table, containing aliases, help, and boolean information like scrimMode usage, and each function called for different command arguments (for example, /enter (player) (player2) (seat) vs /enter (vehicleName))
- 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: " .. cmdName) end
- local thisCmdFunc
- for i = 1,select("#", ...) do
- thisCmdFunc = select(i, ...)
- assert(thisCmdFunc.arguments, "NO ARGUMENTS IN COMMAND CREATION: " .. cmdName)
- assert(thisCmdFunc.arguments.minArgs, "NO MINIMUM ARGUMENTS IN COMMAND CREATION: " .. cmdName)
- assert(thisCmdFunc.arguments.maxArgs, "NO MAXIMUM ARGUMENTS IN COMMAND CREATION: " .. cmdName)
- assert(type(thisCmdFunc.func) == "function", "BAD FUNCTION IN COMMAND CREATION: " .. type(thisCmdFunc.func) .. ": " .. cmdName)
- end
- --stupid tabs...
- commandInfo.help = gsub(commandInfo.help, "\t", "")
- -- Create this command with properties from the Commands class.
- local newCommand = {name = cmdName, info = 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
- -- This function is called whenever a command is attempting to execute.
- -- Execution function is responsible for determining which overloaded command function to execute
- -- In the case of the user using incorrect arguments, this function will parse an error message to respond with.
- function Commands.Execute(thisCommand, arguments, command, executorPlayerId)
- local parsedArguments, newErr
- local err = ""
- -- Loop through all overloaded functions for this command.
- for i = 1,#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)
- return
- elseif newErr == "" then
- -- call the command, and stop looping.
- thisCommand[i].func(executorPlayerId, thisCommand:unpackArguments(parsedArguments))
- return
- else
- err = err .. "\n" .. newErr
- end
- end
- sendresponse(err .. gsub(thisCommand.info.help, ".-Syntax: %%s(.-)", "\nInvalid Syntax: " .. command .. "%1"), executorPlayerId)
- 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
- -- Returns command arguments into lua arguments the Execute function can use.
- -- This function alone is one of the main reasons I converted my if-elseif commands into a metatable. It saved me sooo much duplicate lines of code in the individual commands.
- 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.info.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 = {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'" .. arguments[i] .. "' cannot reference more than one player in this command!" or err
- -- if player wasn't specified, use the executing player.
- 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 (PlayerClass[parsedArguments[i-1]].bancount or 0) or nil)
- elseif argType == "Time" then
- local temp
- argument, temp = getTimeAndReason(concat(arguments, " ", i), self.usesBanCounts and (PlayerClass[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
- --hprintf(concat(arguments, " ", i))
- 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 == "Object" then
- argument = objects[argument]
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid Object!" 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 or argument == false and 0
- err = not argument and arguments[i] and err .."\n'" .. arguments[i] .. "' is not a valid AdminBlocker Type!" or err
- elseif argType == "Remote Banlist Mode" then
- argument = tonumber(argument) or argument
- argument = (argument == 0 or argument == "read-only") and 0 or (argument == 1 or argument == "one-way sync") and 1 or (argument == 2 or argument == "remote-only") and 2 or (argument == 3 or argument == "sync") and 3
- 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
- local function getOperatingSystem()
- local slash_ident = package.config:sub(1,1)
- if slash_ident == "\\" then
- return "Windows"
- elseif slash_ident == "/" then
- return "Unix"
- end
- end
- -- I don't remember why I didn't want to use LFS, maybe I was worried it wouldn't work with SAPP.
- local function lookupFiles(dir)
- local files = {}
- local OS = getOperatingSystem()
- local p
- if OS == "Windows" then
- p = io.popen("dir " .. dir .. " /B /O:gn")
- elseif OS == "Unix" then
- p = io.popen('find "' .. dir .. '" -type f')
- end
- for file in p:lines() do
- insert(files, file)
- end
- end
- -- Script Validation
- function Commands:validscripts(...)
- local dir = getprofilepath() .. "\\scripts\\"
- local scripts = {}
- --LuaFileSystem Method.
- --[[
- require "lfs"
- for f in lfs.dir(dir) do
- if string.find(f, ".lua") then
- local file = io.open(dir .. f, "r")
- local str = file:read("*all")
- if string.find(str, "function GetRequiredVersion()") then
- if f ~= "gametypes.lua" then
- local script = string.gsub(f, ".lua", "")
- if not table.find(scripts, script) then
- table.insert(scripts, script)
- end
- end
- end
- end
- end--]]
- local bool
- local files = lookupFiles(dir)
- local scriptname = ""
- for i = 1,select("#", ...) do
- bool = false
- for i = 1,files do
- if files[i] == select(1, ...) then
- bool = true
- break
- end
- end
- if not bool then
- break
- end
- end
- 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 PlayerClass[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
- PlayerClass[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 playerId = 0,15 do
- if gethash(playerId) == hash then
- PlayerClass[playerId].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 playerId = 0,15 do
- if getplayer(playerId) then
- if netMatch(ip_address, getip(playerId)) then
- PlayerClass[playerId].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 nickname or playerIndex.
- -- Use 'sv_admin_list' to get a list of admins for their nickname.
- -- 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 PlayerClass[playerId].admin_entry then
- cmdreply[cmdreply()] = getname(playerId) .. " was never an admin"
- goto continue
- end
- admin_table[gethash(playerId)] = nil
- ip = getip(playerId)
- for index,thisAdmin in next,admin_table do
- if thisAdmin.type == "ip" and netMatch(index, ip) then
- admin_table[index] = nil
- end
- end
- PlayerClass[playerId].admin_entry = false
- 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()
- local player
- for playerId = 0,15 do player = PlayerClass[playerId]
- if getplayer(playerId) and player and player.admin_entry == thisAdmin then
- player.admin_entry = false
- 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]
- PlayerClass[playerId].afk = true
- cmdreply[cmdreply()] = getname(playerId) .. " is now afk"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- local function check_in_circle(x,y, X, Y, R)
- return (X - x)^2 + (Y - y)^2 <= R
- end
- -- Not finished
- Commands.Create(
- "bubble",
- {
- help = [[-- Bubble
- -- Syntax: %s [Player] {Radius}
- -- Puts a bubble around the player, so people cannot enter it.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, radius)
- radius = radius or 5
- local playerId
- for i = 1,#players do playerId = players[i]
- PlayerClass[playerId].bubble = true
- cmdreply[cmdreply()] = getname(playerId) .. " is now in a bubble with radius of " .. radius
- 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(
- "aliasold",
- {
- aliases = {"oldalias"},
- 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(
- "remotecontrol",
- {
- help = [[-- Remote Control
- -- Syntax: %s {Port or Boolean}
- -- Starts or shuts down the remote control feature.
- -- Use a telnet client like Putty to connect
- -- This command REQUIRES using global rcons (sv_rcon_add). This may be changed later.]],
- },
- {
- arguments = {"Positive Number", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, port)
- if not socket then
- socket = require"socket"
- http = require"socket.http"
- http.TIMEOUT = 1
- end
- port = port <= 65535 and port > 800 and port or error("Ports must be between 65535 and 800. 2303 is recommended.")
- if port then
- server = socket.tcp()
- assert(server:bind("*", port))
- assert(server:listen(9001))
- server:settimeout(0)
- sendresponse("The Remote Control server has been opened on port " .. tostring(port))
- defaults.remotecontrol = registertimer(500, "remoteTimer")
- else
- sendresponse("Remote Control is enabled and currently has " .. #clients .. " clients connected.", executorPlayerId)
- end
- end
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool = ReturnScriptBooleanCheck("Remote Control", defaults.remotecontrol, strBool)
- if newBool then
- if not socket then
- socket = require"socket"
- http = require"socket.http"
- http.TIMEOUT = 1
- end
- server = socket.tcp()
- assert(server:bind("*", 2303))
- assert(server:listen(9001))
- server:settimeout(0)
- sendresponse("The Remote Control server has been opened on port 2303", executorPlayerId)
- defaults.remotecontrol = registertimer(500, "remoteTimer")
- elseif newBool == false then
- for i = 1,#clients do
- clients[i].socket:close()
- end
- server:close()
- server = nil
- end
- end
- }
- )
- 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)
- if newBool ~= nil then
- defaults.anticaps = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.chatcommands = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.chatids = newBool
- end
- sendresponse(response, executorPlayerId)
- end
- }
- )
- function invisCrouch(id, count)
- if not defaults.crouch_camo then return false end
- for playerId = 0,15 do
- local m_playerObj = getplayerobject(playerId)
- if m_playerObj and readbyte(m_playerObj + 0x2A0) == 3 then
- applycamo(playerId, 1)
- end
- end
- return true
- 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 then
- registertimer(200, "invisCrouch")
- defaults.crouch_camo = true
- elseif newBool ~= nil then
- defaults.crouch_camo = false
- end
- sendresponse(response, executorPlayerId)
- end
- }
- )
- --REM possibly rehaul this later, to include output to server consoles, to change the verbosity level of info, etc
- -- Currently, this function enables certain debug messages I've deemed important enough to display.
- -- Will output to the server's console, and to the player's in-game console.
- Commands.Create(
- "debug",
- {
- aliases = {"debugmode", "toggledebug", "enabledebug", "verbose"},
- help = [[--Debug Mode
- -- Syntax: %s {Boolean} {Player}
- -- Turns on this scripts Debug messages, to help identify an issue with the script.
- -- Note: Will enable debug mode for executing player even if a player is specified]]
- },
- {
- arguments = {"Boolean", "Player", minArgs = 0, maxArgs = 2},
- func = function(executorPlayerId, strBool, players)
- local newBool, response = ReturnScriptBooleanCheck("Debug Mode", defaults.debug_mode, strBool)
- if newBool ~= nil then
- defaults.debug_mode = newBool
- if players then
- local playerId
- for i = 1,#players do playerId = players[i]
- debug_players[playerId] = newBool
- end
- elseif executorPlayerId ~= nil then
- debug_players[executorPlayerId] = newBool
- end
- end
- sendresponse(response, executorPlayerId)
- 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)
- 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] = {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] = {joincount = 1, names = {names}}
- unique_table[match(ip, "%d+%.%d+%.%d+%.")] = {joincount = 1, names = {names}}
- end
- end
- end
- end
- file:close()
- elseif newBool ~= nil then
- defaults.uniques_enabled = false
- end
- sendresponse(response, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "deathless",
- {
- aliases = {"d", "deathlessplayer", "deathlessmode"},
- 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)
- if newBool ~= nil then
- defaults.deathless = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.falldamage = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.firstjoin_message = newBool
- end
- sendresponse(response, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "centralbanlist",
- {
- aliases = {"centralbansystem", "remotebansystem", "remotebanlist", "globalbansystem", "globalbanlist", "masterbansystem", "masterbanlist"},
- help = [[-- Remote Ban System
- -- Syntax: %s [Host or Boolean] {PHP Script} {Ban File} {Method}
- -- Changes how the remote ban system works
- -- Check out the manual for information on this feature.
- -- This feature is off by default.]]
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Remote Ban System", not not defaults.remote_bansystem, strBool)
- if newBool == false then
- defaults.remote_bansystem = newBool
- elseif newBool then
- sendresponse("This feature cannot simply be enabled. You must pass a hostname, file, mode, etc.\nCheck out the manual for more information", executorPlayerId)
- return
- end
- sendresponse(response, executorPlayerId)
- end
- },
- {
- arguments = {"String", "String", "String", "Remote Banlist Mode", "Positive Number", minArgs = 4, maxArgs = 5},
- func = function(executorPlayerId, host, phpscript, banfile, mode, port)
- if not socket then
- socket = require"socket"
- http = require"socket.http"
- http.TIMEOUT = 1
- end
- defaults.remote_bansystem = {
- host = host,
- phpscript = phpscript,
- banfile = banfile,
- mode = mode,
- http_source = "http://" .. host .. "/" .. phpscript,
- port = port or 80
- }
- if mode == 0 then -- read-only
- elseif mode == 1 then -- one way (read-only) sync
- elseif mode == 2 then -- remote-only
- elseif mode == 3 then -- sync
- end
- reloadRemoteBanlist()
- updateBanFiles()
- sendresponse("The Remote Ban System is now enabled!", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "firefist",
- {
- aliases = {'arsonist', 'firefister'},
- help = [[-- Firefist
- -- Syntax: %s [Player] {Boolean}
- -- Enable/Disable Firefist for a player.
- ]],
- },
- {
- arguments = {"Player", "Boolean", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, bool)
- local player
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- if bool then
- player.firefist = bool
- sendresponse("Fire fist " .. tostring(bool) .. " for " .. tostring(getname(playerId)), executorPlayerId)
- registertimer(300, "FireFistTimer")
- else
- sendresponse("Fire fist for player " .. tostring(getname(playerId)) .. " is currently " .. tostring(bool), executorPlayerId)
- end
- end
- end
- }
- )
- -- apply flame to receiving player.
- function ApplyFlame(receiverPlayerId, firefisterObjId)
- local playerObjId = getplayerobjectid(receiverPlayerId)
- local x,y,z = getobjectcoords(playerObjId)
- local flame = createobject(flameid, firefisterObjId, 5, true, x, y, z+0.65)
- local xflame = createobject(flameid, firefisterObjId, 5, true, x-0.08, y, z+0.43)
- local gflamefx = createobject(flameid, firefisterObjId, 5, true, x-0.12, y, z+0.04)
- local flameobject = getobject(flame)
- writefloat(flameobject + 0x68, 0)
- writefloat(flameobject + 0x6C, 0)
- writefloat(flameobject + 0x70, -0.2)
- end
- function getBodyPartLocation(m_object, offset)
- --m_object = m_object + (offset or 0x0)
- --unkFloats[10] (???) Probably rotations.
- bipd_bodypart_x = readfloat(m_object, offset + 0x28)
- bipd_bodypart_y = readfloat(m_object, offset + 0x2C)
- bipd_bodypart_z = readfloat(m_object, offset + 0x30)
- return bipd_bodypart_x,bipd_bodypart_y,bipd_bodypart_z
- end
- -- apply flame damage to fist of firefister
- function FireFistTimer(id, cc)
- local playerObjId, m_playerObj, hx, hy, hz, fistflame, ffobject
- local firefisterfound = false
- for playerId = 0,15 do
- if not getplayer(playerId) or not PlayerClass[playerId].firefist then goto nextIter end
- firefisterfound = true
- playerObjId = getplayerobjectid(playerId)
- m_playerObj = getobject(playerObjId)
- if not m_playerObj then goto nextIter end
- hx,hy,hz = getBodyPartLocation(m_playerObj, 0x8C4)
- fistflame = createobject(flameid, 0, 5, true, hx, hy, hz+0.08)
- fistflame2 = createobject(flameid, 0, 5, true, hx, hy, hz+0.1)
- ffobject = getobject(fistflame)
- ffobject2 = getobject(fistflame2)
- writefloat(ffobject + 0x68, 0)
- writefloat(ffobject + 0x6C, 0)
- writefloat(ffobject + 0x70, -0.2)
- writefloat(ffobject2 + 0x68, 0)
- writefloat(ffobject2 + 0x6C, 0)
- writefloat(ffobject2 + 0x70, -0.2)
- ::nextIter::
- end
- if not firefisterfound then
- return false
- end
- return true
- end
- Commands.Create(
- "hashduplicates",
- {
- aliases = {'duplicates', 'allowduplicates'},
- help = [[-- Allow Hash Duplicates
- -- 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)
- if newBool then
- writebyte(addresses.hash_duplicate_patch, 0x74)
- defaults.hash_duplicates = true
- elseif newBool ~= nil then
- writebyte(addresses.hash_duplicate_patch, 0xEB)
- defaults.hash_duplicates = false
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool then
- defaults.infinite_ammo = true
- local player, m_playerObj, playerObjId, m_weaponObj, weaponObjId
- infammo_timer = registertimer(500, "playerWeaponCheckTimer")
- for playerId = 0,15 do
- if not getplayer(playerId) then
- goto continue
- end
- m_playerObj, playerObjId = getplayerobject(playerId)
- if not m_playerObj then
- goto continue
- end
- player = PlayerClass[playerId]
- for slot = 0,3 do
- weaponObjId = player.weapons[slot]
- m_weaponObj = getobject(weaponObjId)
- if m_weaponObj then
- writeshort(m_weaponObj + 0x2B6, 0x7CFF)
- writeshort(m_weaponObj + 0x2B8, 0x7CFF)
- updateammo(weaponObjId)
- player.weapons[slot] = 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 = 0,3 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)
- if not address_magazines or address_magazines == 0 then
- goto continue2
- end
- 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
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.killing_spree = newBool
- end
- sendresponse(response, executorPlayerId)
- end
- }
- )
- -- TODO: Use gametype scorelimit per-player or per-team instead of hardcoded values
- Commands.Create(
- "multiteamvehicles",
- {
- aliases = {"mtvehicles", "mtv"},
- 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)
- if not team_play then
- local m_player
- if newBool then
- --[[if not team_play_temp then
- team_play_temp = team_play
- end
- team_play = true--]]
- for playerId = 0,15 do
- m_player = getplayer(playerId)
- if m_player then
- team_scores[playerId] = player_scores[playerId]
- writebyte(m_player + 0x20, 0)
- end
- end
- writebyte(addresses.gametype_base + 0x58, 255)
- defaults.multiteam_vehicles = true
- elseif newBool ~= nil then
- --team_play = team_play_temp or team_play
- for playerId = 0,15 do
- m_player = getplayer(playerId)
- if m_player then
- writebyte(m_player + 0x20, readbyte(m_player + 0x66))
- end
- end
- writebyte(addresses.gametype_base + 0x58, scorelimit)
- defaults.multiteam_vehicles = false
- end
- else
- sendresponse("Cannot be applied to team games.", executorPlayerId)
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool then
- local m_playerObj, m_weaponObj, weaponObjId
- for playerId = 0,15 do
- m_playerObj = getplayerobject(playerId)
- if m_playerObj then
- for j = 0,3 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
- sendresponse(response, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "pmenabled",
- {
- aliases = {"pvtmessage", "privatemessage", "privatemessageenabled"},
- 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)
- if newBool ~= nil then
- defaults.pm_enabled = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.rtv_enabled = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.sa_message = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- 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
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.tbag_detection = newBool
- end
- sendresponse(response, executorPlayerId)
- 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)
- if newBool ~= nil then
- defaults.votekick_enabled = newBool
- end
- sendresponse(response, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "defaultspawnweapons",
- {
- aliases = {"spawnweapons", "weaponsonspawn", "chooseweapons", "selectweapons", "poontang"},
- help = [[-- Choose Default Spawn Weapons
- -- Syntax: %s {Primary Weapon or 'Default'} {Secondary Weapon} {Tertiary Weapon} {Quaternary Weapon}
- -- Will allow you to change the default weapons that you spawn with.
- -- Not sending arguments will show the current setting of this command.
- -- Sending a single argument 'Default' to this command will use the default weapon spawning.]]
- },
- {
- 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 = 0,3 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
- -- 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.]]
- },
- {
- arguments = {"AdminBlocker Type", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, abtype)
- 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 and 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 redsize = getteamsize(0)
- local bluesize = getteamsize(1)
- if math.abs(redsize - bluesize) > 1 then
- local randPlayerId = SelectRandomPlayer(bluesize > redsize and 1 or 0)
- if randPlayerId then
- changeteam(randPlayerId, true)
- say("Balancing Teams")
- sendresponse("The teams have been balanced", executorPlayerId)
- else
- sendresponse("There was no one found on the other team.")
- end
- else
- sendresponse("Teams are already balanced.", executorPlayerId)
- end
- 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 = {"b", "hashban", "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 .. " attempted to Ban you!")
- goto continue
- end
- hash = gethash(playerId)
- if hash == sharedhashes[hash] then
- cmdreply[cmdreply()] = name .. " has a shared hash, and therefore cannot be hashbanned. Try an IP Ban instead."
- goto continue
- end
- tempBanPlayer(resolveplayer(playerId))
- if time ~= 1 then
- addBan(name, hash, 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"
- end
- ::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 playerId = 0,15 do
- if getplayer(playerId) and gethash(playerId) == hash then
- 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")
- 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 playerId = 0,15 do
- if getplayer(playerId) and netMatch(ip_address, getip(playerId)) then
- 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")
- sendresponse("That IP Address has been banned from the server successfully", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "bos",
- {
- help = [[Ban on Sight
- -- Syntax: %s [Bosplayer Index] {Bantype 'Hash' or 'IP'}
- -- 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 = {"Positive Number", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, playerId)
- local leave_entry = leave_table[playerId]
- if not leave_entry then
- sendresponse("Invalid BoS ID! Use sv_bosplayers to get a list of bosable players.", executorPlayerId)
- return
- end
- local bos_entry
- for i = 1,#bos_table do bos_entry = bos_table[i]
- if bos_entry.hash == leave_entry.hash or netMatch(bos_entry.ip, leave_entry.ip) then
- sendresponse(leave_entry.name .. " is already on the BoS", executorPlayerId)
- return
- end
- end
- 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
- -- check if they are already in the server
- for playerId = 0,15 do
- if getplayer(playerId) then
- if not sharedhashes[leave_entry.hash] and leave_entry.hash == gethash(playerId) or netMatch(leave_entry.ip, getip(playerId)) then
- tempBanPlayer(playerId)
- privateSayAdmins(bos_entry.name .. " banned from BoS.\nEntry: " .. bos_entry.name .. "- " .. bos_entry.hash)
- 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, -1, "ip", "Ban on Sight")
- end
- end
- 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(
- "hashbanlist",
- {
- help = [[-- Hash Ban List
- -- Syntax: %s
- -- Displays all players currently hash banned from the server.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- Commands.banlist[1].func(executorPlayerId, "hash")
- end
- }
- )
- Commands.Create(
- "ipbanlist",
- {
- help = [[-- IP Ban List
- -- Syntax: %s
- -- Displays all players currently IP banned from the server.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- Commands.banlist[1].func(executorPlayerId, "ip")
- end
- }
- )
- Commands.Create(
- "namebanlist",
- {
- help = [[-- Name Ban List
- -- Syntax: %s
- -- Displays all players currently name banned from the server.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- Commands.banlist[1].func(executorPlayerId, "name")
- end
- }
- )
- Commands.Create(
- "textbanlist",
- {
- help = [[-- Text Ban List
- -- Syntax: %s
- -- Displays all players currently chat banned from the server.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- Commands.banlist[1].func(executorPlayerId, "text")
- end
- }
- )
- local function getBanlist(banlists, bantype)
- if banlists ~= "local" then
- --reloadRemoteBanlist()
- end
- local output = {}--TM.New()
- local cur_time = os.time()
- local ban_entry, time
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if banlists == "both" or ban_entry.remote and banlists == "remote" or not ban_entry.remote and banlists == "local" then
- time = ban_entry.time
- if bantype == "all" or (time == -1 or ((time - cur_time) > 0)) and (not bantype or bantype == ban_entry.type) then
- output[#output+1] = format("[%u | %s | %s | %s | %s | %s]", id, ban_entry.name, ban_entry.count or "N/A", ban_entry.type, time ~= -1 and formatTime(timeleft) or "Never", ban_entry.reason or "None")
- end
- end
- end
- return output
- end
- Commands.Create(
- "banlist",
- {
- aliases = {"listbans", "bans", "showbans", "viewbans"},
- help = [[-- Ban List
- -- Syntax: %s {ip | hash | chat | name | all}
- -- Displays all players banned from the server.
- -- Specifying a second argument will filter the list by the specified bantype.
- -- Specifying "all" will show everyone who has ever been banned on this server.]]
- },
- {
- arguments = {"String", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, bantype)
- bantype = bantype and lower(bantype)
- if bantype and bantype ~= "name" and bantype ~= "chat" and bantype ~= "hash" and bantype ~= "ip" and bantype ~= "all" then
- sendresponse("Invalid Bantype. Valid bantypes are IP, Hash, Name, Chat, and All", executorPlayerId)
- return
- end
- cmdreply.header = "[ID | Name | Bans | Type | Expires | Reason]"
- cmdreply.delim = "|"
- cmdreply.align = true
- local args = defaults.remote_bansystem
- local output = getBanlist(not args and "local" or args.mode == 1 and "remote" or "both", bantype)
- for i = 1,#output do
- cmdreply[cmdreply()] = output[i]
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "unban",
- {
- aliases = {"ipunban", "hashunban", "textunban", "nameunban"},
- help = [[-- Unban
- -- Syntax: %s [ID]
- -- Unbans the specified ban entry and allows the person to rejoin the server.
- -- Note: This command will NOT remove people COMPLETELY off the banlist, but will allow the banned player to rejoin.
- -- Use removeban to completely remove someone off the banlist.]]
- },
- {
- arguments = {"Positive Number", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, ID)
- local entry = ban_table[ID]
- local cur_time = os.time()
- local args = defaults.remote_bansystem
- if not entry or (args and args.mode == 2 and not entry.remote) or (entry.time ~= -1 and entry.time <= cur_time) 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 playerId = 0,15 do
- if getplayer(playerId) and netMatch(entry.ip, getip(playerId)) then
- PlayerClass[playerId].muted = false
- end
- end
- end
- local bantype = entry.type
- entry.time = cur_time -- set the ban expire time to the present.
- local name = executorPlayerId and PlayerClass[executorPlayerId].admin_entry and PlayerClass[executorPlayerId].admin_entry.name or getname(executorPlayerId)
- if entry.reason then
- if find(entry.reason, "| Unbanned by '") then
- entry.reason = gsub(entry.reason, " | Unbanned by '[^\']'", " | Unbanned by '" .. name .. "'")
- else
- entry.reason = entry.reason .. " | Unbanned by '" .. name .. "'"
- end
- else
- entry.reason = "None Given | Unbanned by '" .. name .. "'"
- end
- if args and args.mode >= 2 then
- http.request(args.http_source, "&bans=" .. toBanTextEntry(entry) .. "&unban=true")
- end
- updateBanFiles(bantype) -- update banlist file.
- sendresponse(bantype .. " ban '" .. index .. "' has been unbanned from the banlist!", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "removeban",
- {
- aliases = {"banremove", "deleteban", "bandelete", "wipeban", "banwipe"},
- help = [[-- Remove Ban
- -- Syntax: %s [ID]
- -- Similar to unban but will completely remove the ban entry from the banlist
- -- Note: this will NOT remove bans on a central remote banlist, but instead will unban them!]]
- },
- {
- arguments = {"Positive Number", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, ID)
- local entry = ban_table[ID]
- local cur_time = os.time()
- local args = defaults.remote_bansystem
- if not entry or (args and args.mode == 2 and not entry.remote) or (entry.time ~= -1 and entry.time <= cur_time) 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 playerId = 0,15 do
- if getplayer(playerId) and netMatch(entry.ip, getip(playerId)) then
- PlayerClass[playerId].muted = false
- end
- end
- end
- -- remove the ban entry from the banlist completely
- remove(ban_table, ID)
- if args and args.mode >= 2 then
- http.request(args.http_source, "&bans=" .. toBanTextEntry(entry) .. "&unban=true")
- end
- 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
- -- Displays the Ban On Sight list
- -- These people will be automatically added to the banlist when they join the server.
- -- Use unbos to remove from this 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.
- -- This list is constructed from people who leave the server.]]
- },
- {
- 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", "changelevel", "level", "modifylevel", "changeadminlevel", "modifyadminlevel", "setadminlevel"},
- help = [[-- Change Level Command
- -- Syntax: %s [Nickname] {Level}
- -- Change the specified admins' level]]
- },
- {
- arguments = {"String", "Access Level", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, nickname, level)
- 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
- if level then
- thisAdmin.level = level
- sendresponse(nickname .. " is now a level " .. level .. (thisAdmin.type == "ip" and " IP Admin" or " Hash Admin"), executorPlayerId)
- updateAdminFiles()
- else
- sendresponse(nickname .. " is currently a level " .. thisAdmin.level .. (thisAdmin.type == "ip" and " IP Admin" or " Hash Admin"), executorPlayerId)
- end
- return
- end
- end
- sendresponse("Invalid Nickname", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "changeteam",
- {
- aliases = {"ts", "teamchange", "swapteam", "teamswap"},
- help = [[-- Change team Command
- -- Syntax: %s [Player]
- -- Change the specified players team]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- if team_play then
- local playerId
- for i = 1,#players do playerId = players[i]
- changeteam(playerId, true)
- sendresponse(getname(playerId) .. " has been forced to change teams", executorPlayerId)
- end
- else
- sendresponse("Can only be applied to team games.", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "disconnect",
- {
- aliases = {"losenetworkconnection", "loseconnection", "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_pointer) -- 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", "listcommands", "showcommands", "allcommands", "getcommands", "viewcommands"},
- 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 admin_entry = PlayerClass[executorPlayerId].admin_entry
- if admin_entry and admin_entry ~= true then
- sendresponse(concat(access_table[admin_entry.level or 0], " | "), 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
- -- Use this command sparingly. It has been known to crash servers (ironic right?) on abuse]]
- },
- {
- 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 .. " attempted to Crash you!")
- goto continue
- end
- local mapId = gettag("vehi", "vehicles\\warthog\\mp_warthog")
- if mapId then
- objectId = createobject(mapId, 0, 1, false, 0, 1, 2)
- if not objectId then break end
- end
- 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 = 2, maxArgs = 2},
- func = function(executorPlayerId, players, value)
- local playerId
- for i = 1,#players do playerId = players[i]
- if value then
- PlayerClass[playerId].dmgmultiplier = value
- cmdreply[cmdreply()] = getname(playerId) .. " now has a damage multiplier of " .. value
- else
- cmdreply[cmdreply()] = getname(playerId) .. " has a damage multiplier of " .. PlayerClass[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 a rcon password", executorPlayerId)
- return
- end
- rcon_passwords[password] = nil
- sendresponse(password .. " is no longer a 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 and isinvehicle(playerId) then
- exitvehicle(playerId)
- cmdreply[cmdreply()] = "Ejecting " .. getname(playerId) .. " from their vehicle"
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is not in a vehicle"
- 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' world 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 = {"g", "god", "godmode", "godset", "cheatgod", "cheatsetgod", "cheatgodmode", "cheatinvincible", "invincible"},
- 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 enabled. You cannot give out godmode", executorPlayerId)
- return
- end
- local playerId, player, m_playerObj
- for i = 1,#players do playerId = players[i]
- m_playerObj = getplayerobject(playerId)
- if m_playerObj then
- player = PlayerClass[playerId]
- if not player.godmode then
- cmdreply[cmdreply()] = getname(playerId) .. " has been given godmode"
- player.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", "cheatheal", "restorehealth", "cheatrestorehealth", "cheatheal"},
- 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, mapId, 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)
- mapId = gettag("eqip", "powerups\\health pack")
- if mapId then
- healthpack = getobject(createobject(mapId, 0, 0, false, x, y, z+0.5))
- else
- cmdreply[cmdreply()] = "Health Pack could not be spawned!"
- end
- 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", "cheathide"},
- scrimBlock = true,
- help = [[-- Hide
- -- Syntax: %s [Player]
- -- You are invisible. Not Camo.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, player
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- if not player.hidden then
- cmdreply[cmdreply()] = getname(playerId) .. " is now hidden"
- player.hidden = true
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is already hidden"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "info",
- {
- aliases = {"i", "playerinfo", "infoplayer", "getplayerinfo", "getinfo"},
- 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
- 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
- for i = 1,#players do playerId = players[i]
- local m_player = getplayer(playerId)
- local ip = getip(playerId)
- local player = PlayerClass[playerId]
- 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 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 player.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", player.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", player.hidden, player.godmode, player.afk)
- cmdreply[cmdreply()] = "----------"
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "ipban",
- {
- aliases = {"banip", "ipbanplayer"},
- 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 .. " attempted to IPBan you!")
- goto continue
- end
- tempBanPlayer(resolveplayer(playerId))
- 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")
- say(name .. " was IP banned! Reason: " .. reason)
- 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", 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", "cheatsetcamo", "cheatcamo", "cheatgivecamo", "givecamo"},
- 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, player
- 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
- player = PlayerClass[playerId]
- if player.invisible then
- cmdreply[cmdreply()] = getname(playerId) .. " is already invisible"
- goto continue
- end
- player.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] {Reason}
- -- 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 .. " attempted to Kick 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", "cheatkill", "cheatkillplayer"},
- 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", "startscrim"},
- 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
- sendresponse("Live on three.", executorPlayerId)
- lo3_timer = registertimer(500, "lo3Timer")
- end
- sendresponse("Live on three.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "login",
- {
- aliases = {"l"},
- 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
- if PlayerClass[executorPlayerId].tempadmin then
- sendresponse("You are already logged in", executorPlayerId)
- return
- end
- if PlayerClass[executorPlayerId].admin_entry then
- sendresponse("You are already an admin!", executorPlayerId)
- return
- end
- if admin_logins[username] == password then
- PlayerClass[executorPlayerId].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"
- 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)
- local m_vehicleObj = getplayervehicle(playerId)
- if m_vehicleObj then -- these four lines are only in here for shoo.
- writebit(m_vehicleObj + 0x10, 5, 1)
- end
- cmdreply[cmdreply()] = getname(playerId) .. " has been moved"
- else
- cmdreply[cmdreply()] = getname(playerId) .. " is dead"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- --TODO: sv_announce_bans
- Commands.Create(
- "nameban",
- {
- aliases = {"banname"},
- help = [[-- Name Ban
- -- Syntax: %s [Player]
- -- Bans a use of a name in the server]]
- },
- {
- 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 .. " attempted to NameBan you!")
- goto continue
- end
- if not randomNames[name] then
- b = {}--TM.New()
- b.name, b.type = name, "name"
- local args = defaults.remote_bansystem
- if args and args.mode == 2 then
- b.remote = true
- end
- ban_table[#ban_table+1] = b
- updateBanFiles()
- cmdreply[cmdreply()] = halo_svcmd("sv_kick " .. resolveplayer(playerId), true)
- say(name .. " has been name banned from the server")
- ::found::
- else
- cmdreply[cmdreply()] = "You cannot ban this name because this name has been assigned automatically."
- end
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "overshield",
- {
- aliases = {"os", "giveos", "osgive", "giveovershield", "overshieldgive", "cheatgiveos", "cheatosgive", "cheatovershield", "cheatplayerovershield", "cheatgiveovershield", "cheatovershieldgive"},
- 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, mapId, 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)
- mapId = gettag("eqip", "powerups\\overshield")
- if mapId then
- overshield = getobject(createobject(mapId, 0, 0, false, x, y, z+0.5))
- else
- cmdreply[cmdreply()] = "Overshield could not be spawned!"
- end
- 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", "showplayers", "listplayers"},
- help = [[-- Player List
- -- Syntax: %s
- -- Displays a list of players.
- -- 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 rconId = 1,16 do playerId = rresolveplayer(rconId)
- if getplayer(playerId) then
- cmdreply[cmdreply()] = "[" .. rconId .. " (" .. playerId .. ") | " .. getname(playerId) .. "]"
- end
- 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, PlayerClass[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
- 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",
- {
- aliases = {"resetweaps", "weaponsreset", "weapsreset"},
- 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, player, m_playerObj
- for i = 1,#players do playerId = players[i]
- PlayerClass[playerId].disarmed = false
- resetweapons(playerId)
- cmdreply[cmdreply()] = getname(playerId) .. " had their weapons reset"
- 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", "totalrtv", "rtvtotal", "rtvpercent", "rtvpercentage", "rockthevoteneeded", "rockthevotepercent", "rockthevotetotal", "totalrockthevote", "midgamevoteneeded"},
- 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",
- {
- aliases = {"rockthevotetimeout"},
- 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", "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(
- "color",
- {
- aliases = {"setcolor", "colorset", "playercolor", "cheatsetcolor", "cheatplayercolor"},
- 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)
- -- check if argument is correct color
- if color then
- color = tonumber(color) or player_colors[color]
- if type(color) ~= "number" then
- sendresponse("Invalid Color", executorPlayerId)
- return
- end
- end
- local color_name = player_colors[color]
- local playerId, m_playerObj, playerObjId, player, x, y, z
- for i = 1,#players do playerId = players[i]
- if not color then
- cmdreply[cmdreply()] = getname(playerId) .. " is currently " .. (player_colors[readbyte(getplayer(playerId) + 0x60)] or "Invalid Color")
- goto continue
- end
- setcolor(playerId, color)
- cmdreply[cmdreply()] = getname(playerId) .. " had their color changed to '" .. color_name .. "'"
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "assists",
- {
- aliases = {"setassists", "assistset"},
- scrimBlock = true,
- help = [[-- Set Assists
- -- Syntax: %s [Player] {Assists}
- -- Set the assists for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, assists)
- local playerId
- if not assists then
- for i = 1,#players do playerId = players[i]
- cmdreply[cmdreply()] = getname(playerId) .. " Assists: " .. tostring(readshort(getplayer(playerId) + 0xA4, assists))
- end
- else
- for i = 1,#players do playerId = players[i]
- writeshort(getplayer(playerId) + 0xA4, assists)
- cmdreply[cmdreply()] = getname(playerId) .. " had their assists set to " .. assists
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "deaths",
- {
- aliases = {"setdeaths", "deathset"},
- scrimBlock = true,
- help = [[-- Set Deaths
- -- Syntax: %s [Player] {Deaths}
- -- Set the deaths for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, deaths)
- local playerId
- if not deaths then
- for i = 1,#players do playerId = players[i]
- cmdreply[cmdreply()] = getname(playerId) .. " Deaths: " .. tostring(readshort(getplayer(playerId) + 0xAE, deaths))
- end
- else
- for i = 1,#players do playerId = players[i]
- writeshort(getplayer(playerId) + 0xAE, deaths)
- cmdreply[cmdreply()] = getname(playerId) .. " had their deaths set to " .. deaths
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "kills",
- {
- aliases = {"setkills", "killset"},
- scrimBlock = true,
- help = [[-- Set Kills
- -- Syntax: %s [Player] {Kills}
- -- Set the kills for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, kills)
- local playerId
- if not kills then
- for i = 1,#players do playerId = players[i]
- cmdreply[cmdreply()] = getname(playerId) .. " Kills: " .. tostring(readshort(getplayer(playerId) + 0x9C, kills))
- end
- else
- for i = 1,#players do playerId = players[i]
- writeshort(getplayer(playerId) + 0x9C, kills)
- cmdreply[cmdreply()] = getname(playerId) .. " had their kills set to " .. kills
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "score",
- {
- aliases = {"setscore", "scoreset"},
- scrimBlock = true,
- help = [[-- Set Score
- -- Syntax: %s [Player] {Score}
- -- Set the score for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, score)
- local playerId
- if not score then
- for i = 1,#players do playerId = players[i]
- cmdreply[cmdreply()] = getname(playerId) .. ": " .. getscore(playerId)
- end
- else
- 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
- end
- }
- )
- Commands.Create(
- "teamscore",
- {
- aliases = {"setteamscore", "seteamscore", "teamscoreset"},
- scrimBlock = true,
- help = [[-- Set Team Score
- -- Syntax: %s [Team] {Score}
- -- Set the score for the specified team]]
- },
- {
- arguments = {"Whole Number", "Whole Number", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, team, score)
- if not score then
- sendresponse("Team " .. team .. ": " .. getteamscore(team), executorPlayerId)
- else
- setteamscore(team, score)
- sendresponse("Team " .. team .. " had their score set to " .. score, executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "scorelimit",
- {
- aliases = {"setscorelimit"},
- help = [[-- Set Score Limit
- -- Syntax: %s {Score}
- -- Set the score for the specified players]]
- },
- {
- arguments = {"Whole Number", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, score)
- if not score then
- sendresponse("Scorelimit: " .. getscorelimit(), executorPlayerId)
- else
- sendresponse("Scorelimit set to " .. (setscorelimit(score) or score), executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "frags",
- {
- aliases = {"setfrags", "fragset", "setfragnades"},
- scrimBlock = true,
- help = [[-- Set Frags
- -- Syntax: %s [Player] {Frags}
- -- Set the frags for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 1, 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
- if not frags then
- cmdreply[cmdreply()] = getname(playerId) .. " Frags: " .. readbyte(m_playerObj + 0x31E)
- else
- writebyte(m_playerObj + 0x31E, frags)
- cmdreply[cmdreply()] = "Setting " .. getname(playerId) .. "'s frag grenades to " .. frags
- --privatesay(playerId, "Your frag grenades were set to " .. frags)
- end
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "plasmas",
- {
- aliases = {"setplasmas", "stickies", "plasmaset", "setplasmanades"},
- scrimBlock = true,
- help = [[-- Set Plasmas
- -- Syntax: %s [Player] {Plasmas}
- -- Set the plasmas for the specified players]]
- },
- {
- arguments = {"Player", "Whole Number", minArgs = 1, 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
- if not plasmas then
- cmdreply[cmdreply()] = getname(playerId) .. " Plasmas: " .. readbyte(m_playerObj + 0x31E)
- else
- writebyte(m_playerObj + 0x31E, plasmas)
- cmdreply[cmdreply()] = "Setting " .. getname(playerId) .. "'s plasma grenades to " .. plasmas
- --privatesay(playerId, "Your plasma grenades were set to " .. plasmas)
- end
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "prefix",
- {
- aliases = {"setprefix", "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 **SERVER**", 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(
- "say",
- {
- help = [[-- Server Say
- -- Syntax: %s [Message]
- -- Will send a message as the Server to anyone currently in the game.]]
- },
- {
- arguments = {"String", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, message)
- say(message)
- end
- }
- )
- Commands.Create(
- "mode",
- {
- aliases = {"setmode", "modeset"},
- scrimBlock = true,
- help = [[-- mode
- -- Syntax: %s [Player] [Mode] {Object}
- -- destroy
- -- portalgun
- -- entergun
- -- spawngun
- -- normal]]
- },
- {
- arguments = {"Player", "String", "String", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, players, bulletmode)
- local playerId
- for i = 1,#players do playerId = players[i]
- if bulletmode == "destroy" then
- PlayerClass[playerId].bulletmode = "destroy"
- cmdreply[cmdreply()] = getname(playerId) .. " is now in destroy mode"
- elseif bulletmode == "portalgun" then
- PlayerClass[playerId].bulletmode = "portalgun"
- cmdreply[cmdreply()] = getname(playerId) .. " is now in portalgun mode"
- elseif bulletmode == "entergun" then
- PlayerClass[playerId].bulletmode = "entergun"
- cmdreply[cmdreply()] = getname(playerId) .. " is now in entergun mode"
- elseif bulletmode == "normal" or bulletmode == "none" or bulletmode == "regular" then
- local player = PlayerClass[playerId]
- player.objspawnid = false
- player.bulletmode = false
- cmdreply[cmdreply()] = getname(playerId) .. " is now in normal mode"
- elseif bulletmode then
- cmdreply[cmdreply()] = "Invalid Bullet Mode!"
- else
- cmdreply[cmdreply()] = getname(playerId) .. " Bulletmode: " .. PlayerClass[playerId.bulletmode]
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- },
- {
- arguments = {"Player", "String", "Object", minArgs = 3, maxArgs = 3},
- func = function(executorPlayerId, players, bulletmode, object)
- if bulletmode == "spawngun" then
- local playerId, player
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- player.bulletmode = "spawngun"
- player.objspawnid = object.mapId
- cmdreply[cmdreply()] = getname(playerId) .. " is now spawning " .. object.name .. ""
- end
- else
- sendresponse("Invalid Bullet Mode!", executorPlayerId)
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "password",
- {
- aliases = {"setpass", "pass", "setpassword", "passwordset"},
- help = [[-- Set Server Password
- -- Syntax: %s {Password}
- -- Self-explanatory.]]
- },
- {
- arguments = {"Password", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, password)
- if not password then
- sendresponse("The password is currently: " .. 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(
- "loadbanlist",
- {
- aliases = {"banlistload", "loadbans", "bansload", "mergebans", "bansmerge", "mergebanlist", "banlistmerge"},
- help = [[-- Reload Banlist
- -- Syntax: %s
- -- Loads all bans from the ban file.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- -- Save the ban table temporarily
- local temp_bantable = {}--TM.New()
- for id = 1,#ban_table do
- temp_bantable[id] = ban_table[id]
- 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")
- -- 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 cur_time = os.time()
- local hash, ip, ban_entry
- for playerId = 0,15 do
- if not getplayer(playerId) then
- goto continue
- end
- hash, ip = gethash(playerId), getip(playerId)
- for id = 1,#ban_table do ban_entry = ban_table[id]
- if ban_entry.time > cur_time then
- if ban_table.type == "hash" and hash == ban_table.hash or ban_table.type == "ip" and netMatch(ban_table.ip, ip) then
- tempBanPlayer(resolveplayer(playerId))
- break
- elseif ban_entry.type == "chat" and (ban_entry.hash == hashOnlyOnScriptReload or netMatch(ban_entry.ip, ip)) then
- PlayerClass[playerId].muted = true
- elseif ban_entry.type == "name" and ban_entry.name == name then
- svcmd("sv_kick " .. resolveplayer(playerId) .. " Found on the Name Banlist during a reload.")
- break
- end
- end
- end
- ::continue::
- end
- updateBanFiles()
- sendresponse("The Banlist has been reloaded.", executorPlayerId)
- end
- }
- )]====]
- Commands.Create(
- "reloadbanlist",
- {
- aliases = {"banlistreload", "reloadbans", "bansreload", "refreshipbans"},
- help = [[-- Reload Banlist
- -- Syntax: %s
- -- Loads all bans from the ban file.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayerId)
- -- Clear the ban table.
- for id = 1,#ban_table do
- ban_table[id] = nil
- end
- local args = defaults.remote_bansystem
- if args then
- reloadRemoteBanlist()
- end
- if not args or args and args.mode ~= 2 then
- 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")
- -- 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")
- end
- -- The banned player could be currently playing on the server. Apply punishments to players that are found on the banlist.
- for playerId = 0,15 do
- if getplayer(playerId) then
- punishIfOnBanlist(playerId)
- end
- end
- updateBanFiles()
- sendresponse("The Banlist has been reloaded.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "respawntime",
- {
- aliases = {"setresp", "setrespawntime"},
- 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
- 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
- }
- )
- local function saveTeleportsToFile()
- local file = assert(io.open(profilepath .. "data\\locations.txt", "w"))
- local writetbl = {}
- 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"))
- file:close()
- end
- Commands.Create(
- "setteleport",
- {
- aliases = {"settp", "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] = {x, y, z}
- sendresponse("'" .. locname .. "' has been added as a teleport location!", executorPlayerId)
- end
- },
- {
- arguments = {"String", "Single Player", minArgs = 1, maxArgs = 2},
- 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] = {x, y, z}
- sendresponse("'" .. locname .. "' has been added as a teleport location!", executorPlayerId)
- saveTeleportsToFile()
- 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)
- map = map or Map or "all"
- sendresponse("Teleport Locations " .. (map ~= "all" 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 map == thisMap or map == "all" then
- cmdreply[cmdreply()] = thisMap .. " " .. locname
- end
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "allvehicles",
- {
- aliases = {"allvehis", "spawnvehicles", "spawnallvehicles", "spawnvehis", "spawnallvehi", "spawnallvehis"},
- help = [[ -- Spawn All Vehicles
- -- Syntax: %s {Player}
- -- Spawns all vehicles available to a map at a specific player's location.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local tag_class, tag_id, tag_name_address, tag_name, tag_address, playerId, playerObjId, m_playerObj, x, y, z
- for j = 1,#players do playerId = players[j]
- for i = 1,#tag_table.vehi do tag_id = tag_table.vehi[i]
- --for tag_id,tag_entry in pairs(tag_table) do
- playerObjId = getplayerobjectid(playerId)
- m_playerObj = getobject(playerObjId)
- x,y,z = getobjectcoords(playerObjId)
- x = x + readfloat(m_playerObj + 0x230) * 2
- y = y + readfloat(m_playerObj + 0x234) * 2
- createobject(tonumber(tag_id), 0, 65534, false, x, y + i*2, z+2)
- sendresponse("Vehicle '" .. tostring(tag_id) .. "' spawned at " .. getname(playerId) .. "'s location!", playerId)
- end
- end
- sendresponse(#tag_table.vehi .. " of each vehicle was spawned.", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "allweapons",
- {
- aliases = {"allweaps", "spawnweapons", "spawnallweapons", "spawnweaps", "spawnallweap", "spawnallweaps"},
- help = [[ -- Spawn All Weapons
- -- Syntax: %s {Player}
- -- Spawns all weapons available to a map at a specific player's location.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local tag_class, tag_id, tag_name_address, tag_name, tag_address, playerId, playerObjId, m_playerObj, x, y, z, iter, objectId, m_object
- for i = 1,#players do playerId = players[i]
- iter = 0
- for tag_id,tag_entry in pairs(tag_table) do
- if type(tag_entry) == "table" and tag_entry.tag_class == "weap" then
- playerObjId = getplayerobjectid(playerId)
- m_playerObj = getobject(playerObjId)
- x,y,z = getobjectcoords(playerObjId)
- x = x + readfloat(m_playerObj + 0x230) * 2
- y = y + readfloat(m_playerObj + 0x234) * 2
- objectId = getobject(createobject(tonumber(tag_id), 0, 65534, true, x, y + iter, z+2))
- m_object = getobject(objectId)
- if m_object then
- end
- sendresponse("Weapon '" .. tostring(tag_id) .. "' spawned at " .. getname(playerId) .. "'s location!", playerId)
- iter = iter + 0.5
- end
- end
- end
- end
- }
- )
- Commands.Create(
- "allequipment",
- {
- aliases = {"alleqip", "spawnequipment", "spawnallequipment", "spawneqips", "spawnalleqip", "spawnalleqips"},
- help = [[ -- Spawn All Equipment
- -- Syntax: %s {Player}
- -- Spawns all weapons available to a map at a specific player's location.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local tag_class, tag_id, tag_name_address, tag_name, tag_address, playerId, playerObjId, m_playerObj, x, y, z, iter
- for i = 1,#players do playerId = players[i]
- iter = 0
- for tag_id,tag_entry in pairs(tag_table) do
- if type(tag_entry) == "table" and tag_entry.tag_class == "eqip" then
- playerObjId = getplayerobjectid(playerId)
- m_playerObj = getobject(playerObjId)
- x,y,z = getobjectcoords(playerObjId)
- x = x + readfloat(m_playerObj + 0x230) * 2
- y = y + readfloat(m_playerObj + 0x234) * 2
- createobject(tonumber(tag_id), 0, 65534, true, x, y + iter, z+2 + iter*2)
- sendresponse("Equipment '" .. tostring(tag_id) .. "' spawned at " .. getname(playerId) .. "'s location!", playerId)
- iter = iter + 0.25
- end
- end
- end
- end
- }
- )
- -- ADD JETPACK COMMAND FROM BRANDIS SCRIPT HERE!
- Commands.Create(
- "ghost",
- {
- aliases = {"ghostplayer"},
- help = [[ -- Ghost Player
- -- Syntax: %s [Player]
- -- Puts a player into Ghost Mode, they will not have a collision model
- -- bullets will pass right through them ]]
- },
- {
- 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
- writebit(m_playerObj + 0x10, 0, 1)
- sendresponse(getname(playerId) .. " is now a ghost!", executorPlayerId)
- --privatesay(playerId, "You are now a ghost.")
- else
- sendresponse("You cannot ghost " .. getname(playerId) .. " because " .. getname(playerId) .. " is dead!", executorPlayerId)
- end
- end
- end
- }
- )
- Commands.Create(
- "unghost",
- {
- aliases = {"ghostplayer"},
- help = [[ -- Unghost Player
- -- Syntax: %s [Player]
- -- Removes a player from Ghost Mode]]
- },
- {
- 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
- writebit(m_playerObj + 0x10, 0, 0)
- sendresponse(getname(playerId) .. " is no longer a ghost!", executorPlayerId)
- else
- sendresponse("You cannot unghost " .. getname(playerId) .. " because " .. getname(playerId) .. " is dead!", executorPlayerId)
- end
- end
- end
- }
- )
- local function updateObjectPhysics(objId, m_object)
- m_object = m_object or getobject(objId)
- if m_object then
- writebit(m_object + 0x10, 0, 0) -- Unset noCollisions bit.
- writebit(m_object + 0x10, 5, 0) -- Unset ignorePhysics.
- end
- end
- local function setVehicleUpright(objId, m_object)
- m_object = m_object or getobject(objId)
- if m_object then
- writefloat(m_object + 0x8A, 2.3 * (10 ^ -41))
- writefloat(m_object + 0x8C, 2.3 * (10 ^ -41))
- writefloat(m_object + 0x90, 2.3 * (10 ^ -41))
- writefloat(m_object + 0x94, 2.3 * (10 ^ -41))
- updateObjectPhysics(objId, m_object)
- end
- end
- Commands.Create(
- "upright",
- {
- aliases = {"rotate", "flip", "f", "setupright"},
- help = [[ -- Upright Vehicle
- -- Syntax: %s [Player]
- -- Places a player's vehicle in the upright position.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, playerVehiObjId, m_vehicleObj
- for i = 1,#players do playerId = players[i]
- playerVehiObjId = getplayervehicleid(playerId)
- m_vehicleObj = getobject(playerVehiObjId)
- if m_vehicleObj then
- setVehicleUpright(playerVehiObjId, m_vehicleObj)
- sendresponse(getname(playerId) .. " has been rotated upright!", executorPlayerId)
- else
- sendresponse(getname(playerId) .. " is not in a vehicle!", executorPlayerId)
- end
- end
- end
- },
- {
- arguments = {"Boolean", minArgs = 0, maxArgs = 1},
- func = function(executorPlayerId, strBool)
- local newBool, response = ReturnScriptBooleanCheck("Antiflip", defaults.antiflip, strBool)
- if newBool ~= nil then
- defaults.antiflip = newBool
- end
- sendresponse(response, executorPlayerId)
- 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 = {"Object", "Player", "Positive Number", "Whole Number", "Boolean", minArgs = 1, maxArgs = 5},
- func = function(executorPlayerId, object, players, amount, resp_time, bRecycle, spawn_type)
- amount = amount or 1
- bRecycle = not not bRecycle
- if spawn_type == "enter" and object.type ~= "vehi" then
- sendresponse("Invalid Vehicle!", executorPlayerId)
- return
- end
- if spawn_type == "give" and object.type ~= "weap" then
- sendresponse("Invalid Weapon!", executorPlayerId)
- return
- end
- if not object.mapId or object.mapId < 400 then
- sendresponse("Object " .. object.name .. " could not be spawned at this time.", executorPlayerId)
- return
- end
- local playerId, m_playerObj, playerObjId, objectId, x, y, z
- 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
- -- Spawn the object right where they are looking (should work for vehicles too)
- x,y,z = getobjectcoords(playerObjId)
- x = x + readfloat(m_playerObj + 0x230) * 2
- y = y + readfloat(m_playerObj + 0x234) * 2
- -- Create the object
- for i = 0,amount-1 do
- --hprintf(tostring(object.mapId))
- objectId = createobject(object.mapId, 0, resp_time, bRecycle, x, y + i, z+2 + i*2)
- end
- -- check if object was spawned correctly
- if not objectId then
- cmdreply[cmdreply()] = "Error spawning object: " .. object.name
- goto continue
- end
- if spawn_type == "give" then
- assignweapon(playerId, objectId)
- cmdreply[cmdreply()] = object.name .. " given to " .. getname(playerId)
- elseif spawn_type == "enter" then
- local drones = PlayerClass[playerId].drones
- drones[#drones+1] = objectId
- entervehicle(playerId, objectId, 0)
- cmdreply[cmdreply()] = getname(playerId) .. " was forced to enter a " .. object.name
- else
- cmdreply[cmdreply()] = object.name .. " spawned at " .. getname(playerId) .. "'s location."
- end
- ::continue::
- end
- sendresponse(cmdreply, executorPlayerId)
- 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 = {"Object", "Player", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, object, players) Commands.spawn[1].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", "cheatgiveweapon"},
- scrimBlock = true,
- help = [[-- Give
- -- Syntax: %s [Object] [Player]
- -- Gives specified player the specified weapon]]
- },
- {
- arguments = {"Object", "Player", minArgs = 1, maxArgs = 2},
- func = function(executorPlayerId, object, players) Commands.spawn[1].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(
- "mapcyclebegin",
- {
- aliases = {"mcbegin", "startcycle", "cyclestart", "mc"},
- 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(
- "ffa",
- {
- aliases = {"setffa"},
- help = [[-- Set FFA
- -- Syntax: %s
- -- Hard-forces the current slayer game to act like a FFA gametype.
- -- unknown how it works on other gametypes.]]
- },
- {
- arguments = {minArgs = 0, maxArgs = 0},
- func = function(executorPlayer)
- local m_player, client_network_struct, client_color
- local ce = 0x0
- if Game == "CE" then
- ce = 0x40
- end
- for playerId = 0,15 do
- m_player = getplayer(playerId)
- if m_player then
- writebyte(m_player + 0x20, playerId)
- client_network_struct = addresses.network_struct + 0x1AA+ce + playerId * 0x20
- client_color = readword(client_network_struct + 0x18)
- --say(getname(playerId) .. " is trying to turn " .. tostring(player_colors[client_color]) .. " aka " .. tostring(client_color) .. " name: " .. tostring(readwidestring(client_network_struct, 12)))
- setcolor(playerId, client_color)
- cmdreply[cmdreply()] = "Setting player " .. tostring(getname(playerId)) .. " to team " .. playerId .. " with color " .. player_colors[client_color]
- end
- end
- team_play = false
- sendresponse(cmdreply, executorPlayerId)
- sendresponse("FFA applied successfully", executorPlayerId)
- end
- }
- )
- Commands.Create(
- "teams",
- {
- aliases = {"setteams"},
- help = [[-- Set Teams
- -- Syntax: %s
- -- Hard-forces the current slayer game to act like a Team gametype.
- -- unknown how it works on other gametypes.]]
- },
- {
- arguments = {"Whole Number", minArgs = 0, maxArgs = 1},
- func = function(executorPlayer, amount)
- amount = amount or 2
- local m_player, team
- for playerId = 0,15 do
- m_player = getplayer(playerId)
- if m_player then
- writebyte(m_player + 0x20, playerId%amount)
- setcolor(playerId, playerId%amount+2)
- team = getteam(playerId)
- team_scores[team] = team_scores[team] + getscore(playerId)
- cmdreply[cmdreply()] = "Setting player " .. tostring(getname(playerId)) .. " to team " .. (playerId%amount)
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- sendresponse("Teams applied successfully", executorPlayerId)
- team_play = true
- end
- }
- )
- --[[Commands.Create(
- "map",
- {
- aliases = {"m", "setmap", "choosemap"},
- is_alias = true,
- help = -- Set Map
- -- Syntax: %s [Map] [Gametype] {script1} {script2} {script3 etc..}
- -- Ends the current game, and starts a new game on selected map and gametype.
- },
- {
- arguments = {"Remaining Arguments", minArgs = 1, maxArgs = 10},
- func = function(executorPlayerId, mapargs)
- halo_svcmd("sv_mapcycle_timeout 1")
- halo_svcmd("sv_mapvote 0")
- sendresponse("sv_map " .. mapargs, executorPlayerId)
- sendresponse(halo_svcmd("sv_map " .. mapargs, true), executorPlayerId)
- end
- }
- )]]
- Commands.Create(
- "statusmore",
- {
- aliases = {"serverinfo", "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
- sendresponse(key .. ": " .. tostring(value), executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "superban",
- {
- aliases = {"ultraban", "megaban"},
- help = [[-- Superban
- -- Syntax: %s [Player] {Time} {Reason}
- -- 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 .. " attempted to SuperBan 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)
- say(name .. " was Super Banned from the server! Reason: " .. reason)
- -- Create name ban.
- local b = {}--TM.New()
- b.name,b.type,b.reason = name,"name",reason
- ban_table[#ban_table+1] = b
- -- Add IP Ban
- addBan(name, nil, getip(playerId) .. "/24", time, "ip", reason)
- -- Execute Hash Ban
- svcmd("sv_ban " .. resolveplayer(playerId) .. " " .. timetoword(time))
- ::continue::
- end
- end
- }
- )
- Commands.Create(
- "suspend",
- {
- aliases = {"suspendplayer", "playersuspend", "suspendpl", "sleep", "cheatsuspendplayer"},
- 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, player
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- if player.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)
- player.suspended = time ~= -1 and time or true
- say(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]
- -- Unsuspends 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 PlayerClass[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", "takeweaps", "weaponsremove", "weapsremove", "weapstake"},
- scrimBlock = true,
- help = [[-- Take Weapons
- -- Syntax: %s [Player]
- -- Take all the weapons away from the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, m_playerObj, playerObjId
- for i = 1,#players do playerId = players[i]
- PlayerClass[playerId].disarmed = true
- m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- for slot = 0,3 do
- local m_weapon, weaponObjId = getplayerweapon(playerId, slot)
- 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)
- return
- end
- saveTeleportsToFile()
- end
- }
- )
- Commands.Create(
- "teleport",
- {
- aliases = {"tp", "t", "teletolocation", "tele", "teletoloc"},
- 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", "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, player
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- if PlayerClass[playerId].admin_entry then
- cmdreply[cmdreply()] = "Admins cannot be banned from the chat!"
- elseif player.muted then
- cmdreply[cmdreply()] = getname(playerId) .. " is already textbanned!"
- else
- name = getname(playerId)
- player.muted = true
- addBan(name, gethash(playerId), getip(playerId) .. "/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)
- cmdreply[cmdreply()] = name .. " has been banned from the chat " .. ((time == -1 and "indefinitely") or ("for " .. timetoword(time)))
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- 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) - (time_passed_value or 0)
- local timelimit = timelimit_set_value or readdword(addresses.gametype_base + 0x78)
- local time_left = (timelimit - time_passed) / 30
- sendresponse("Current Timelimit is " .. timetoword(timelimit) .. ". Time remaining: " .. timetoword(time_left), executorPlayerId)
- else
- timelimit_set_value = time
- time_passed_value = readdword(readdword(addresses.gameinfo_header) + 0xC)
- writedword(addresses.gametype_base + 0x78, time_passed_value + 30*time) -- Can't set time_passed to 0 because it causes weird stuff to happen.
- 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", "cheatunsetgod", "cheatremovegod", "cheatremovegodmode"},
- help = [[-- Ungod
- -- Syntax: %s [Player]
- -- Ungods the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, player
- for i = 1,#players do playerId = players[i]
- local m_playerObj, playerObjId = getplayerobject(playerId)
- if m_playerObj then
- player = PlayerClass[playerId]
- if player.godmode then
- player.godmode = false
- sendresponse(getname(playerId) .. " is no longer in godmode", executorPlayerId)
- else
- sendresponse(getname(playerId) .. " is not in godmode", executorPlayerId)
- end
- else
- sendresponse(getname(playerId) .. " is dead", executorPlayerId)
- end
- end
- end
- }
- )
- Commands.Create(
- "cheatunhax",
- {
- aliases = {"unhax"},
- help = [[-- Cheat Unhax
- -- Syntax: %s [Player]
- -- Unhaxs the specified player.]]
- },
- {
- 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, 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", "cheatunhide", "cheatunhideplayer"},
- help = [[-- Unhide
- -- Syntax: %s [Player]
- -- Unhides the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, player
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- if player.hidden then
- cmdreply[cmdreply()] = getname(playerId) .. " is no longer hidden."
- player.hidden = false
- else
- cmdreply[cmdreply()] = getname(playerId) .. " was never hidden."
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "uninvis",
- {
- aliases = {"uncamo", "removeinvis", "removecamo", "cheatuncamoplayer", "cheatuninvis", "cheatremovecamo", "cheatuncamo", "cheatuncamoplayer"},
- help = [[-- Uninvis
- -- Syntax: %s [Player]
- -- Removes camouflage from the specified player.]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, player
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- if not player.invisible then
- cmdreply[cmdreply()] = getname(playerId) .. " is not invisible"
- else
- player.invisible = false
- cmdreply[cmdreply()] = getname(playerId) .. " is no longer invisible"
- end
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "unmute",
- {
- aliases = {"removemute"},
- help = [[-- Unmute
- -- Syntax: %s [Player]
- -- Unmutes the specified player.
- -- Will also unban their chat ban from the banlist]]
- },
- {
- arguments = {"Player", minArgs = 1, maxArgs = 1},
- func = function(executorPlayerId, players)
- local playerId, player, ban_entry
- for i = 1,#players do playerId = players[i]
- player = PlayerClass[playerId]
- if player.muted then
- player.muted = false
- -- remove them from the textbanlist
- ban_entry = findBanlistEntry(nil, gethash(playerId), getip(playerId), "chat")
- if ban_entry then
- sendresponse(getname(playerId) .. " has been unmuted", executorPlayerId)
- ban_entry.time = os.time()
- updateBanFiles()
- return
- end
- if player.spamcounter < 0 then
- sendresponse(getname(playerId) .. " has been forgiven for spamming.", executorPlayerId)
- player.spamcounter = 0
- else
- sendresponse(getname(playerId) .. " is not found in any ban entries somehow???", executorPlayerId)
- 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
- if getplayer(playerId) then
- admin_entry = PlayerClass[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
- end
- sendresponse(cmdreply, executorPlayerId)
- end
- }
- )
- Commands.Create(
- "votekickaction",
- {
- aliases = {"vkaction"},
- 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)
- elseif action == "kick" or action == "ban" then
- sendresponse("The current VoteKick action has been changed to '" .. action .. "'", executorPlayerId)
- defaults.votekick_action = action
- else
- sendresponse("That is not a valid action", executorPlayerId)
- end
- end
- }
- )
- Commands.Create(
- "votekicktimeout",
- {
- 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(
- "votekickrequired",
- {
- 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)
- -- Sort the commands so they're alphabetical when someone does /list or sv_commands
- table.sort(Commands,
- function(word1, word2)
- local myChar1, myChar2
- local word1Len = #word1
- local word2Len = #word2
- local longestLen = word1Len >= word2Len and word1Len or word2Len
- local chartobyte = string.byte
- for i = 1,longestLen do
- myChar1 = i <= word1Len and chartobyte(sub(word1, i, i)) or 0
- myChar2 = i <= word2Len and chartobyte(sub(word2, i, i)) or 0
- if myChar1 < myChar2 then
- return true
- elseif myChar1 ~= myChar2 then
- return false
- end
- end
- return false
- end
- )
- processid = process
- Persistent = persistent
- profilepath = getprofilepath()
- Game = game
- GetGameAddresses(game)
- if _SERVERAPP ~= "Sapp" then
- writeword(addresses.servername_patch, 0x9090)
- writeword(addresses.devmode_patch1, 0x9090)
- writeword(addresses.devmode_patch2, 0x9090)
- --writebyte(addresses.color_patch, 0xEB)
- end
- -- 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
- 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
- file = io.open(defaults.sharedhash_file .. ".txt")
- if file then
- local iter = 0
- for line in file:lines() do
- if match(line, "%g%g%g+") then
- --reset our sharedhashes table and only load stuff in the sharedhashes file.
- if iter == 0 then -- only reset the table during the first iteration
- sharedhashes = {}
- end
- iter = iter + 1
- sharedhashes[iter] = line
- end
- end
- file:close()
- if iter == 0 then
- file = io.open(defaults.sharedhash_file .. ".txt", "a")
- if file then
- for hash,index in next,sharedhashes do
- file:write(hash .. "\n")
- end
- end
- file:close()
- end
- else
- file = io.open(defaults.sharedhash_file .. ".txt", "w")
- if file then
- for hash,index in next,sharedhashes do
- file:write(hash .. "\n")
- end
- end
- file:close()
- end
- local args = defaults.remote_bansystem
- if not args or args.mode ~= 2 then
- 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")
- 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, accessEntry, thisCommand, fullaccess
- local iter = 0
- local allcommands = concat(Commands, ", ")
- 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=(.+)")
- commands = commands == "-1" and allcommands or commands
- fullaccess = commands == allcommands
- if iter % 2 == 0 and lvlMatch then
- level = lvlMatch
- elseif iter % 2 ~= 0 and commands then
- -- String full of commands this access level can execute.
- access_entry = {commands = commands, allcommands = fullaccess}
- -- 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
- thisCommandName = getvalidformat(commands[i])
- thisCommandEntry = Commands[thisCommandName]
- if not thisCommandEntry then
- thisCommandName = commands[i]
- thisCommandEntry = thisCommandName
- end
- commandIndex = #access_entry+1
- access_entry[thisCommandEntry] = commandIndex
- access_entry[commandIndex] = thisCommandName
- end
- table.sort(access_entry, alphabetize)
- access_table[level] = access_entry
- 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] = {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.New()
- locations[map][locname] = {x, y, z}
- end
- end
- file:close()
- end
- -- Load the remote banlist.
- local args = defaults.remote_bansystem
- if args then
- reloadRemoteBanlist()
- end
- local gameinfo_base = readdword(addresses.gameinfo_header)
- -- Code for script reload.
- -- 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 {}
- team_play = readbyte(addresses.gametype_base + 0x34) == 1
- gametype = readbyte(addresses.gametype_base + 0x30)
- starting_equipment = readbit(addresses.gametype_base + 0x38, 2) and "Generic" or "Custom"
- LoadTags()
- for playerId = 0,15 do
- if not getplayer(playerId) then
- goto continue
- end
- -- Increase our total player counter.
- cur_players = cur_players + 1
- -- Add player in the script's tables.
- PlayerClass:Initialize(playerId)
- -- Remove the player from the server if they are on the banlist.
- punishIfOnBanlist(playerId)
- ::continue::
- end
- end
- end
- -- override slayer's score system by setting the scorelimit to a high number and swapping the map in onplayerkill.
- if gametype == 2 then
- team_scores[0] = getteamscore(0)
- team_scores[1] = getteamscore(1)
- --writebyte(addresses.slayer_score_patch, 0xEB)
- -- how tf do i set slayer scorelimit: figured it out writebyte(addresses.gametype_base + 0x58, score)
- 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 "-------------------------------------------------------------------------------"
- file = io.open("temp_" .. processid .. ".tmp") or io.open "defaults.txt"
- local temp_commands_executed = {} --TM.New()
- local words
- -- if gameinfo_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..."
- for command,value in next,defaults do
- file:write("sv_" .. command .. " " .. tostring(value) .. "\n")
- end
- file:close()
- end
- maintimer = registertimer(33, "MainTimer")
- collectgarbage()
- end
- function turnAdminCheckOff(id, count)
- halo_svcmd "sv_admin_check false" -- stupid phasor :(
- -- Load Maplist and Gamelist.
- --[[local gmatch = string.gmatch
- for map in gmatch(concat(halo_svcmd("sv_maplist", true)), "%w+") do
- valid_maps[map] = true
- end
- for gametype in gmatch(concat(halo_svcmd("sv_gamelist", true)), "%w+") do
- valid_gametypes[gametype] = true
- end--]]
- return false
- end
- function OnScriptUnload()
- if defaults.remotecontrol then
- for i = 1,#clients do
- clients[i].socket:close()
- end
- server:close()
- server = nil
- end
- local writetbl = {}--TM.New()
- local file = assert(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()
- -- Continue to write these onscriptunload because they aren't as important as admins/bans and they're written to a lot more.
- --[[file = assert(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 = assert(io.open("temp_" .. processid .. ".tmp", "w"))
- start = #writetbl+1
- for command,value in next,defaults do
- if command == "remote_bansystem" and type(value) == "table" then
- writetbl[#writetbl+1] = command .. " " .. value.host .. " " .. value.phpscript .. " " .. value.banfile .. " " .. value.mode .. " " .. value.port
- else
- writetbl[#writetbl+1] = command .. " " .. tostring(value)
- end
- 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()
- if gametype == 2 then
- --writebyte(addresses.slayer_score_patch, 0x74)
- -- how tf do i set slayer scorelimit: figured it out writebyte(addresses.gametype_base + 0x58, score)
- end
- -- Clean up drones.
- for playerId = 0,15 do
- if getplayer(playerId) then
- cleanupdrones(playerId)
- end
- end
- end
- local NameRequestName
- function OnNameRequest(hash, name)
- -- No commas allowed in the name (it's our delimiter for the banlist and admin file.)
- local count
- name, count = gsub(name, ",", "")
- NameRequestName = tostring(name)
- if findBanlistEntry(name, nil, nil, "name") then
- hprintf(name .. " joined with a banned name, using random name.")
- return false
- end
- if count and count >= 1 then
- return false, name
- end
- end
- -- brief Called when a hash is validated by gamespy
- -- param hash: The hash that was checked
- -- param status: Result of the check (1 = valid, 2 = invalid, 3 = valid hash but invalid challenge)
- -- Status 2 indicates that somebody is trying to spoof a player's hash
- -- (i.e. pretend to be them). The player is immediately kicked after calling this function.
- function OnHashValidation(hash, status)
- hprintf("Hash: " .. tostring(hash) .. " Status: " .. tostring(status))
- --[[if status == 2 then
- WriteLog(profilepath .. "logs\\SecurityIssues.log", hash .. " attempted to spoof, status 2")
- end--]]
- end
- local isMuted
- function OnBanCheck(hash, ip)
- hprintf(NameRequestName .. " (Hash: " .. tostring(hash) .. " IP: " .. tostring(ip) .. ") is attempting to join the server")
- -- 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
- -- Check if they are on boslist.
- local bos_entry
- for i = 1,#bos_table do bos_entry = bos_table[i]
- if netMatch(bos_entry.ip, ip) then
- privateSayAdmins(bos_entry.name .. " banned from BoS.\nEntry: " .. bos_entry.name .. "- " .. bos_entry.ip)
- 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, -1, "ip", "Ban on Sight")
- return false
- end
- end
- -- Check if they are on banlist.
- local ban_entry = findBanlistEntry(nil, hash, ip)
- if ban_entry then
- hprintf(NameRequestName .. " (Hash: " .. hash .. " IP: " .. ip .. ") has been rejected because they were found on the " .. ban_entry.type .. " banlist with index '" .. ( ban_entry.name .. ":" .. (ban_entry.hash or "") .. ":" .. (ban_entry.ip or "") ) .. "'")
- if ban_entry.type == "chat" then
- isMuted = true
- else
- return false
- end
- end
- end
- function OnPlayerJoin(playerId)
- local player = PlayerClass:Initialize(playerId)
- -- 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)
- elseif readword(getplayer(playerId) + 0x60) == 10 and sub(gethash(playerId), 1, 5) ~= "56d5f" --[[forjessasblack-or readword(getplayer(playerId) + 0x60) == 1 and sub(gethash(playerId), 1, 5) ~= "c68bd"--]] or readword(getplayer(playerId) + 0x60) == 12 and sub(gethash(playerId), 1, 5) ~= "abd5c" then
- writeword(getplayer(playerId) + 0x60, 13)
- end
- cur_players = cur_players + 1
- local name = getname(playerId)
- local hash = gethash(playerId)
- local ip = getip(playerId)
- local iprange = match(ip, "^%d+%.%d+%.%d+")
- player.muted = player.muted or not not isMuted
- isMuted = nil
- if player.suspended then
- kill(playerId)
- writeshort(getplayer(playerId) + 0x2C, tonumber(player.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] = {joincount = 1, names = {name}}
- unique_table[ip] = {joincount = 1, names = {name}}
- unique_table[iprange] = {joincount = 1, names = {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 PlayerClass[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 player = PlayerClass[playerId]
- local ip = player.ip
- player.playerId = -1
- if not gameend and player.tempadmin then
- player.tempadmin = false
- end
- if votekickPlayerId == playerId then
- votekicktimer = nil
- votekickPlayerId = nil
- votekick_counter = -defaults.votekick_timeout
- for playerId = 0,15 do
- if getplayer(playerId) then
- PlayerClass[playerId].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")
- PlayerClass[playerId].player_struct = false
- end
- function OnTeamChange(playerId, old_team, new_team, relevant)
- if team_play then
- --say(tostring(getname(playerId)) .. " swapping from " .. tostring(old_team) .. " to " .. tostring(new_team))
- --[[writeword(getplayer(playerId) + 0x60, new_team+2)
- PlayerClass[playerId].changing_teams = true--]]
- end
- end
- function destroyPlayer(id, count, playerId)
- local player = PlayerClass[playerId]
- local playerObjId = getplayerobjectid(playerId)
- if getobject(playerObjId) then
- --say("Destroying " .. tostring(getname(playerId)))
- destroyobject(playerObjId)
- --say("Done! Player " .. tostring(getname(playerId)) .. " is now " .. readword(getplayer(playerId) + 0x60))
- end
- player.changing_teams = false
- return false
- end
- function OnPlayerSpawn(playerId, playerObjId)
- local player = PlayerClass[playerId]
- if player.changing_teams then
- --say(getname(playerId) .. " is changing teams")
- registertimer(100, "destroyPlayer", playerId)
- return
- end
- if defaults.noweapons or player.disarmed then
- local m_weapon, weaponObjId
- for slot = 0,3 do
- m_weapon, weaponObjId = getplayerweapon(playerId, slot)
- if m_weapon then
- destroyobject(weaponObjId)
- end
- end
- end
- if defaults.multiteam_vehicles then
- writebyte(player.player_struct + 0x20, 0)
- end
- if player.colorspawn then
- movobjectcoords(playerObjId, player.x, player.y, player.z)
- player.colorspawn = false
- end
- player.suspended = false
- player.ghostmode = false
- --writebit(m_playerObj + 0x10, 0, 1) -- both for ghostmode
- --writebit(m_playerObj + 0x10, 24, 0)
- -- default spawn weapons code:
- if next(spawnWeapons) then
- if starting_equipment == "Generic" then
- -- check if we still need to assign leftover weapons to players (tertiary and quartenary weapons)
- if spawnWeapons[3] then
- -- assign the leftover weapons to the player
- registertimer(0, "AssignLeftoverWeapons", playerId)
- end
- elseif starting_equipment == "Custom" then
- -- assign the correct weapons to the player
- registertimer(0, "AssignWeapons", playerId)
- end
- end
- end
- local mode = 1 -- screw you phasor
- function OnNewGame(map)
- if Persistent then
- rtv_counter = 0
- for _,entry in next,PlayerClass do
- if type(entry) ~= "function" then
- entry.rtv_rocked = false
- end
- end
- end
- Map = map
- locations[map] = locations[map] or {}
- gameend = false
- gametype = readbyte(addresses.gametype_base + 0x30)
- team_play = readbyte(addresses.gametype_base + 0x34) == 1
- scorelimit = getscorelimit()
- starting_equipment = readbit(addresses.gametype_base + 0x38, 2) and "Generic" or "Custom"
- -- Turn MTV Off
- if team_play then
- defaults.multiteam_vehicles = false
- end
- LoadTags()
- mode = 1
- if gametype == 2 then
- --writebyte(addresses.slayer_score_patch, 0xEB)
- -- how tf do i set slayer scorelimit: figured it out writebyte(addresses.gametype_base + 0x58, score)
- end
- local args = defaults.remote_bansystem
- if args then
- reloadRemoteBanlist()
- end
- collectgarbage()
- end
- function OnGameEnd(mode_that_sometimes_lies)
- if mode == 1 then
- gameend = true
- collectgarbage()
- if gametype == 2 then
- team_scores[0] = 0
- team_scores[1] = 0
- for i = 0,15 do
- player_scores[i] = 0
- end
- --writebyte(addresses.slayer_score_patch, 0x74)
- -- how tf do i set slayer scorelimit: figured it out writebyte(addresses.gametype_base + 0x58, score)
- end
- team_play_temp = nil
- 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 .. " votes")
- else
- svcmd("sv_kick " .. resolveplayer(votekickPlayerId) .. " Votekicked with " .. votekick_counter .. " 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.
- local msg = gsub(message, "**SERVER**", "\n**SERVER TO " .. getname(playerId) .. "**")
- hprintf(msg)
- 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 player = PlayerClass[playerId]
- if player.muted or player.spamcounter < 0 then
- return false
- end
- local t = tokenizecmdstring(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 player.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")
- end
- say(rtv_counter .. " of " .. total_votes_required .. " votes required for rtv")
- player.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 player.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 PlayerClass[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
- player.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 player.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))
- player.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 = _SERVERAPP == "Phasor" or not not say(name .. ": " .. message, false) -- sapp will execute the command a second time if this isn't here. I still like this environment showing up in the chat.
- elseif sub(cmd, 1, 1) == "\\" then
- output_environment = 3
- found = true
- AllowChat = false
- end
- if found then
- if defaults.chatcommands then
- if cmd == "/" or cmd == "\\" then
- sendresponse("Invalid Command", playerId)
- elseif cmd == "/e" or 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
- player.spamcounter = player.spamcounter + 1
- end
- -- Print a message to the console of the chat.
- hprintf("\nOnServerChat(" .. playerId .. ", " .. tostring(chattype) .. ") " .. getname(playerId) .. ": (" .. resolveplayer(playerId) .. ") " .. message)
- if AllowChat ~= false then
- if defaults.anticaps then
- if defaults.chatids then
- return true, " (" .. resolveplayer(playerId) .. ") " .. lower(message)
- end
- return true, lower(message)
- elseif defaults.chatids then
- return true, " (" .. resolveplayer(playerId) .. ") " .. message
- end
- end
- return AllowChat
- end
- function rtvTimer(id, count)
- if rtv_counter > 0 then
- rtv_counter = -defaults.rtv_timeout
- for playerId = 0,15 do
- if getplayer(playerId) then
- PlayerClass[playerId].rtv_rocked = false
- end
- end
- say "The current rtv has expired"
- end
- return false
- end
- function rconBruteForceTimeout(id, count, player)
- if player.rcon_fails == 0 then
- player.rconfail_timer = -1
- return false
- end
- player.rcon_fails = player.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)
- 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 not Commands[cmd].scrim 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, register our brute force timer
- local player = PlayerClass[playerId]
- if player.rcon_fails >= 10 then
- if player.rconfail_timer ~= -1 then
- player.rcon_fails = player.rcon_fails + 1
- else
- player.rconfail_timer = registertimer(1000, "rconBruteForceTimeout", player)
- 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(cmd, level)
- else
- access = getaccess(playerId)
- local generic_rcon = readstring(addresses.network_server_globals + 0x128)
- -- If there are no admins on the server, and the rcon was correct, allow the command
- if not next(admin_table) and generic_rcon == password then
- permission = true
- -- If the player has admin access, then allow the command IF a password was not provided (chat command), sv_rcon_password is set to 'any' (allow all rcon passwords), or check if the rcon matches the rcon password.
- elseif access and (not password or generic_rcon == "any" or generic_rcon == password) then
- permission = checkaccess(cmd, access)
- end
- end
- if permission == false then
- local admin_entry = PlayerClass[playerId].admin_entry
- local admin_name = admin_entry and admin_entry.name or "N/A"
- if level then
- cmdlog(" >>Security Alert: " .. getname(playerId) .. " (Nickname: " .. admin_name .. " 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 and output_environment <= 1 then
- if not access then
- cmdlog(getname(playerId) .. " (Nickname: " .. admin_name .. " 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)
- goto ReturnPermission
- elseif password ~= generic_rcon then
- cmdlog(getname(playerId) .. " (Nickname: " .. admin_name .. " Hash:" .. gethash(playerId) .. " IP: " .. getip(playerId) .. ") tried to use '" .. password .. "' as an rcon password")
- sendresponse("That is not an rcon password", playerId)
- else
- cmdlog(getname(playerId) .. " (Nickname: " .. admin_name .. " Hash:" .. gethash(playerId) .. " IP: " .. getip(playerId) .. ") tried to execute: '" .. command .. "'")
- sendresponse("You cannot execute this command.", playerId)
- end
- else
- cmdlog(getname(playerId) .. " (Nickname: " .. admin_name .. " Hash:" .. gethash(playerId) .. " IP: " .. getip(playerId) .. ") tried to execute: '" .. command .. "'")
- sendresponse("You cannot execute this command.", playerId)
- goto ReturnPermission
- end
- player.rcon_fails = player.rcon_fails + 1
- else
- command_attempt = true
- player.rcon_fails = 0
- end
- ::ReturnPermission::
- return permission
- end
- function OnServerCommand(playerId, command)
- -- prevents rare issues that happen when init files execute blank commands
- if not match(command, "%w+") then return nil end
- -- 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
- command_attempt = nil
- 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
- t[2] = concat(t, "", 2)
- thisCommand = Commands[getvalidformat(t[2])]
- if thisCommand and thisCommand.info.help then
- sendresponse(gsub(thisCommand.info.help, "%%s", t[2]), 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 tempCmd = cmd
- local i = 2
- while i <= count do
- tempCmd = tempCmd .. gsub(t[i], "_", "")
- thisCommand = Commands[tempCmd]
- if thisCommand then
- t[1] = tempCmd
- for j = 2,i do
- remove(t, 2)
- end
- break
- end
- i = i + 1
- end
- thisCommand = Commands[getvalidformat(t[1])]
- -- 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
- if not match(newcmd, "script_reload") and not match(newcmd, "script_unload " .. sub(debug.getinfo(1, "S").source, 2, -5)) then
- if sub(newcmd, 1, 1) == "/" or sub(newcmd, 1, 1) == "\\" then
- -- print("1st CHECK")
- newcmd = sub(newcmd, 2)
- message = halo_svcmd(newcmd, true)
- end
- -- Second Possibility: the command might need an sv_, or might need the sv_ removed.
- if type(message) ~= "table" or type(message[1]) ~= "string" or find(concat(message), "Requested function \"") then
- --print("2nd check")
- -- Add the sv_
- if sub(newcmd, 1, 3) ~= "sv_" then
- --print("3rd CHECK")
- message = halo_svcmd("sv_" .. newcmd, true)
- -- Remove the sv_
- else
- message = halo_svcmd(sub(newcmd, 4), true)
- end
- end
- if type(message) ~= "table" or type(message[1]) ~= "string" or find(concat(message), "Requested function \"") then
- --sendresponse('Command "' .. t[1] .. '" not found.', playerId)
- -- Send back the message from the non-scripted command.
- else
- sendresponse(message, playerId)
- end
- end
- end
- end
- if playerId and response == false then
- cmdlog(format("%s (Nickname: %s Hash: %s IP: %s) has executed: %s", getname(playerId), (PlayerClass[playerId].admin_entry and PlayerClass[playerId].admin_entry.name or "N/A"), gethash(playerId), getip(playerId), command))
- end
- return response
- end
- local function sendKillingSpreeMessages(killerPlayerId, victimPlayerId)
- 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 >= 40 and spree%2 == 0 then
- Say("OMFGWTFBBQWAFFLES " .. kname .. " is Unfrigginbelievable with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "OMFGWTFBBQWAFFLES Unfrigginbelievable")
- elseif spree >= 35 and spree < 40 then
- Say(kname .. " is Inconceivable with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "Inconceivable")
- elseif spree >= 30 then
- Say(kname .. " is Invincible with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "Invincible")
- elseif spree >= 25 then
- Say(kname .. " is Untouchable with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "Untouchable")
- elseif spree >= 20 then
- Say(kname .. " is on a Rampage with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "Rampage")
- elseif spree >= 15 then
- Say(kname .. " is on a Running Riot with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "Running Riot")
- elseif spree >= 10 then
- Say(kname .. " is on a Killing Frenzy with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "Killing Frenzy")
- elseif spree >= 5 then
- Say(kname .. " is on a Killing Spree with " .. spree .. " kills!", 1, playerId)
- sendconsoletext(killerPlayerId, "Killing Spree")
- end
- local m_vplayer = getplayer(victimPlayerId)
- local victim_spree = readword(m_vplayer + 0x96)
- if victim_spree >= 5 then
- Say(kname .. " just ended " .. getname(victimPlayerId) .. "'s killing spree of " .. victim_spree .. "!")
- end
- end
- function OnPlayerKill(killerPlayerId, victimPlayerId, mode)
- if mode == 6 then
- hprintf(getname(victimPlayerId) .. " has committed suicide!")
- elseif mode == 0 or mode >= 4 then
- hprintf(getname(victimPlayerId) .. " was killed by " .. getname(killerPlayerId))
- elseif mode == 1 then
- hprintf(getname(victimPlayerId) .. " fell off a high place")
- elseif mode == 2 then
- hprintf(getname(victimPlayerId) .. " was killed by the Guardians")
- elseif mode == 3 then
- hprintf(getname(victimPlayerId) .. " was rolled over by a vehicle")
- end
- cleanupdrones(victimPlayerId)
- local victim = PlayerClass[victimPlayerId]
- local killer = PlayerClass[killerPlayerId]
- victim.godmode = false
- if defaults.respawn_time then
- writedword(getplayer(victimPlayerId) + 0x2C, defaults.respawn_time * 30)
- end
- if mode == 4 then
- -- Score monitoring.
- if gametype == 2 then
- local score = player_scores[killerPlayerId]
- player_scores[killerPlayerId] = score + 1
- if team_play then
- team_scores[getteam(killerPlayerId)] = team_scores[getteam(killerPlayerId)] + 1
- score = team_scores[getteam(killerPlayerId)]
- end
- --say("Score: " .. tostring(score) .. "Team Score: " .. tostring(team_scores[getteam(killerPlayerId)]) .. " Scorelimit: " .. tostring(scorelimit))
- if score >= scorelimit then -- check if the scorelimit has been reached.
- halo_svcmd("sv_map_next")
- end
- end
- if defaults.killing_spree then
- sendKillingSpreeMessages(killerPlayerId, victimPlayerId)
- end
- end
- if defaults.tbag_detection then
- killer.tbagname = getname(victimPlayerId)
- killer.tbagcount = 0
- victim.tbagcount = 0
- victim.x,
- victim.y,
- victim.z = getobjectcoords(getplayerobjectid(victimPlayerId))
- end
- 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 = PlayerClass[playerId].weapons
- local m_weaponObj, weaponObjId
- for slot = 0,3 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 player = PlayerClass[playerId]
- if player.tbagname == "" then
- return
- end
- local playerObjId = getplayerobjectid(playerId)
- local m_playerObj = getobject(playerObjId)
- if not m_playerObj then
- return
- end
- local crouching = readbyte(m_playerObj + 0x2A0) == 3
- if not player.crouch and crouching then
- player.tbagcount = (player.tbagcount or 0) + 1
- if player.tbagcount == 4 then
- player.tbagcount = 0
- say(getname(playerId) .. " is T-Bagging " .. player.tbagname)
- player.tbagname = ""
- end
- player.crouch = true
- elseif player.crouch and not crouching then
- player.crouch = false
- end
- end
- function OnObjectInteraction(playerId, objectId, mapId)
- if defaults.noweapons or PlayerClass[playerId].disarmed then
- if getObjType(objectId) == 2 then
- return false
- end
- end
- return nil -- gotta return a value
- end
- local object_types = {
- [0] = "Biped",
- "Vehicle",
- "Weapon",
- "Equipment",
- "Garbage",
- "Projectile",
- "Scenery",
- "Machine",
- "Control",
- "Light Fixture",
- "Placeholder",
- "Sound Scenery"
- }
- function OnDamageApplication(receiverObjId, causerObjId, tagId, hit, backtap)
- if not getobject(causerObjId) then
- return
- end
- local playerId = objectidtoplayer(causerObjId)
- if not playerId then
- return
- end
- local player = PlayerClass[playerId]
- if player.bulletmode == "destroy" then
- destroyobject(receiverObjId)
- elseif player.bulletmode == "entergun" then
- local m_receiverObj = getobject(receiverObjId)
- if not m_receiverObj then
- return
- end
- local objtype = readword(m_receiverObj + 0xB4)
- if objtype == 1 then -- check if object is a vehicle
- entervehicle(playerId, receiverObjId, 0)
- end
- elseif player.bulletmode == "debuggun" then
- local m_receiverObj = getobject(receiverObjId)
- if not m_receiverObj then
- return
- 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.01)
- elseif defaults.deathless or (receivingPlayerId and PlayerClass[receivingPlayerId].godmode) then
- odl_multiplier(0.00000000000000000000000000000000000000001)
- 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", {tagdata, 0x1C4, dmg_side_effect}) -- new phasor doesn't automatically reset tagdata anymore.
- end
- elseif getobject(causerObjId) and receivingPlayerId then
- --say("2APPLYING DAMAGE TO: " .. tostring(getname(receivingPlayerId)))
- -- make sure firefister doesn't take fire damage
- local dmg_damage_category = readword(tagdata + 0x1C6)
- if dmg_damage_category == 7 then
- --say("2FLAME DAMAGE BEING APPLIED TO: " .. tostring(getname(receivingPlayerId)))
- if PlayerClass[receivingPlayerId].firefist then
- --say("2SETTING 0 DAMAGE")
- odl_multiplier(0)
- end
- end
- local causingPlayerId = objectidtoplayer(causerObjId)
- local m_causingPlayer, m_receivingPlayer = getplayer(causingPlayerId), getplayer(receivingPlayerId)
- if not m_receivingPlayer or not m_causingPlayer or causingPlayerId == receivingPlayerId then
- return
- end
- local player = PlayerClass[causingPlayerId]
- if player.dmgmultiplier ~= 1 then
- odl_multiplier(player.dmgmultiplier)
- end
- if defaults.multiteam_vehicles then
- writebyte(m_receivingPlayer + 0x20, getteam(receivingPlayerId)+1)
- registertimer(0, "multiteamtimer", receivingPlayerId)
- end
- if PlayerClass[receivingPlayerId].firefist then -- check for melee damage
- ApplyFlame(receivingPlayerId, causerObjId)
- PlayerClass[receivingPlayerId].firecauser = causerPlayerId
- end
- elseif receivingPlayerId then
- --say("1APPLYING DAMAGE TO: " .. tostring(getname(receivingPlayerId)))
- -- make sure firefister doesn't take fire damage
- local dmg_damage_category = readword(tagdata + 0x1C6)
- if dmg_damage_category == 7 then
- --say("1FLAME DAMAGE BEING APPLIED TO: " .. tostring(getname(receivingPlayerId)))
- if PlayerClass[receivingPlayerId].firefist then
- --say("1SETTING 0 DAMAGE")
- odl_multiplier(0)
- end
- end
- end
- 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 portalgunTimer(id, count, userdata)
- local playerObjId = userdata[1]
- local m_bulletObj = userdata[2]
- if count < 100 then
- if getobject(playerObjId) then
- if readfloat(m_bulletObj + 0x68) == 0 then
- local x = readfloat(m_bulletObj, 0x5C)
- local y = readfloat(m_bulletObj, 0x60)
- local z = readfloat(m_bulletObj, 0x64)
- movobjectcoords(playerObjId, x, y, z)
- else
- return true
- end
- end
- end
- return false
- end
- function spawngunTimer(id, count, userdata)
- local playerId = userdata[1]
- local m_bulletObj = userdata[2]
- if getplayerobject(playerId) then
- local x = readfloat(m_bulletObj, 0x5C)
- local y = readfloat(m_bulletObj, 0x60)
- local z = readfloat(m_bulletObj, 0x64)
- local objspawnid = PlayerClass[playerId].objspawnid
- if objspawnid then
- createobject(objspawnid, 0, 60, false, x, y, z+0.6)
- end
- end
- return false
- 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)
- return -- we can safely return here
- end
- end
- end
- local mapId = TempObjectTable[1]
- local playerId = 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 player = PlayerClass[playerId]
- if player.bulletmode == "portalgun" then
- registertimer(100, "portalgunTimer", {getplayerobjectid(playerId), getobject(objectId)})
- elseif player.bulletmode == "spawngun" then
- registertimer(100, "spawngunTimer", {playerId, getobject(objectId)})
- end
- end
- end
- end
- function OnWeaponAssignment(playerId, objId, slot, weapTagId)
- if not next(spawnWeapons) then return nil end
- if playerId then
- local m_player = getplayer(playerId)
- if m_player then
- if slot == 0 and spawnWeapons[1] then
- return spawnWeapons[1]
- elseif slot == 1 and spawnWeapons[2] then
- return spawnWeapons[2]
- end
- end
- end
- return nil
- end
- -- basically this timer assigns the tertiary and quarternary weapons to players for the default_spawn_weapons command.
- -- this is needed since onweaponassignment isn't called for tertiary and quartenary weapons
- -- This timer is used for Generic gametypes
- function AssignLeftoverWeapons(id, count, playerId)
- local m_object = getplayerobject(playerId)
- if m_object then
- if spawnWeapons[3] then
- local m_weaponId = createobject(spawnWeapons[3], 0, 60, false, 5, 2, 2)
- if m_weaponId and m_weaponId ~= 0xFFFFFFFF then
- local m_weapon = getobject(m_weaponId)
- if m_weapon then
- -- set the ammo
- writeword(m_weapon + 0x2B6, ammocount)
- writeword(m_weapon + 0x2B8, clipcount)
- writefloat(m_weapon + 0x240, math.abs(batterycount - 1))
- -- force it to sync
- updateammo(m_weaponId)
- end
- end
- if spawnWeapons[4] then
- -- create the quarternary weapon
- local m_weaponId = createobject(spawnWeapons[4], 0, 60, false, 1, 1, 1)
- -- make sure createobject didn't screw up
- if m_weaponId ~= 0xFFFFFFFF then
- -- assign the weapon to the player
- assignweapon(playerId, m_weaponId)
- -- make sure we can safely set the ammo
- local m_weapon = getobject(m_weaponId)
- if m_weapon then
- -- set the ammo
- writeword(m_weapon + 0x2B6, ammocount)
- writeword(m_weapon + 0x2B8, clipcount)
- writefloat(m_weapon + 0x240, math.abs(batterycount - 1))
- -- force it to sync
- updateammo(m_weaponId)
- end
- end
- end
- end
- end
- return false
- end
- -- This timer is used for Custom gametypes
- function AssignWeapons(id, count, userdata)
- local playerId = userdata[1]
- local clipcount = userdata[2]
- local ammocount = userdata[3]
- local batterycount = userdata[4]
- if not playerId or not getplayer(playerId) then
- return false
- end
- local m_object = getplayerobject(playerId)
- if m_object then
- -- count is increased everytime the timer is called
- if count == 1 then
- -- gets rid of any weapons a zombie is holding
- destroyweapons(playerId)
- end
- local i = count
- if spawnWeapons[i] then
- local m_weaponId = createobject(spawnWeapons[i], 0, 60, false, 1, 1, 1) or 0xFFFFFFFF
- local m_weapon = getobject(m_weaponId)
- if m_weapon then
- -- Assign the weapon to the player.
- assignweapon(playerId, m_weaponId)
- -- set the ammo
- writeword(m_weapon + 0x2B6, ammocount)
- writeword(m_weapon + 0x2B8, clipcount)
- writefloat(m_weapon + 0x240, 1)
- -- force it to sync
- updateammo(m_weaponId)
- end
- end
- if count < 4 then return true else return false end
- end
- return false
- end
- function MainTimer(id, count)
- -- For hiding.
- local m_player
- for playerId = 0,15 do
- if getplayer(playerId) and PlayerClass[playerId] and PlayerClass[playerId].hidden then
- m_player = getplayer(playerId)
- 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 player
- -- For invisible timer, suspended timer, and message spamming.
- for playerId = 0,15 do
- if getplayer(playerId) then
- player = PlayerClass[playerId]
- if player.invisible == -1 then
- applycamo(playerId, 1.2)
- elseif player.invisible then
- applycamo(playerId, 1.2)
- player.invisible = player.invisible - 1
- if player.invisible <= 0 then
- player.invisible = false
- end
- end
- if type(player.suspended) == "number" then
- player.suspended = player.suspended - 1
- if player.suspended == 0 then
- player.suspended = false
- say(player.name .. " is no longer suspended")
- end
- end
- -- Player is currently muted for spamming, add 1 second from their timeout counter until they are at 0 (or above).
- if player.spamcounter < 0 then
- player.spamcounter = player.spamcounter + 1
- if player.spamcounter > 0 then
- say(getname(playerId) .. " has been unmuted")
- player.spamcounter = 0
- end
- -- Player has spammed too many messages, mute them for spamming
- elseif player.spamcounter > defaults.spam_max then
- say(getname(playerId) .. " has been muted for " .. timetoword(defaults.spam_timeout) .. " seconds for spamming")
- player.spamcounter = -defaults.spam_timeout
- -- Player has sent a message within the last second, will take 4 seconds to remove from spam counter.
- elseif player.spamcounter > 0 then
- player.spamcounter = player.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
- -- This script is now compatible with BOTH Sapp and Phasor!
- if loadstring then -- don't need the module if this script is loaded via phasor.
- _G = require"PhasorSappCompatibility"
- else
- _SERVERAPP = "Phasor"
- end
Recent Pastes