rockbandcheeseman

ATInfection3

Apr 27th, 2013
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 213.60 KB | None | 0 0
  1. -- AT] Infection 3.0
  2.  
  3. -- Table.Load and Table.Save --
  4.  
  5. function table.save(t, filename)
  6.  
  7.     local dir = getprofilepath()
  8.     local file = io.open(dir .. "\\data\\" .. filename, "w+")
  9.     local spaces = 1
  10.  
  11.     local function format(t)
  12.  
  13.         local function whitespace(num)
  14.             local str = ""
  15.             for i = 1, num do
  16.                 str = str .. "\t"
  17.             end
  18.  
  19.             return str
  20.         end
  21.  
  22.         local str = ""
  23.  
  24.         for k,v in pairs(t) do
  25.             if type(v) == "string" then
  26.                 v = string.format("%q", v)
  27.             end
  28.             if type(k) == "string" then
  29.                 k = string.format("%q", k)
  30.             end
  31.             k = tostring(k)
  32.             if v == math.inf then
  33.                 v = "1 / 0"
  34.             end
  35.             if type(v) == "table" then
  36.                 if table.len(v) > 0 then
  37.                     spaces = spaces + 1
  38.                     str = str .. "\n" .. whitespace(spaces - 1) .. "[" .. k .. "] = {" .. format(v) .."\n" .. whitespace(spaces - 1) .. "},"
  39.                     spaces = spaces - 1
  40.                 else
  41.                     str = str .. "\n" .. whitespace(spaces) .. "[" .. k .. "] = {},"
  42.                 end
  43.             else
  44.                 str = str .."\n" .. whitespace(spaces) .. "[" .. k .. "] = " .. tostring(v) .. ","
  45.             end
  46.         end
  47.  
  48.         return string.sub(str, 1, string.len(str) - 1)
  49.     end
  50.    
  51.     file:write("return {" .. format(t) .. "\n}")
  52.     file:close()
  53. end
  54.  
  55. function table.load(filename)
  56.  
  57.     local dir = getprofilepath()
  58.     local exists = loadfile(dir .. "\\data\\" .. filename)
  59.     local t
  60.     if exists then
  61.         t = exists()
  62.     end
  63.     return t or {}
  64. end
  65.  
  66. -- Mute
  67.  
  68. -- You may update this table in this script or via console commands.
  69.  
  70. --[[ Mute Table ]]--
  71.    
  72.     -- To mute specific hashes by default (they will be permanent mutes), simply enter them into the mute_table, surrounded by quotes and separated by commas.  Once the script it loaded and unloaded, you can delete them if you want; they will be saved.
  73.  
  74.     local mute_default = {} -- "eb12931aef01915b20d014c10", "a45c6a5e116fd31b65ade46b3"    (these are made-up, invalid hashes)
  75.    
  76.     mute_table = table.load("mutelist")
  77.  
  78. -- Chat Filter
  79.  
  80. -- You may update this table in this script or via console commands.
  81.  
  82. --[[ Swear Tables and Variables ]]--
  83.  
  84.     sweartable = table.load("sweartable") or {}
  85.    
  86.     local swear_default = {}
  87.  
  88.     -- To specify swear words that players must say exactly to be counted as a swear, enter the word (in lowercase) in the swear_default.exact table, surrounded by quotes and separated by commas.  To specify swear words that should be blocked in any context, enter into swear_default.anywhere.  Note that swear_default.exact may not have a space, while swear_default.anywhere can.
  89.    
  90.     swear_default.exact = {}  -- "ass", "fu", "shit"
  91.     swear_default.anywhere = {} -- "fuck", "damn", "donkey boner"
  92.    
  93.     -- Nil check
  94.     sweartable.exact = sweartable.exact or {}
  95.     sweartable.anywhere = sweartable.anywhere or {}
  96.    
  97.     -- Swear Variables:
  98.     if sweartable.automute == nil then
  99.         automute = true
  100.     else
  101.         automute = sweartable.automute
  102.     end
  103.    
  104.     -- The amount of times a player needs to swear before they are automuted.
  105.     swears_to_mute = sweartable.tomute or 3
  106.    
  107.     -- Either "none" (0), "block" (1) or "append" (2).  If "block", when a player swears, their entire message will be blocked.  If "append", players' messages will be changed to their specified replacement words.
  108.     swear_action = sweartable.action or 2
  109.    
  110.     -- If a swear word has no specific replacement word, this is what it will be replaced by.
  111.     swear_append = sweartable.append or "**censored**"
  112.    
  113.     -- If a player swears, this is the message they will receive.  If you don't want players to receive swear messages, use "".
  114.     swear_message = sweartable.message or "Please do not swear in this server."
  115.    
  116.     -- Amount of time a player will be automuted for (-1 = rest of game) (-2 = permanent) (all other values taken in seconds)
  117.     swear_penalty = sweartable.penalty or -1
  118.    
  119.     -- If a player has been muted this many times, the next time they are muted, the admin who muted them is notified to consider a permanent mute.  Use 0 to disable.
  120.     notify_of_mutes = sweartable.mutenotify or 5
  121.    
  122. --[[ Editable values ]]--
  123.  
  124.     -- Teams --
  125.     zombie_team = 1  -- 0 is red, 1 is blue
  126.     human_team = 1 - zombie_team
  127.    
  128.     -- General Infection Values --
  129.     starting_zombies = 1  -- If values is < 1, this is taken as a percentage of current players.  Otherwise, it is taken as an actual value.
  130.  
  131.     -- General Booleans --
  132.     lastman_zombie = true  -- If true, the last man from the previous game will be a zombie this game.  If false, zombies for this game will be chosen at random.
  133.     infected_by_zombie = true  -- Allows/unallows for a player to be infected by being killed by a zombie
  134.     infected_by_fall = true  -- Allows/unallows for a player to be infected by falling to their death
  135.     infected_by_server = true  -- Allows/unallows for a player to be infected when killed by the server
  136.     infected_by_suicide = true  -- Allows/unallows for a player to be infected by committing suicide
  137.     infected_by_vehicle = false  -- Allows/unallows for a player to be infected by being killed by a vehicle
  138.     infected_by_betrayal = false  -- Allows/unallows for a player to be infected if they betray a teammate
  139.     infected_by_guardians = false  -- Allows/unallows for a player to be infected by the guardians
  140.     zombies_invisible = false  -- Allows/unallows zombies to always be invisible
  141.    
  142.     -- Anti-Block Features --
  143.     anti_block = true  -- Allows/unallows the use of Anti-Block, which will warn then penalize a player who is blocking (using the specifications below)
  144.     -- All following values are only relevant if anti_block is true
  145.         block_time_warning = 5  -- Amount of time in seconds before a player is sent a warning that they are blocking
  146.         block_time_action = 10  -- Amount of time in seconds a player is blocking before an action is taken
  147.         block_time_warning_message = "You appear to be blocking. You have " .. block_time_action - block_time_warning .. " seconds to move from your position."  -- Message sent to players who appear to be blocking (use nil if you don't want a message to be sent)
  148.         block_time_action_message = "You have been killed for blocking."  -- Message sent to a player who has been blocking for the amount of time specified in block_time_action (use nil if you don't want a message to be sent)
  149.         block_action = "sv_kill <player>"  -- Command executed on player when they've been blocking for the amount of time specified in block_time_action (use <player> to represent where the player's number should go in the command)
  150.         multiple_offense_action_amount = 3  -- Amount of times the block_action must be performed in this game in order for the multiple_offense_action to be taken (use nil to disable)
  151.         multiple_offense_action_message = nil  -- Message sent to a player who has been penalized for blocking the amount of times specified in multiple_offense_action_amount (use nil if you don't want a message to be sent)
  152.         multiple_offense_action = "sv_kick <player>"  -- Command executed on player when they've been penalized for blocking the amount of times specified in multiple_offense_action_amount (use <player> to represent where the player's number should go in the command)
  153.    
  154.     -- Messages --
  155.     welcome_message = "Infection"  -- Message players are welcomed with
  156.     infected_message = " was infected!"  -- Message printed to the server when a player is infected
  157.     human_message = "You are a human. Survive!"  -- Message sent to humans when they become human
  158.     zombie_message = "You are a zombie. Kill the humans!"  -- Message sent to zombies when they become zombies
  159.     no_zombies_left_message = "There are no zombies left."  -- Message sent to server if there are no zombies left
  160.     no_zombies_timer_message = "A random player will be forced to become a zombie"  -- Message sent to server to notify the server will choose a random player to become a zombie
  161.     no_zombies_team_change_message = "Thank you; the game can continue."  -- Message sent to the server if a player changes team voluntarily when there are no zombies left
  162.     lastman_message = " is the last man alive!"  -- Message sent to the server when there is only one human left
  163.     vehicle_block_message = "You cannot enter vehicles."  -- Message sent to players who try to enter a vehicle but are blocked from doing so
  164.  
  165.  
  166.     -- Weapon Attributes --
  167.         -- Weapon Tag List
  168.             --[[
  169.             "weapons\\assault rifle\\assault rifle"
  170.             "weapons\\pistol\\pistol"
  171.             "weapons\\plasma pistol\\plasma pistol"
  172.             "weapons\\plasma rifle\\plasma rifle"
  173.             "weapons\\needler\\mp_needler"
  174.             "weapons\\shotgun\\shotgun"
  175.             "weapons\\sniper rifle\\sniper rifle"
  176.             "weapons\\rocket launcher\\rocket launcher"
  177.             "weapons\\plasma_cannon\\plasma_cannon"
  178.             "weapons\\flamethrower\\flamethrower"
  179.             "weapons\\flag\\flag"
  180.             "weapons\\ball\\ball"
  181.             ]]--
  182.  
  183.         -- If you use an oddball as a team's primary and only weapon, they will be unable to drop it.
  184.         -- Human Weapons (use "" for default and nil for no weapon)
  185.         human_weapons = {}
  186.         human_weapons[1] = ""  -- Primary weapon
  187.         human_weapons[2] = ""  -- Secondary weapon
  188.         --human_weapons[3] = nil  -- Tertiary weapon
  189.         --human_weapons[4] = nil  -- Quartenary weapon
  190.  
  191.         -- Zombie Weapons (use "" for default and nil for no weapon)
  192.         zombie_weapons = {}
  193.         zombie_weapons[1] = "weapons\\shotgun\\shotgun"  -- Primary weapon
  194.         zombie_weapons[2] = nil  -- Secondary weapon
  195.         --zombie_weapons[3] = nil  -- Tertiary weapon
  196.         --zombie_weapons[4] = nil  -- Quartenary weapon
  197.  
  198.         -- Human Ammo OnPlayerSpawn (use nil for default; for plasma weapons, specify the battery percentage in the ammo category)
  199.         human_ammo = {}
  200.         human_clip = {}
  201.         human_ammo[1] = nil  -- Ammo for primary weapon
  202.         human_clip[1] = nil  -- Clip for primary weapon
  203.         human_ammo[2] = nil  -- Ammo for secondary weapon
  204.         human_clip[2] = nil  -- Clip for secondary weapon
  205.         --human_ammo[3] = nil  -- Ammo for tertiary weapon
  206.         --human_clip[3] = nil  -- Clip for teriary weapon
  207.         --human_ammo[4] = nil  -- Ammo for quartenary weapon
  208.         --human_clip[4] = nil  -- Clip for quartenary weapon
  209.  
  210.         -- Zombie Ammo OnPlayerSpawn (use nil for default; for plasma weapons, specify the battery percentage in the ammo category)
  211.         zombie_ammo = {}
  212.         zombie_clip = {}
  213.         zombie_ammo[1] = 0  -- Ammo for primary weapon
  214.         zombie_clip[1] = 0  -- Clip for primary weapon
  215.         zombie_ammo[2] = 0  -- Ammo for secondary weapon
  216.         zombie_clip[2] = 0  -- Clip for secondary weapon
  217.         --zombie_ammo[3] = 0  -- Ammo for tertiary weapon
  218.         --zombie_clip[3] = 0  -- Clip for teriary weapon
  219.         --zombie_ammo[4] = 0  -- Ammo for quartenary weapon
  220.         --zombie_clip[4] = 0  -- Clip for quartenary weapon
  221.  
  222.         -- Human Grenades (use nil for default)
  223.         human_frags = nil
  224.         human_plasmas = nil
  225.  
  226.         -- Zombie Grenades (use nil for default)
  227.         zombie_frags = 0
  228.         zombie_plasmas = 0
  229.  
  230.         -- Objects Humans Cannot Interact With (separate entries with a comma)
  231.         human_blocked = {
  232.                         "weapons\\flag\\flag",
  233.                         }
  234.  
  235.         -- Objects Zombies Cannot Interact With (separate entires with a comma)
  236.         zombie_blocked = {
  237.                         "weapons\\assault rifle\\assault rifle",
  238.                         "weapons\\pistol\\pistol",
  239.                         "weapons\\plasma pistol\\plasma pistol",
  240.                         "weapons\\plasma rifle\\plasma rifle",
  241.                         "weapons\\needler\\mp_needler",
  242.                         "weapons\\shotgun\\shotgun",
  243.                         "weapons\\sniper rifle\\sniper rifle",
  244.                         "weapons\\rocket launcher\\rocket launcher",
  245.                         "weapons\\plasma_cannon\\plasma_cannon",
  246.                         "weapons\\flamethrower\\flamethrower",
  247.                         "weapons\\flag\\flag",
  248.                         "weapons\\ball\\ball",
  249.                         "weapons\\frag grenade\\frag grenade",
  250.                         "weapons\\plasma grenade\\plasma grenade",
  251.                         }
  252.  
  253.     -- Vehicle Attributes --
  254.     human_vehicle = true  -- Allows/unallows humans to enter vehicles
  255.     zombie_vehicle = false  -- Allows/unallows zombies to enter vehicles
  256.  
  257.     -- Health and Damage Attributes --
  258.         -- Max Health and Shields (use nil for default, 1 = 100%)
  259.         human_vitality = nil
  260.         zombie_vitality = 0.5
  261.  
  262.         -- Damage Multipliers (use 1 for default)
  263.         human_damage = 1
  264.         zombie_damage = 1
  265.         zombie_melee_damage = 500
  266.  
  267.     -- General Human Attributes --
  268.     human_speed = 1  -- Speed of a human (1 is normal)
  269.  
  270.     -- General Zombie Attributes --
  271.     zombie_speed = 1.5  -- Speed of zombie (1 is normal)
  272.  
  273.     -- Last Man Attributes --
  274.     lastman_damage = 1.5  -- Damage multiplier (use 1 for default)
  275.     lastman_vitality = nil  -- Last man's max health and shields (use nil for no change, 1 = 100%)
  276.     lastman_ammo = 600  -- Ammo last man's weapons will have (use nil for no change)
  277.     lastman_clip = nil  -- Clip last man's weapons will have (use nil for no change)
  278.     lastman_frags = nil  -- Frag grenades the last man should have (use nil for no change, 7 maximum)
  279.     lastman_plasmas = nil  -- Plasma grenades the last man should have (use nil for no change, 7 maximum)
  280.     lastman_speed = 1.5  -- Speed of last man (1 is normal)
  281.     lastman_invistime = 15  -- Amount of time (in seconds) the last man is invisible (use nil to disable)
  282.  
  283. --[[ Uneditable Values ]]--
  284.  
  285.     -- Don't mess with these
  286.     hashes = {}
  287.     cur_hashes = {}
  288.     teams = {}
  289.     blocking = {}
  290.     block_offenses = {}
  291.     balls = {}
  292.     phasor_changeteam = changeteam
  293.     game_begin = false
  294.     join_zombie = false
  295.     no_zombies = false
  296.     block_time_warning = block_time_warning * 1000
  297.     block_time_action = block_time_action * 1000
  298.     cur_players = 0
  299.  
  300.     gametype_base = 0x671340
  301.     writeword(0x4A4DBF, 0x0, 0x9090)
  302.     writeword(0x4A4E7F, 0x0, 0x9090)
  303.  
  304. -- Players --
  305.  
  306.     players = table.load("players")
  307.     players.recent = players.recent or {}
  308.  
  309.     -- Amount of games player indexes are available and printed via 'sv_players'
  310.     players.recentmemory = players.recentmemory or 2
  311.  
  312.     players.levels = players.levels or {}
  313.     players.admins = players.admins or {}
  314.  
  315. -- Commands --
  316.  
  317.     commands = {}
  318.    
  319.     commands.syntax = {}
  320.     commands.info = {}
  321.    
  322.     -- Syntax displayed when a command is executed incorrectly.
  323.     commands.syntax["sv_ammo"] = {"sv_ammo", "<Player ID or Server Index>", "<opt: Weapon or Slot>", "<Ammo>", "<Clip>"}
  324.    
  325.     --commands.syntax["cls"] = {"cls"}
  326.     commands.syntax["sv_help"] = {"sv_help", "<Command>"}
  327.     commands.syntax["sv_players"] = {"sv_players", "<opt: Search>"}
  328.     commands.syntax["sv_banlist"] = {"sv_banlist"}
  329.     commands.syntax["sv_ban"] = {"sv_ban", "<Player ID or Server Index>", "<opt: Ban Penalty>"}
  330.     commands.syntax["sv_unban"] = {"sv_unban", "<Server Index>"}
  331.     commands.syntax["sv_kick"] = {"sv_kick", "<Player ID or Server Index>"}
  332.     commands.syntax["sv_ban_penalty"] = {"sv_ban_penalty", "<opt: Bancount>", "<opt: Ban Penalty>"}
  333.     commands.syntax["sv_friendly_fire"] = {"sv_friendly_fire", "<opt: Friendly Fire Value>"}
  334.     commands.syntax["sv_gamelist"] = {"sv_gamelist", "<opt: Search>"}
  335.     commands.syntax["sv_maxplayers"] = {"sv_maxplayers", "<opt: Value>"}
  336.     commands.syntax["sv_name"] = {"sv_name", "<opt: Server Name>"}
  337.     commands.syntax["sv_password"] = {"sv_password", "<opt: Password>"}
  338.     commands.syntax["sv_public"] = {"sv_public", "<opt: Boolean>"}
  339.     commands.syntax["sv_rcon_password"] = {"sv_rcon_password", "<opt: Password>"}
  340.     commands.syntax["sv_single_flag_force_reset"] = {"sv_single_flag_force_reset", "<opt: Boolean>"}
  341.     commands.syntax["sv_status"] = {"sv_status"}
  342.     commands.syntax["sv_timelimit"] = {"sv_timelimit", "<opt: Timelimit>"}
  343.     commands.syntax["sv_tk_ban"] = {"sv_tk_ban", "<opt: Value>"}
  344.     commands.syntax["sv_tk_cooldown"] = {"sv_tk_cooldown", "<opt: Value>"}
  345.     commands.syntax["sv_tk_grace"] = {"sv_tk_grace", "<opt: Value>"}
  346.    
  347.     commands.syntax["sv_map"] = {"sv_map", "<Map>", "<Gametype>", "<opt: Scripts...>"}
  348.     commands.syntax["sv_map_next"] = {"sv_map_next"}
  349.     commands.syntax["sv_map_reset"] = {"sv_map_reset", "<opt: Count>"}
  350.     commands.syntax["sv_mapcycle"] = {"sv_mapcycle"}
  351.     commands.syntax["sv_mapcycle_add"] = {"sv_mapcycle_add", "<Map>", "<Gametype>", "<opt: Scripts...>"}
  352.     commands.syntax["sv_mapcycle_del"] = {"sv_mapcycle_del", "<Mapcycle Index>"}
  353.     commands.syntax["sv_mapcycle_begin"] = {"sv_mapcycle_begin"}
  354.     commands.syntax["sv_mapcycle_timeout"] = {"sv_mapcycle_timeout", "<opt: Value>"}
  355.     commands.syntax["sv_maplist"] = {"sv_maplist", "<opt: Search>"}
  356.    
  357.     commands.syntax["sv_gametypes"] = {"sv_gametypes", "<opt: Search>"}
  358.     commands.syntax["sv_scripts"] = {"sv_scripts", "<opt: Search>"}
  359.    
  360.     commands.syntax["sv_mapvote"] = {"sv_mapvote", "<opt: Boolean>"}
  361.     commands.syntax["sv_mapvote_begin"] = {"sv_mapvote_begin"}
  362.     commands.syntax["sv_mapvote_add"] = {"sv_mapvote_add", "<Map>", "<Gametype>", "<opt: Scripts...>"}
  363.     commands.syntax["sv_mapvote_del"] = {"sv_mapvote_del", "<Mapvote Index>"}
  364.     commands.syntax["sv_mapvote_list"] = {"sv_mapvote_list"}
  365.     commands.syntax["sv_mapvote_info"] = {"sv_mapvote_info", "<Mapvote Index>"}
  366.     commands.syntax["sv_mapvote_options"] = {"sv_mapvote_options", "<opt: Value>"}
  367.    
  368.     commands.syntax["sv_objects"] = {"sv_objects", "<opt: Search>"}
  369.     commands.syntax["sv_create"] = {"sv_create", "<opt: Player ID or Server Index>", "<Object>", "<opt: Respawn Time>", "<opt: X>", "<opt: Y>", "<opt: Z>"}
  370.     commands.syntax["sv_destroy"] = {"sv_destroy", "<Object ID or Search>"}
  371.    
  372.     commands.syntax["sv_reloadscripts"] = {"sv_reloadscripts"}
  373.     commands.syntax["sv_teams_balance"] = {"sv_teams_balance"}
  374.     commands.syntax["sv_teams_lock"] = {"sv_teams_lock"}
  375.     commands.syntax["sv_teams_unlock"] = {"sv_teams_unlock"}
  376.     commands.syntax["sv_changeteam"] = {"sv_changeteam", "<Player ID or Server Index>"}
  377.     commands.syntax["sv_teleport"] = {"sv_teleport", "<Player ID or Server Index>", "<Location Name or X>", "<opt: Y>", "<opt: Z>"}
  378.     commands.syntax["sv_teleport_to"] = {"sv_teleport_to", "<Teleported Player ID or Server Index>", "<Destination Player ID or Server Index>"}
  379.     commands.syntax["sv_teleport_add"] = {"sv_teleport_add", "<Location Name>", "<opt: X>", "<opt: Y>", "<opt: Z>"}
  380.     commands.syntax["sv_teleport_del"] = {"sv_teleport_del", "<Teleport Index>"}
  381.     commands.syntax["sv_teleport_list"] = {"sv_teleport_list"}
  382.     commands.syntax["sv_kickafk"] = {"sv_kickafk", "<opt: AFK Time>"}
  383.     commands.syntax["sv_host"] = {"sv_host", "<Value>"}
  384.     commands.syntax["sv_say"] = {"sv_say", "<Message>"}
  385.     commands.syntax["sv_gethash"] = {"sv_gethash", "<Player ID or Server Index>"}
  386.     commands.syntax["sv_chatids"] = {"sv_chatids", "<opt: Boolean>"}
  387.     commands.syntax["sv_disablelog"] = {"sv_disablelog"}
  388.     commands.syntax["sv_logname"] = {"sv_logname", "<Log Type>", "<Log Name>"}
  389.     commands.syntax["sv_savelog"] = {"sv_savelog"}
  390.     commands.syntax["sv_loglimit"] = {"sv_loglimit", "<Log Type>", "<Log Size>"}
  391.     commands.syntax["sv_getobject"] = {"sv_getobject", "<Player ID or Server Index>"}
  392.    
  393.     commands.syntax["sv_kill"] = {"sv_kill", "<Player ID, Server Index or Team>", "<opt: Killer Player ID or Server Index>"}
  394.     commands.syntax["sv_invis"] = {"sv_invis", "<opt: Player ID, Server Index or Team>", "<opt: Duration>"}
  395.     commands.syntax["sv_setspeed"] = {"sv_setspeed", "<Player ID, Server Index or Team>", "<Speed>", "<opt: Duration>"}
  396.    
  397.     commands.syntax["sv_unique"] = {"sv_unique"}
  398.     commands.syntax["sv_alias"] = {"sv_alias", "<Player ID or Server Index>"}
  399.     commands.syntax["sv_reset_alias"] = {"sv_reset_alias", "<Player ID or Server Index>"}
  400.     commands.syntax["sv_player_memory"] = {"sv_player_memory", "<Value>"}
  401.     commands.syntax["sv_player_name"] = {"sv_player_name", "<Player ID or Server Index>", "<opt: New Player Name>"}
  402.     commands.syntax["sv_player_index"] = {"sv_player_index", "<Player ID or Server Index>", "<opt: New Server Index>"}
  403.     commands.syntax["sv_message"] = {"sv_message", "<Player ID or Server Index>", "<Message>"}
  404.    
  405.     commands.syntax["sv_commands"] = {"sv_commands", "<opt: Search, Player ID, Server Index or Admin Level>"}
  406.     commands.syntax["sv_levels"] = {"sv_levels", "<opt: Search>"}
  407.     commands.syntax["sv_level_add"] = {"sv_level_add", "<opt: Level Name>"}
  408.     commands.syntax["sv_level_del"] = {"sv_level_del", "<Admin Level>"}
  409.     commands.syntax["sv_level_admins"] = {"sv_level_admins", "<Admin Level>"}
  410.     commands.syntax["sv_level_id"] = {"sv_level_id", "<Admin Level>", "<opt: Level ID>"}
  411.     commands.syntax["sv_level_name"] = {"sv_level_name", "<Admin Level>", "<opt: Level Name>"}
  412.     commands.syntax["sv_admin_add"] = {"sv_admin_add", "<Player ID or Server Index>", "<opt: Admin Level>"}
  413.     commands.syntax["sv_admin_del"] = {"sv_admin_del", "<Player ID or Server Index>"}
  414.     commands.syntax["sv_command_add"] = {"sv_command_add", "<Admin Level>", "<Command>"}
  415.     commands.syntax["sv_command_del"] = {"sv_command_del", "<Admin Level>", "<Command>"}
  416.     commands.syntax["sv_admins"] = {"sv_admins", "<opt: Search, Player ID, Server Index, Command, or Admin Level>"}
  417.     commands.syntax["sv_admin_level"] = {"sv_admin_level", "<Player ID or Server Index>", "<opt: Admin Level>"}
  418.     commands.syntax["sv_admin_default"] = {"sv_admin_default", "<opt: Admin Level>"}
  419.     commands.syntax["sv_openaccess"] = {"sv_openaccess", "<Admin Level>", "<opt: Boolean>"}
  420.    
  421.     commands.syntax["sv_mute"] = {"sv_mute", "<Player ID or Server Index>", "<opt: Mute Duration>", "<opt: Mute Message>"}
  422.     commands.syntax["sv_unmute"] = {"sv_unmute", "<Player ID or Server Index>"}
  423.     commands.syntax["sv_permamute"] = {"sv_permamute", "<Player ID or Server Index>", "<opt: Mute Message>"}
  424.     commands.syntax["sv_mute_duration"] = {"sv_mute_duration", "<Player ID or Server Index>", "<opt: New Mute Duration>"}
  425.     commands.syntax["sv_mute_message"] = {"sv_mute_message", "<Player ID or Server Index>", "<opt: New Mute Message>"}
  426.     commands.syntax["sv_mute_info"] = {"sv_mute_info", "<Player ID or Server Index>"}
  427.     commands.syntax["sv_swears"] = {"sv_swears", "<Player ID or Server Index>"}
  428.     commands.syntax["sv_mute_players"] = {"sv_mute_players"}
  429.     commands.syntax["sv_mutelist"] = {"sv_mutelist", "<opt: Search or Sorted By>", "<opt: Sorting Direction>", "<opt: Number of Results>"}
  430.     commands.syntax["sv_mutelog"] = {"sv_mutelog", "<Player ID or Server Index>"}
  431.     commands.syntax["sv_reset_mute_info"] = {"sv_reset_mute_info", "<Player ID or Server Index>"}
  432.  
  433.     commands.syntax["sv_swear_add"] = {"sv_swear_add", "<Word>", "<opt: Appended Word>", "<opt: Swear Type>"}
  434.     commands.syntax["sv_swear_del"] = {"sv_swear_del", "<Word>", "<opt: Swear Type>"}
  435.     commands.syntax["sv_swear_type"] = {"sv_swear_type", "<Word>"}
  436.     commands.syntax["sv_sweartable"] = {"sv_sweartable", "<opt: Swear Type>"}
  437.     commands.syntax["sv_automute"] = {"sv_automute", "<opt: Boolean>"}
  438.     commands.syntax["sv_swears_to_mute"] = {"sv_swears_to_mute", "<opt: Swears to Mute>"}
  439.     commands.syntax["sv_swear_action"] = {"sv_swear_action", "<opt: Swear Action>"}
  440.     commands.syntax["sv_swear_append"] = {"sv_swear_append", "<opt: Default Swear Append>"}
  441.     commands.syntax["sv_swear_message"] = {"sv_swear_message", "<opt: Swear Message>"}
  442.     commands.syntax["sv_swear_penalty"] = {"sv_swear_penalty", "<opt: Automute Swear Penalty>"}
  443.     commands.syntax["sv_mute_notify"] = {"sv_mute_notify", "<opt: Mutes Until Notifed>"}
  444.    
  445.     -- Information about command displayed when a player uses sv_help.
  446.     -- Command information:
  447.    
  448.     --commands.info["cls"] = {"Stops console messages from printing when the rcon console is not open."}
  449.     commands.info["sv_help"] = {"Displays information and syntax about the given command."}
  450.     commands.info["sv_players"] = {"Displays a list of players currently in the server as well as players who have recently left the server if a search is not specified. If a search is specified, this command searches through all players' aliases that have joined the server under and returns a list of matches, their Server Index and Server Name."}
  451.     commands.info["sv_banlist"] = {"Displays a list of players who are currently banned, their Server ID and the amount of times they have been banned."}
  452.     commands.info["sv_ban"] = {"Kicks and bans the specified player from joining the server in the future.", "If no Ban Penalty is specified, the player will be banned for the default amount of time based on how many times they have been banned."}
  453.     commands.info["sv_unban"] = {"Unbans the specified player via their Server Index."}
  454.     commands.info["sv_kick"] = {"Kicks the specified player from the server."}
  455.     commands.info["sv_ban_penalty"] = {"Amount of time a player should be banned for depending on the amount of times they have been banned in the past.", "If no Ban Penalty is specified, the Ban Penalty for the specified Bancount is printed.", "If neither a Bancount nor a Ban Penalty are specified, all Ban Penalties for all Bancounts are printed."}
  456.     commands.info["sv_friendly_fire"] = {"Used to provide a global override for the gametype Friendly Fire setting.", "If no Friendly Fire Value is specified, the current value is printed."}
  457.     commands.info["sv_gamelist"] = {"Prints a list of gametypes sorted alphabetically.", "If no Search is specified, all gametypes are printed."}
  458.     commands.info["sv_maxplayers"] = {"Specifies the maximum amount of players able to join the server at once.", "If no Value is specified, the current maximum players is printed."}
  459.     commands.info["sv_name"] = {"The name of the server.", "If no Server Name is specified, the current Server Name is printed."}
  460.     commands.info["sv_password"] = {"The password players must enter to join the server. Use sv_password \"\" to disable the password.", "If no Password is specified, the current Server Password is printed."}
  461.     commands.info["sv_public"] = {"Specifies if this server is available to players outside of your LAN.", "If no Boolean is specified, the current Public Boolean is printed."}
  462.     commands.info["sv_rcon_password"] = {"The password admins must use to use rcon commands in the rcon console.", "If no Password is specified, the current Rcon Password is printed."}
  463.     commands.info["sv_single_flag_force_reset"] = {"Specifies boolean for in a single-flag CTF game, if the time for a player to be on offense runs out, even if a player is holding the flag, the teams will switch offense and defense and the flag will reset.", "If no Boolean is specified, the current Single Flag Force Reset Boolean is printed."}
  464.     commands.info["sv_status"] = {"Displays the current map and amount of players the server is currently running with."}
  465.     commands.info["sv_timelimit"] = {"Changes the timelimit for the next game and every game after. Use -1 for default and 0 for infinite.", "If no Timelimit is specified, the current Timelimit is printed."}
  466.     commands.info["sv_tk_ban"] = {"Specifies the amount of Team Kill Points a player must have before they are automatically banned by the server.", "If no Value is specified, the current TK Ban Value is printed."}
  467.     commands.info["sv_tk_cooldown"] = {"Specifies the amount of time before a player's Team Kill Points are reset to zero.", "If no Value is specified, the current TK Cooldown Value is printed."}
  468.     commands.info["sv_tk_grace"] = {"Specifies the time window in which multiple team kills only count as one Team Kill Point.", "If no Value is specified, the current TK Grace Value is printed."}
  469.    
  470.     commands.info["sv_map"] = {"Loads the specified map with the specified gametype and specified scripts.", "If no scripts are specified, only the Main script will be loaded."}
  471.     commands.info["sv_map_reset"] = {"Resets the current map the specified amount of times.", "If no Count is specified, the map will be reset once."}
  472.     commands.info["sv_mapcycle"] = {"Prints the current entries in the mapcycle and their Mapcycle Indexes."}
  473.     commands.info["sv_mapcycle_add"] = {"Adds the specified map, gametype, and script to the mapcycle.", commands.info["sv_map"][2]}
  474.     commands.info["sv_mapcycle_del"] = {"Deletes the specified mapcycle entry via its Mapcycle Index (accessible via \"sv_mapcycle\")"}
  475.     commands.info["sv_mapcycle_begin"] = {"Begins the current mapcycle."}
  476.     commands.info["sv_mapcycle_timeout"] = {"The amount of time in seconds the Post Carnage Report shows after players are able to exit the server by hitting Esc.", "If no Value is specified, the current Mapcycle Timeout Value is printed."}
  477.     commands.info["sv_maplist"] = {"Prints list of map names given a search.", "If no search is specified, all map names are printed."}
  478.    
  479.     commands.info["sv_scripts"] = {"Prints a list of all valid scripts given the input search.", "If no search is specified, all valid scripts are printed."}
  480.    
  481.     commands.info["sv_reloadscripts"] = {"Reloads the current script(s)."}
  482.     commands.info["sv_mapvote"] = {"Toggles the allowance of Mapvoting.", "If no Boolean is specified, the current Mapvote Boolean is printed."}
  483.     commands.info["sv_mapvote_add"] = {"Adds the specified map, gametype and scripts to the Mapvote List.", commands.info["sv_map"][2]}
  484.     commands.info["sv_mapvote_del"] = {"Deletes the specified gametype from the Mapvote List via its Mapvote Index (accessible via \"sv_mapvote_list\")."}
  485.     commands.info["sv_mapvote_list"] = {"Lists all gametypes in the Mapvote List and their Mapvote Indexes."}
  486.     commands.info["sv_teams_balance"] = {"Balances the teams by choosing a random person on the favored team and changing their team."}
  487.     commands.info["sv_teams_lock"] = {"Does not allow players to change their team via the pause menu."}
  488.     commands.info["sv_teams_unlock"] = {"Allows players to change their team via the pause menu."}
  489.     commands.info["sv_changeteam"] = {"Changes the team of the specified player."}
  490.     commands.info["sv_teleport"] = {"Teleports the specified player to the specified location name or specified coordinates.", "You must specify either only the location name or X, Y, and Z coordinates."}
  491.     commands.info["sv_teleport_to"] = {"Teleports the specified Teleported Player to the specified Destination Player's coordinates."}
  492.     commands.info["sv_teleport_add"] = {"Adds the specified location the Teleport Location List.", "If only the Location Name is specified, your current coordinates are saved with the given name."}
  493.     commands.info["sv_teleport_del"] = {"Deletes the specified Teleport Location via its Teleport Location Index (accessible via \"sv_teleport_list\")."}
  494.     commands.info["sv_teleport_list"] = {"Lists all Teleport Locations for the current map and their coordinates."}
  495.     commands.info["sv_kickafk"] = {"Specifies the amount of time a player should be AFK before they are kicked from the server.", "If no AFK Time is specified, the current Kick AFK Time is printed."}
  496.     commands.info["sv_host"] = {"WHAT THE HELL DOES THIS DO?"}
  497.     commands.info["sv_say"] = {"Prints the specified Message in the chat as **SERVER**."}
  498.     commands.info["sv_gethash"] = {"Prints the hash of the specified player."}
  499.     commands.info["sv_chatids"] = {"Toggles the numbers that appear next to a player's name when they send messages in the chat.", "If no Boolean is specified, the current Chat ID Boolean is printed."}
  500.     commands.info["sv_disablelog"] = {"Disables Phasor logging."}
  501.     commands.info["sv_logname"] = {"Changes the specified Log Type to have the specified Log Name."}
  502.     commands.info["sv_savelog"] = {"Saves all logs."}
  503.     commands.info["sv_loglimit"] = {"Specifies the limit of size in kB a certain Log Type file can get to before a new file is automatically created."}
  504.     commands.info["sv_getobject"] = {"Returns the Halo Object ID of the specified player."}
  505.    
  506.     commands.info["sv_kill"] = {"Kills the specified player or team, sending them the specified message.", "If no Message is specified, players will be sent default messages."}
  507.     commands.info["sv_invis"] = {"Gives the specified player active camouflage for the specified amount of time.", "If no Player or Duration is specified, all players who currently have camouflage will be printed.", "If no Duration is specified, the player will be given camouflage until death."}
  508.     commands.info["sv_setspeed"] = {"Changes the current player's speed to the specified value.", "If no Duration is specified, this player's speed will remain until the end of the game or until changed."}
  509.    
  510.     commands.info["sv_unique"] = {"Displays the amount of unique players who have joined the server."}
  511.     commands.info["sv_alias"] = {"Displays a list of names the specified player has joined this server under sorted from the name they use most often to the name they use least often."}
  512.     commands.info["sv_reset_alias"] = {"Clears the alias list for the specified player."}
  513.     commands.info["sv_player_memory"] = {"Amount of games a player's Server Index and name will be accessible via \"sv_players\".", "If no Value is specified, the current amount of games a player's information is saved for is printed."}
  514.     commands.info["sv_player_name"] = {"Prints or allows you to change the specified player's Player Name.", "If no New Player Name is specified, the specified player's current Player Name is printed.", "Entering \"\" as a player's new name will reset a player's Player Name to their most-used alias."}
  515.     commands.info["sv_player_index"] = {"Prints or allows you to change the specified player's Server Index.", "If no New Server Index is specified, the specified player's current Server Index is printed."}
  516.     commands.info["sv_message"] = {"Sends a message to the specified player in their console chat. If they are not currently in the server, they will receive this message upon joining."}
  517.    
  518.     commands.info["sv_commands"] = {"Prints a list of admin commands.", "If no Search, Player ID, Server Index or Admin Level is specified, prints all commands you are able to execute."}
  519.     commands.info["sv_levels"] = {"Prints a list of Admin Level IDs and their respective names."}
  520.     commands.info["sv_level_add"] = {"Creates a new Admin Level with the specified Level Name.", "If no Level Name is specified, a default Level Name will be given."}
  521.     commands.info["sv_level_del"] = {"Deletes the specified Admin Level."}
  522.     commands.info["sv_level_admins"] = {"Prints a list of all admins in the specified Admin Level."}
  523.     commands.info["sv_level_id"] = {"The unique integer ID of the specified Admin Level.", "If no Level ID is specified, the current Level ID is printed."}
  524.     commands.info["sv_level_name"] = {"The unique nickname for the specified Admin Level.", "If no Level Name is specified, the current Level Name is printed."}
  525.     commands.info["sv_admin_add"] = {"Adds the specified player to the specified Admin Level."}
  526.     commands.info["sv_admin_del"] = {"Removes the specified player from the admin list."}
  527.     commands.info["sv_command_add"] = {"Adds the specified command to the specified Admin Level."}
  528.     commands.info["sv_command_del"] = {"Removes the specified command from the specified Admin Level."}
  529.     commands.info["sv_admins"] = {"Prints a list of all admins in order of Admin Level."}
  530.     commands.info["sv_admin_level"] = {"Admin Level of the specified player.", "If no Admin Level is specified, the player's current Admin Level is printed."}
  531.     commands.info["sv_openaccess"] = {"Allows/unallows the specified Admin Level to execute any admin command.", "If no Boolean is specified, the current Open-Access Boolean is printed."}
  532.    
  533.     commands.info["sv_mute"] = {"Mutes the specified player for the specified duration and with the specified Mute Message.", "If no Mute Duration is specified, the default duration is -1 (for the rest of the game).", "If no Mute Message is specified, the default Mute Message is \"You have been muted.\""}
  534.     commands.info["sv_unmute"] = {"Unmutes the specified player."}
  535.     commands.info["sv_permamute"] = {"Permanently mutes the specified player with the specified Mute Message.", "If no Mute Message is specified, the default Mute Message is \"You have been permanently muted.\""}
  536.     commands.info["sv_mute_duration"] = {"Prints or allows you to change the specified player's Mute Duration.", "If no New Mute Duration is specified, the specified player's current Mute Duration is printed."}
  537.     commands.info["sv_mute_message"] = {"Prints or allows you to change the specified player's Mute Message.", "If no New Mute Message is specified, the specified player's current Mute Message is printed."}
  538.     commands.info["sv_mute_info"] = {"Prints specified player's mute information."}
  539.     commands.info["sv_swears"] = {"Prints a list of swears the specified player has attempted to send through chat."}
  540.     commands.info["sv_mute_players"] = {"Prints basic mute information about players currently in the server."}
  541.     commands.info["sv_mutelist"] = {"Displays a list of players based on certain mute categories sorted in the direction specified.", "If no Search or Sorted By entry is specified, the list will be sorted by Server Index.", "If no Number of Results is specified, the default value is 15.", "If no Sorting Direction is specified, a default sorting direction is chosen based on the search criteria."}
  542.     commands.info["sv_mutelog"] = {"Displays the Mute Log of the specified player. Includes mutes and unmutes with details of each."}
  543.     commands.info["sv_reset_mute_info"] = {"Resets the specified player's mute information."}
  544.     commands.info["sv_reset_alias"] = {"Clears a player's alias list."}
  545.    
  546.     commands.info["sv_swear_add"] = {"Adds the specified word to the Swear Table.", "If no Appended Word is specified, the default Swear Append is applied.", "If no Swear Type is specified, the default Swear Type is \"exact\"."}
  547.     commands.info["sv_swear_del"] = {"Deletes the specified word from the Swear Table.", "If no Swear Type is specified, the specified command will be deleted from both the Exact Swear Table and the Anywhere Swear Table."}
  548.     commands.info["sv_swear_type"] = {"Prints the type of swear word (\"Exact\" or \"Anywhere\") the specified word is."}
  549.     commands.info["sv_sweartable"] = {"Prints the current sweartable given a specific Swear Type."}
  550.     commands.info["sv_automute"] = {"Boolean allowing/unallowing the server to automatically mute a player who attempts to breach the swear filter a certain amount of times."}
  551.     commands.info["sv_swears_to_mute"] = {"Amount of times a player must attempt to swear before they are automuted by the server."}
  552.     commands.info["sv_swear_action"] = {"Action taken when a player attempts to swear through the chat; either blocked, appended, or no action."}
  553.     commands.info["sv_swear_append"] = {"Default string a swear word with no specified append string will be appended to."}
  554.     commands.info["sv_swear_message"] = {"Message players receive when they attempt to swear."}
  555.     commands.info["sv_swear_penalty"] = {"Duration of a player's mute when they are automuted for swearing."}
  556.     commands.info["sv_mute_notify"] = {"Amount of times a player must be muted before an admin is notified while executing ' sv_mute ' of how many times this player has been muted before."}
  557.    
  558.     -- Parameter Information:
  559.    
  560.     commands.info["<Player ID>"] = {"Player ID: Unique player number between 1 and 16 obtained by \"sv_players\"."}
  561.     commands.info["<Server Index>"] = {"Server Index: Unique 3-digit ID which allows an admin to access a player's information even if they aren't in the server. You may also specify a player's hash instead."}
  562.     commands.info["<Team>"] = {"Team: Either \"all\", \"red\", \"blue\" or \"me\". Executes this command on all of these players."}
  563.     commands.info["<Player ID or Server Index>"] = {commands.info["<Player ID>"][1], commands.info["<Server Index>"][1]}
  564.     commands.info["<Player ID, Server Index or Team>"] = {commands.info["<Player ID>"][1], commands.info["<Server Index>"][1], commands.info["<Team>"][1]}
  565.     commands.info["<Boolean>"] = {"Boolean: True or False."}
  566.     commands.info["<Word>"] = {"Word: String this command should be applied to."}
  567.     commands.info["<Message>"] = {"Message: Message to be sent."}
  568.     commands.info["<Search>"] = {"Search: Returns matches to these keywords."}
  569.     commands.info["<Search or Sorted By>"] = {commands.info["<Search>"][1], "Sorted By: The criteria the table is sorted by (i.e. name, index, etc)."}
  570.     commands.info["<Number of Results>"] = {"Number of Results: Amount of entries printed."}
  571.     commands.info["<Sorting Direction>"] = {"Sorting Direction: Ascending, descending, or default order for this table to be sorted."}
  572.     commands.info["<Command>"] = {"Command: Admin command."}
  573.     commands.info["<Message>"] = {"Message: Message to be sent."}
  574.     commands.info["<Duration>"] = {"Duration: Amount of time in seconds."}
  575.     commands.info["<Value>"] = {"Value: Value this command should take in."}
  576.     commands.info["<Count>"] = {"Count: Iterations of this characteristic."}
  577.     commands.info["<Special Value>"] = {"This command allows the use of \"cur\" and \"inf\" as well as mathematical operators to represent certain values. \"cur\" is the current value and \"inf\" is infinity. You can mix and match these properties with numbers and mathematical operators to achieve the value you want. Example: \"sv_setspeed 1 cur*2\" would double player 1's speed. Make sure there are no spaces in your Special Value entry."}
  578.     commands.info["<Speed>"] = {"Speed: Speed of player.", commands.info["<Special Value>"][1]}
  579.    
  580.     commands.info["<Ban Name>"] = {"Ban Name: Name saved in the banlist for this player."}
  581.     commands.info["<Bancount>"] = {"Bancount: Amount of times a player has been banned."}
  582.     commands.info["<Ban Penalty>"] = {"Ban Penalty: Amount of time a player is banned for. Use d for days, h for hours, m for minutes, s for seconds, and inf for Infinite (for example: 5d 6h 7m 8s)."}
  583.    
  584.     commands.info["<Friendly Fire Value>"] = {"Friendly Fire Value: 0 = \"defaults\" | 1 = \"off\" | 2 = \"shields\" | 3 = \"on\""}
  585.     commands.info["<Server Name>"] = {"Server Name: Name of server players see when they attempt to join it via the Gamespy Lobby."}
  586.     commands.info["<Password>"] = {"Password: Password which must be 8 characters or less."}
  587.     commands.info["<Timelimit>"] = {"Timelimit: Amount of time in minutes before the current game ends."}
  588.    
  589.     commands.info["<Map>"] = {"Map: Name of map accessible via \"sv_maplist\"."}
  590.     commands.info["<Gametype>"] = {"Gametype: Name of gametype accessible via \"sv_gamelist\"."}
  591.     commands.info["<Scripts>"] = {"Scripts: Names of scripts to be loaded (names available via \"sv_scripts\")."}
  592.     commands.info["<Mapcycle Index>"] = {"Mapcycle Index: Index by which a mapcycle entry is deleted."}
  593.     commands.info["<Mapvote Index>"] = {"Mapvote Index: Index by which a Mapvote entry is deleted."}
  594.    
  595.     commands.info["<Location Name>"] = {"Location Name: Name of teleportation location to be saved in the Teleport Location List."}
  596.     commands.info["<X>"] = {"X: X-coordinate (east-west)."}
  597.     commands.info["<Y>"] = {"Y: Y-coordinate (north-south)."}
  598.     commands.info["<Z>"] = {"Z: Z-coordinate (up-down)."}
  599.     commands.info["<Location Name or X>"] = {commands.info["<Location Name>"][1], commands.info["<X>"][1]}
  600.     commands.info["<Teleported Player ID or Server Index>"] = {"Teleported Player: Player ID or Server Index of the player who will be teleported.", unpack(commands.info["<Player ID or Server Index>"])}
  601.     commands.info["<Teleport Index>"] = {"Teleport Index: Index by which a Teleport Location is deleted."}
  602.    
  603.     commands.info["<AFK Time>"] = {"AFK Time: Amount of time in minutes a player is AFK."}
  604.     commands.info["<Log Type>"] = {"Log Type: Type of log such as \"game\", \"rcon\", etc."}
  605.     commands.info["<Log Name>"] = {"Log Name: Name of the file of the specified Log Type."}
  606.     commands.info["<Log Size>"] = {"Log Size: Maximum size in kB of a log of the specified Log Type before a new file is created."}
  607.    
  608.     commands.info["<Admin Level>"] = {"Admin Level: Specified by either the level's ID or Name."}
  609.     commands.info["<Search, Player ID, Server Index or Admin Level>"] = {commands.info["<Search>"][1], commands.info["<Player ID or Server Index>"][1], commands.info["<Admin Level>"][1]}
  610.     commands.info["<Search, Player ID, Server Index, Command, or Admin Level>"] = {commands.info["<Search>"][1], commands.info["<Player ID or Server Index>"][1], commands.info["<Command>"][1], commands.info["<Admin Level>"][1]}
  611.     commands.info["<Level ID>"] = {"Level ID: Unique value for an Admin Level. All Admin Level ID's begin with L (i.e. L0).w"}
  612.     commands.info["<Level Name>"] = {"Level Name: Nickname given to an Admin Level."}
  613.    
  614.     commands.info["<Mute Duration>"] = {"Mute Duration: Amount of time the specified player is muted for."}
  615.     commands.info["<Mute Message>"] = {"Mute Message: Message a muted player receives when they attempt to send a message in chat."}
  616.     commands.info["<New Player Name>"] = {"New Player Name: New Player Name you would like for this player to have."}
  617.     commands.info["<New Server Index>"] = {"New Server Index: New unique Server Index to specify this player."}
  618.     commands.info["<New Mute Duration>"] = {"New Mute Duration: New amount of time this player should be muted for (use \"permanent\" for permanent mutes and \"temporary\" for mutes that last the rest of the game)"}
  619.     commands.info["<New Mute Message>"] = {"New Mute Message: New message this player will receive when he/she attempts to send chat."}
  620.    
  621.     commands.info["<Appended Word>"] = {"Appended Word: Word you would like for the swear word to be changed to when it is attempted to be sent in chat."}
  622.     commands.info["<Swear Type>"] = {"Swear Type: Either \"exact\" or \"anywhere\". Exact Swears are only blocked if the entire word matches, while Anywhere Swears are blocked if the specified string is found anywhere in the message."}
  623.     commands.info["<Swears to Mute>"] = {"Swears to Mute: Amount of swears a player must attempt to send through chat before being automuted."}
  624.     commands.info["<Swear Action>"] = {"Swear Action: Action that should be taken when a player swears. (0 = None) (1 = Block) (2 = Append)"}
  625.     commands.info["<Default Swear Append>"] = {"Default Swear Append: Default string which swear words will be replaced by if they have no specified append string."}
  626.     commands.info["<Swear Message>"] = {"Swear Message: Message players receive when they attempt to send a swear word through the chat. Use \"\" to disable."}
  627.     commands.info["<Automute Swear Penalty>"] = {"Automute Swear Penalty: Duration of a player's mute when they are automuted for swearing."}
  628.     commands.info["<Mutes Until Notified>"] = {"Mutes Until Notified: Amount of times a player must be muted before an administrator is notified when using ' sv_mute ' of how many times this player has been muted in the past."}
  629.    
  630.     chat = {}
  631.    
  632.     sprint = {}
  633.     pprint = {}
  634.     cprint = {}
  635.    
  636.     for i = 0, 15 do
  637.         pprint[i] = {}
  638.     end
  639.    
  640. -- Objects --
  641.  
  642.     objects = {}
  643.     tags = {}
  644.    
  645. -- Tag List --
  646.  
  647.     tags.bipd = {
  648.     ["characters\\cyborg\\cyborg"] = "Cyborg",
  649.     ["characters\\cyborg_mp\\cyborg_mp"] = "Multiplayer Cyborg"
  650.     }
  651.    
  652.     tags["jpt!"] = {
  653.     ["characters\\cyborg\\melee"] = "Generic Melee Damage",
  654.     ["globals\\distance"] = "Distance Damage",
  655.     ["globals\\falling"] = "Fall Damage",
  656.     ["globals\\flaming_death"] = "Flaming Death Damage",
  657.     ["globals\\vehicle_collision"] = "Vehicle Collision Damage",
  658.     ["globals\\vehicle_hit_environment"] = "Vehicle Hit Damage",
  659.     ["globals\\vehicle_killed_unit"] = "Vehicle Kill Unit Damage",
  660.     ["vehicles\\banshee\\banshee bolt"] = "Banshee Bolt Damage",
  661.     ["vehicles\\banshee\\fuel rod trigger"] = "Banshee Fuel Rod Trigger Damage",
  662.     ["vehicles\\banshee\\mp_fuel rod explosion"] = "Banshee Fuel Rod Explosion Damage",
  663.     ["vehicles\\banshee\\trigger"] = "Banshee Trigger Damage",
  664.     ["vehicles\\c gun turret\\mp bolt"] = "Covenant Turret Bolt Damage",
  665.     ["vehicles\\ghost\\ghost bolt"] = "Ghost Bolt Damage",
  666.     ["vehicles\\ghost\\trigger"] = "Ghost Trigger Damage",
  667.     ["vehicles\\rwarthog\\effects\\trigger"] = "Rocket Warthog Trigger Damage",
  668.     ["vehicles\\scorpion\\bullet"] = "Scorpion Bullet Damage",
  669.     ["vehicles\\scorpion\\secondary trigger"] = "Scorpion Secondary Trigger Damage",
  670.     ["vehicles\\scorpion\\shell explosion"] = "Scorpion Shell Explosion Damage",
  671.     ["vehicles\\scorpion\\shell shock wave"] = "Scorpion Shell Shockwave Damage",
  672.     ["vehicles\\warthog\\bullet"] = "Warthog Bullet Damage",
  673.     ["vehicles\\warthog\\trigger"] = "Warthog Trigger Damage",
  674.     ["weapons\\assault rifle\\bullet"] = "Assault Rifle Bullet Damage",
  675.     ["weapons\\assault rifle\\melee"] = "Assault Rifle Melee Damage",
  676.     ["weapons\\assault rifle\\melee_response"] = "Assault Rifle Melee Response Damage",
  677.     ["weapons\\assault rifle\\trigger"] = "Assault Rifle Trigger Damage",
  678.     ["weapons\\ball\\melee"] = "Oddball Melee Damage",
  679.     ["weapons\\ball\\melee_response"] = "Oddball Melee Response Damage",
  680.     ["weapons\\flag\\melee"] = "Flag Melee Damage",
  681.     ["weapons\\flag\\melee_response"] = "Flag Melee Response Damage",
  682.     ["weapons\\flamethrower\\burning"] = "Flamethrower Burning Damage",
  683.     ["weapons\\flamethrower\\explosion"] = "Flamethrower Explosion Damage",
  684.     ["weapons\\flamethrower\\impact damage"] = "Flamethrower Impact Damage",
  685.     ["weapons\\flamethrower\\melee"] = "Flamethrower Melee Damage",
  686.     ["weapons\\flamethrower\\melee_response"] = "Flamethrower Melee Response Damage",
  687.     ["weapons\\flamethrower\\trigger"] = "Flamethrower Trigger Damage",
  688.     ["weapons\\frag grenade\\explosion"] = "Frag Grenade Explosion Damage",
  689.     ["weapons\\frag grenade\\shock wave"] = "Frag Grenade Shockwave Damage",
  690.     ["weapons\\needler\\detonation damage"] = "Needler Detonation Damage",
  691.     ["weapons\\needler\\explosion"] = "Needler Explosion Damage",
  692.     ["weapons\\needler\\impact damage"] = "Needler Impact Damage",
  693.     ["weapons\\needler\\melee"] = "Needler Melee Damage",
  694.     ["weapons\\needler\\melee_response"] = "Needler Melee Response Damage",
  695.     ["weapons\\needler\\shock wave"] = "Needler Shockwave Damage",
  696.     ["weapons\\needler\\trigger"] = "Needler Trigger Damage",
  697.     ["weapons\\pistol\\bullet"] = "Pistol Bullet Damage",
  698.     ["weapons\\pistol\\melee"] = "Pistol Melee Damage",
  699.     ["weapons\\pistol\\melee_response"] = "Pistol Melee Response Damage",
  700.     ["weapons\\pistol\\trigger"] = "Pistol Trigger Damage",
  701.     ["weapons\\plasma grenade\\attached"] = "Plasma Grenade Attached Damage",
  702.     ["weapons\\plasma grenade\\explosion"] = "Plasma Grenade Explosion Damage",
  703.     ["weapons\\plasma grenade\\shock wave"] = "Plasma Grenade Shockwave Damage",
  704.     ["weapons\\plasma pistol\\bolt"] = "Plasma Pistol Bolt Damage",
  705.     ["weapons\\plasma pistol\\melee"] = "Plasma Pistol Melee Damage",
  706.     ["weapons\\plasma pistol\\melee_response"] = "Plasma Pistol Melee Response Damage",
  707.     ["weapons\\plasma pistol\\misfire"] = "Plasma Pistol Misfire Damage",
  708.     ["weapons\\plasma pistol\\trigger"] = "Plasma Pistol Trigger Damage",
  709.     ["weapons\\plasma pistol\\trigger overcharge"] = "Plasma Pistol Trigger Overcharge Damage",
  710.     ["weapons\\plasma rifle\\bolt"] = "Plasma Rifle Bolt Damage",
  711.     ["weapons\\plasma rifle\\charged bolt"] = "Plasma Pistol Charged Bolt",
  712.     ["weapons\\plasma rifle\\melee"] = "Plasma Rifle Melee Damage",
  713.     ["weapons\\plasma rifle\\melee_response"] = "Plasma Rifle Melee Response Damage",
  714.     ["weapons\\plasma rifle\\misfire"] = "Plasma Rifle Misfire Damage",
  715.     ["weapons\\plasma rifle\\trigger"] = "Plasma Rifle Trigger Damage",
  716.     ["weapons\\plasma_cannon\\effects\\plasma_cannon_explosion"] = "Fuel Rod Explosion Damage",
  717.     ["weapons\\plasma_cannon\\effects\\plasma_cannon_melee"] = "Fuel Rod Melee Damage",
  718.     ["weapons\\plasma_cannon\\effects\\plasma_cannon_melee_response"] = "Fuel Rod Melee Response Damage",
  719.     ["weapons\\plasma_cannon\\effects\\plasma_cannon_misfire"] = "Fuel Rod Misfire Damage",
  720.     ["weapons\\plasma_cannon\\effects\\plasma_cannon_trigger"] = "Fuel Rod Trigger Damage",
  721.     ["weapons\\plasma_cannon\\impact damage"] = "Fuel Rod Impact Damage",
  722.     ["weapons\\rocket launcher\\explosion"] = "Rocket Launcher Explosion Damage",
  723.     ["weapons\\rocket launcher\\melee"] = "Rocket Launcher Melee Damage",
  724.     ["weapons\\rocket launcher\\melee_response"] = "Rocket Launcher Melee Response Damage",
  725.     ["weapons\\rocket launcher\\trigger"] = "Rocket Launcher Trigger Damage",
  726.     ["weapons\\shotgun\\melee"] = "Shotgun Melee Damage",
  727.     ["weapons\\shotgun\\melee_response"] = "Shotgun Melee Response Damage",
  728.     ["weapons\\shotgun\\pellet"] = "Shotgun Pellet Damage",
  729.     ["weapons\\shotgun\\trigger"] = "Shotgun Trigger Damage",
  730.     ["weapons\\sniper rifle\\melee"] = "Sniper Rifle Melee Damage",
  731.     ["weapons\\sniper rifle\\melee_response"] = "Sniper Rifle Melee Response Damage",
  732.     ["weapons\\sniper rifle\\sniper bullet"] = "Sniper Rifle Bullet Damage",
  733.     ["weapons\\sniper rifle\\trigger"] = "Sniper Rifle Trigger Damage"
  734.     }
  735.    
  736.     tags.eqip = {
  737.     ["powerups\\active camouflage"] = "Active Camouflage",
  738.     ["powerups\\assault rifle ammo\\assault rifle ammo"] = "Assault Rifle Ammo",
  739.     ["powerups\\double speed"] = "Double Speed",
  740.     ["powerups\\flamethrower ammo\\flamethrower ammo"] = "Flamethrower Ammo",
  741.     ["powerups\\full-spectrum vision"] = "Full-Spectrum Vision",
  742.     ["powerups\\health pack"] = "Health Pack",
  743.     ["powerups\\needler ammo\\needler ammo"] = "Needler Ammo",
  744.     ["powerups\\over shield"] = "Overshield",
  745.     ["powerups\\pistol ammo\\pistol ammo"] = "Pistol Ammo",
  746.     ["powerups\\rocket launcher ammo\\rocket launcher ammo"] = "Rocket Launcher Ammo",
  747.     ["powerups\\shotgun ammo\\shotgun ammo"] = "Shotgun Ammo",
  748.     ["powerups\\sniper rifle ammo\\sniper rifle ammo"] = "Sniper Rifle Ammo",
  749.     ["weapons\\frag grenade\\frag grenade"] = "Frag Grenade",
  750.     ["weapons\\plasma grenade\\plasma grenade"] = "Plasma Grenade"
  751.     }
  752.    
  753.     tags.proj = {
  754.     ["vehicles\\banshee\\banshee bolt"] = "Banshee Bolt",
  755.     ["vehicles\\banshee\\mp_banshee fuel rod"] = "Banshee Fuel Rod",
  756.     ["vehicles\\c gun turret\\mp gun turret"] = "Covenant Turret Bolt",
  757.     ["vehicles\\ghost\\ghost bolt"] = "Ghost Bolt",
  758.     ["vehicles\\scorpion\\bullet"] = "Scorpion Bullet",
  759.     ["vehicles\\scorpion\\tank shell"] = "Scorpion Shell",
  760.     ["vehicles\\warthog\\bullet"] = "Warthog Bullet",
  761.     ["weapons\\assault rifle\\bullet"] = "Assault Rifle Bullet",
  762.     ["weapons\\flamethrower\\flame"] = "Flamethrower Flame",
  763.     ["weapons\\frag grenade\\frag grenade"] = "Frag Grenade Projectile",
  764.     ["weapons\\needler\\mp_needle"] = "Needler Needle",
  765.     ["weapons\\needler\\needle"] = "Campaign Needler Needle",
  766.     ["weapons\\pistol\\bullet"] = "Pistol Bullet",
  767.     ["weapons\\plasma grenade\\plasma grenade"] = "Plasma Grenade Projectile",
  768.     ["weapons\\plasma pistol\\bolt"] = "Plasma Pistol Bolt",
  769.     ["weapons\\plasma rifle\\bolt"] = "Plasma Rifle Bolt",
  770.     ["weapons\\plasma rifle\\charged bolt"] = "Plasma Pistol Charged Bolt",
  771.     ["weapons\\plasma_cannon\\plasma_cannon"] = "Fuel Rod Projectile",
  772.     ["weapons\\rocket launcher\\rocket"] = "Rocket Launcher Rocket",
  773.     ["weapons\\shotgun\\pellet"] = "Shotgun Pellet",
  774.     ["weapons\\sniper rifle\\sniper bullet"] = "Sniper Rifle Bullet"
  775.     }
  776.    
  777.     tags.weap = {
  778.     ["vehicles\\banshee\\mp_banshee gun"] = "Banshee Gun",
  779.     ["vehicles\\c gun turret\\mp gun turret gun"] = "Covenant Turret Gun",
  780.     ["vehicles\\ghost\\mp_ghost gun"] = "Ghost Gun",
  781.     ["vehicles\\rwarthog\\rwarthog_gun"] = "Rocket Warthog Gun",
  782.     ["vehicles\\scorpion\\scorpion cannon"] = "Scorpion Cannon",
  783.     ["vehicles\\warthog\\warthog gun"] = "Warthog Gun",
  784.     ["weapons\\assault rifle\\assault rifle"] = "Assault Rifle",
  785.     ["weapons\\ball\\ball"] = "Oddball",
  786.     ["weapons\\flag\\flag"] = "Flag",
  787.     ["weapons\\flamethrower\\flamethrower"] = "Flamethrower",
  788.     ["weapons\\gravity rifle\\gravity rifle"] = "Gravity Rifle",
  789.     ["weapons\\needler\\mp_needler"] = "Needler",
  790.     ["weapons\\needler\\needler"] = "Campaign Needler",
  791.     ["weapons\\pistol\\pistol"] = "Pistol",
  792.     ["weapons\\plasma pistol\\plasma pistol"] = "Plasma Pistol",
  793.     ["weapons\\plasma rifle\\plasma rifle"] = "Plasma Rifle",
  794.     ["weapons\\plasma_cannon\\plasma_cannon"] = "Fuel Rod",
  795.     ["weapons\\rocket launcher\\rocket launcher"] = "Rocket Launcher",
  796.     ["weapons\\shotgun\\shotgun"] = "Shotgun",
  797.     ["weapons\\sniper rifle\\sniper rifle"] = "Sniper Rifle"
  798.     }
  799.    
  800.     tags.vehi = {
  801.     ["vehicles\\banshee\\banshee_mp"] = "Banshee",
  802.     ["vehicles\\c gun turret\\c gun turret_mp"] = "Covenant Turret",
  803.     ["vehicles\\ghost\\ghost_mp"] = "Ghost",
  804.     ["vehicles\\rwarthog\\rwarthog"] = "Rocket Warthog",
  805.     ["vehicles\\scorpion\\scorpion_mp"] = "Scorpion",
  806.     ["vehicles\\warthog\\mp_warthog"] = "Warthog"
  807.     }
  808.    
  809.     tags.scen = {
  810.     ["levels\\a10\\devices\\h oxy tank\\h oxy tank"] = "Oxygen Tank",
  811.     ["levels\\a10\\devices\\doors\\door_blast_collision\\door_blast_collision"] = "Door Blast Collision",
  812.     ["levels\\b40\\scenery\\b40_doorblinker\\doorblinker"] = "Door Blinker",
  813.     ["levels\\b40\\scenery\\b40_metal_small\\metal_small"] = "Small Metal Scenery",
  814.     ["levels\\b40\\scenery\\b40_metal_tall\\metal_tall"] = "Tall Metal Scenery",
  815.     ["levels\\b40\\scenery\\b40_metal_wide\\metal_wide"] = "Wide Metal Scenery",
  816.     ["levels\\test\\dangercanyon\\scenery\\mp_tree_pine_small\\mp_tree_pine_small"] = "Small Pine Tree",
  817.     ["levels\\test\\timberland\\scenery\\mp_beacon_blue\\mp_beacon_blue"] = "Blue Beacon",
  818.     ["levels\\test\\timberland\\scenery\\mp_beacon_red\\mp_beacon_red"] = "Red Beacon",
  819.     ["levels\\test\\timberland\\scenery\\simple_beacon_blue\\simple_beacon_blue"] = "Simple Blue Beacon",
  820.     ["levels\\test\\timberland\\scenery\\simple_beacon_red\\simple_beacon_red"] = "Simple Red Beacon",
  821.     ["levels\\test\\timberland\\scenery\\mp_boulder_granite_gigantic\\mp_boulder_granite_gigantic"] = "Gigantic Granite Boulder",
  822.     ["levels\\test\\timberland\\scenery\\mp_boulder_granite_large\\mp_boulder_granite_large_00\\mp_boulder_granite_large_00"] = "Large Granite Boulder 00",
  823.     ["levels\\test\\timberland\\scenery\\mp_boulder_granite_large\\mp_boulder_granite_large_01\\mp_boulder_granite_large_01"] = "Large Granite Boulder 01",
  824.     ["levels\\test\\timberland\\scenery\\mp_boulder_granite_large\\mp_boulder_granite_large_02\\mp_boulder_granite_large_02"] = "Large Granite Boulder 02",
  825.     ["levels\\test\\timberland\\scenery\\mp_boulder_granite_large\\mp_boulder_granite_large_03\\mp_boulder_granite_large_03"] = "Large Granite Boulder 03",
  826.     ["levels\\test\\timberland\\scenery\\mp_boulder_granite_large\\mp_boulder_granite_large_04\\mp_boulder_granite_large_04"] = "Large Granite Boulder 04",
  827.     ["levels\\test\\timberland\\scenery\\mp_boulder_granite_medium\\mp_boulder_granite_medium"] = "Medium Granite Boulder",
  828.     ["levels\\test\\timberland\\scenery\\mp_boulder_moss_large\\mp_boulder_moss_large"] = "Large Mossy Boulder",
  829.     ["levels\\test\\timberland\\scenery\\mp_boulder_moss_small\\mp_boulder_moss_small"] = "Small Mossy Boulder",
  830.     ["levels\\test\\timberland\\scenery\\mp_tree_pine_tall\\mp_tree_pine_tall"] = "Tall Pine Tree",
  831.     ["levels\\test\\timberland\\scenery\\waterfall_spray_emitter_small\\waterfall_spray_emitter_small"] = "Small Waterfall",
  832.     ["levels\\test\\icefields\\scenery\\mp_boulder_snow_large_00\\mp_boulder_snow_large_00"] = "Large Snowy Boulder 00",
  833.     ["levels\\test\\icefields\\scenery\\mp_boulder_snow_large_01\\mp_boulder_snow_large_01"] = "Large Snowy Boulder 01",
  834.     ["levels\\test\\icefields\\scenery\\mp_boulder_snow_large_02\\mp_boulder_snow_large_02"] = "Large Snowy Boulder 02",
  835.     ["levels\\test\\icefields\\scenery\\mp_boulder_snow_large_03\\mp_boulder_snow_large_03"] = "Large Snowy Boulder 03",
  836.     ["levels\\test\\icefields\\scenery\\mp_boulder_snow_large_04\\mp_boulder_snow_large_04"] = "Large Snowy Boulder 04",
  837.     ["levels\\test\\icefields\\scenery\\mp_tree_pine_snow_small\\mp_tree_pine_snow_small"] = "Small Snowy Pine Tree",
  838.     ["levels\\test\\icefields\\scenery\\mp_tree_pine_snow_tall\\mp_tree_pine_snow_tall"] = "Tall Snowy Pine Tree",
  839.     ["scenery\\flag_base\\flag_base"] = "Flag Base",
  840.     ["scenery\\floor_arrow\\floor_arrow"] = "Floor Arrow",
  841.     ["scenery\\small beacon\\small blue beacon"] = "Small Blue Beacon",
  842.     ["scenery\\small beacon\\small red beacon"] = "Small Red Beacon",
  843.     ["scenery\\blue landing beacon\\blue landing beacon"] = "Blue Landing Beacon",
  844.     ["scenery\\teleporter_base\\teleporter_base"] = "Teleporter Base",
  845.     ["scenery\\teleporter_shield\\teleporter"] = "Teleporter Shield",
  846.     ["scenery\\h_barricade_large\\h_barricade_large"] = "Large Barricade",
  847.     ["scenery\\h_barricade_large_gap\\h_barricade_large_gap"] = "Large Buffered Barricade",
  848.     ["scenery\\h_barricade_small\\h_barricade_small"] = "Small Barricade",
  849.     ["scenery\\h_barricade_small_visor\\h_barricade_small_visor"] = "Small Visored Barricade",
  850.     ["scenery\\hilltop\\hilltop"] = "Hilltop",
  851.     ["scenery\\c_storage\\c_storage"] = "Covenant Storage",
  852.     ["scenery\\c_storage_large\\c_storage_large"] = "Large Covenant Storage",
  853.     ["scenery\\c_uplink\\c_uplink"] = "Covenant Uplink",
  854.     ["scenery\\c_field_generator\\c_field_generator"] = "Covenant Field Generator",
  855.     ["scenery\\emitters\\glowingdrip\\glowingdrip"] = "Glowing Drip",
  856.     ["scenery\\rocks\\a50_rock_large\\a50_rock_large"] = "Large Rock",
  857.     ["scenery\\rocks\\boulder\\boulder"] = "Boulder",
  858.     ["scenery\\rocks\\boulder_crouch\\boulder_crouch"] = "Crouch Boulder",
  859.     ["scenery\\rocks\\boulder_doublewide\\boulder_doublewide"] = "Doublewide Boulder",
  860.     ["scenery\\rocks\\boulder_large_grey\\boulder_large_grey"] = "Large Grey Boulder",
  861.     ["scenery\\rocks\\boulder_granite_gigantic\\boulder_granite_gigantic"] = "Gigantic Boulder",
  862.     ["scenery\\rocks\\boulder_granite_large\\boulder_granite_large"] = "Large Boulder",
  863.     ["scenery\\rocks\\boulder_granite_medium\\boulder_granite_medium"] = "Medium Boulder",
  864.     ["scenery\\rocks\\boulder_granite_small\\boulder_granite_small"] = "Small Boulder",
  865.     ["scenery\\rocks\\boulder_snow_small\\boulder_snow_small"] = "Small Snowy Boulder",
  866.     ["scenery\\rocks\\b40_snowrocks\\snowrock"] = "Snowy Rock",
  867.     ["scenery\\rocks\\b40_snowrocksmall\\snowrocksmall"] = "Small Snowy Rock",
  868.     ["scenery\\shrubs\\shrub_large\\shrub_large"] = "Large Shrub",
  869.     ["scenery\\plants\\plant fern\\plant fern"] = "Fern",
  870.     ["scenery\\plants\\plant_broadleaf_tall\\plant_broadleaf_tall"] = "Tall Broadleaf",
  871.     ["scenery\\plants\\plant_broadleaf_short\\plant_broadleaf_short"] = "Short Broadleaf",
  872.     ["scenery\\trees\\tree_desert_dead\\tree_desert_dead"] = "Dead Tree",
  873.     ["scenery\\trees\\tree_desert_whitebark\\tree_desert_whitebark"] = "Whitebark Tree",
  874.     ["scenery\\trees\\tree_leafy\\tree_leafy"] = "Leafy Tree",
  875.     ["scenery\\trees\\tree_leafy_medium\\tree_leafy_medium"] = "Medium Leafy Tree",
  876.     ["scenery\\trees\\tree_leafy_sapling\\tree_leafy_sapling"] = "Leafy Sapling Tree",
  877.     ["scenery\\trees\\tree_leafy_doublewide\\tree_leafy_doublewide"] = "Doublewide Leafy Tree",
  878.     ["scenery\\trees\\tree_leafydense_doublewide\\tree_leafydense_doublewide"] = "Doublewide Dense Leafy Tree",
  879.     ["scenery\\trees\\tree_leafy_fallentrunk\\tree_leafy_fallentrunk"] = "Fallen Trunk",
  880.     ["scenery\\trees\\tree_leafy_fallentrunk_short\\tree_leafy_fallentrunk_short"] = "Short Fallen Trunk",
  881.     ["scenery\\trees\\tree_leafy_stump\\tree_leafy_stump"] = "Stump",
  882.     ["scenery\\trees\\tree_leafy_stump_crouch\\tree_leafy_stump_crouch"] = "Crouch Stump"
  883.     }
  884.    
  885. -- Gametype Information --
  886.  
  887. require "lfs"
  888.  
  889. --[[ Gametypes Table ]]--
  890.  
  891.     gametypes = table.load("gametypes")
  892.  
  893. --[[ Script Tables ]]--
  894.  
  895.     scripts = table.load("scripts")
  896.    
  897. function formatbinary(num, digits)
  898.  
  899.     local binary = convertbase(num, 2)
  900.     while string.len(binary) < digits do
  901.         binary = "0" .. binary
  902.     end
  903.    
  904.     return binary
  905. end
  906.  
  907. function convertbase(input, base)
  908.  
  909.     if not base or base == 10 then return tostring(input) end
  910.  
  911.     local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  912.     local answer = {}
  913.  
  914.     repeat
  915.         local digit = (input % base) + 1
  916.         input = math.floor(input / base)
  917.         table.insert(answer, 1, string.sub(digits, digit, digit))
  918.     until input == 0
  919.  
  920.     return table.concat(answer, "")
  921. end
  922.    
  923. -- Searches the specified table for the specified value.  Returns true or false.
  924. function table.find(t, value, anywhere)
  925.  
  926.     for k,v in pairs(t) do
  927.         if v == value then
  928.             return true
  929.         end
  930.         if anywhere then
  931.             if k == value then
  932.                 return true
  933.             end
  934.         end
  935.     end
  936.  
  937.     return false
  938. end
  939.  
  940. function string.split(str, ...)
  941.  
  942.     local subs = {}
  943.     local sub = ""
  944.     local i = 1
  945.  
  946.     for _,v in ipairs(arg) do
  947.         if v == "" then
  948.             for x = 1, string.len(str) do
  949.                 table.insert(subs, string.sub(str, x, x))
  950.             end
  951.  
  952.             return subs
  953.         end
  954.     end
  955.  
  956.     for _,v in ipairs(arg) do
  957.         if string.sub(str, 1, 1) == v then
  958.             table.insert(subs, "")
  959.             break
  960.         end
  961.     end
  962.  
  963.     while i <= string.len(str) do
  964.  
  965.         local bool, bool2
  966.  
  967.         for x = 1, #arg do
  968.             if arg[x] ~= "" then
  969.                 local length = string.len(arg[x])
  970.                 if string.sub(str, i, i + (length - 1)) == arg[x] then
  971.                     if i == string.len(str) then
  972.                         bool2 = true
  973.                     else
  974.                         bool = true
  975.                     end
  976.  
  977.                     i = i + (length - 1)
  978.                     break
  979.                 end
  980.             else
  981.                 for q = 1, string.len(str) do
  982.                     subs = {}
  983.                     table.insert(subs, string.sub(str, q, q))
  984.                     i = string.len(str)
  985.                     break
  986.                 end
  987.             end
  988.         end
  989.  
  990.         if not bool then
  991.             sub = sub .. string.sub(str, i, i)
  992.         end
  993.  
  994.         if bool or i == string.len(str) then
  995.             if sub ~= "" then
  996.                 table.insert(subs, sub)
  997.                 sub = ""
  998.             end
  999.         end
  1000.  
  1001.         if bool2 then
  1002.             table.insert(subs, "")
  1003.         end
  1004.  
  1005.         i = i + 1
  1006.     end
  1007.  
  1008.     for k,v in ipairs(subs) do
  1009.         for _,d in ipairs(arg) do
  1010.             subs[k] = string.gsub(v, d, "")
  1011.         end
  1012.     end
  1013.  
  1014.     return subs
  1015. end
  1016.  
  1017. function LoadScripts()
  1018.  
  1019.     local dir = getprofilepath() .. "\\scripts\\"
  1020.     for f in lfs.dir(dir) do
  1021.         if string.find(f, ".lua") then
  1022.             local file = io.open(dir .. f, "r")
  1023.             local str = file:read("*all")
  1024.             if string.find(str, "function GetRequiredVersion()") then
  1025.                 if f ~= "gametypes.lua" then
  1026.                     local script = string.gsub(f, ".lua", "")
  1027.                     if not table.find(scripts, script) then
  1028.                         table.insert(scripts, script)
  1029.                     end
  1030.                 end
  1031.             end
  1032.         end
  1033.     end
  1034. end
  1035.  
  1036. function LoadGametypes()
  1037.  
  1038.     local dir = getprofilepath() .. "\\savegames\\"
  1039.     local directories = {}
  1040.     local files = {}
  1041.     for f in lfs.dir(dir) do
  1042.         if f ~= "." and f ~= ".." then
  1043.             if lfs.attributes(dir .. f, "mode") == "file" then
  1044.                 table.insert(files, dir .. f)
  1045.             elseif lfs.attributes(dir .. f, "mode") == "directory" then
  1046.                 table.insert(directories, dir .. f)
  1047.             end
  1048.         end
  1049.     end
  1050.    
  1051.     local defdir = getprofilepath() .. "\\saved\\playlists\\default_playlist\\"
  1052.     for f in lfs.dir(defdir) do
  1053.         if f ~= "." and f ~= ".." then
  1054.             if lfs.attributes(defdir .. f, "mode") == "file" then
  1055.                 table.insert(files, defdir .. f)
  1056.             elseif lfs.attributes(defdir .. f, "mode") == "directory" then
  1057.                 table.insert(directories, defdir .. f)
  1058.             end
  1059.         end
  1060.     end
  1061.    
  1062.     for k,v in ipairs(directories) do
  1063.         local dirs = string.split(v, "\\")
  1064.         local gtname = dirs[#dirs]
  1065.         if not gametypes[gtname] then
  1066.             for f in lfs.dir(v) do
  1067.                 if f == "blam.lst" then
  1068.                     local blam = io.open(v .. "\\blam.lst", "r")
  1069.                     local str = blam:read("*all")
  1070.                     local chars = string.split(str, "")
  1071.                     local name = readgame(chars, 0x0, 0x2F)
  1072.                     local gametype = tonumber(readgame(chars, 0x30, 0x33, true)) -- 1 = CTF | 2 = Slayer | 3 = Oddball | 4 = KOTH | 5 = Race
  1073.                     local teamplay = tonumber(readgame(chars, 0x34, 0x37, true)) -- 0 = off | 1 = on
  1074.                     local parameters = formatbinary(readgame(chars, 0x38, 0x3B, true), 8)
  1075.                     -- 0 = off | 1 = on
  1076.                     local players_on_radar = tonumber(string.sub(parameters, 8, 8))
  1077.                     local friend_indicators = tonumber(string.sub(parameters, 7, 7))
  1078.                     local infinite_grenades = tonumber(string.sub(parameters, 6, 6))
  1079.                     local shields = 1 - tonumber(string.sub(parameters, 5, 5))
  1080.                     local invisible_players = tonumber(string.sub(parameters, 4, 4))
  1081.                     local starting_equipment = tonumber(string.sub(parameters, 3, 3)) -- 0 = Generic | 1 = Custom
  1082.                     local only_friends_on_radar = tonumber(string.sub(parameters, 2, 2))
  1083.                     local objectives_indicator = tonumber(readgame(chars, 0x3C, 0x3F, true)) -- 0 = Motion Tracker | 1 = Navpoints | 2 = None
  1084.                     local odd_man_out = tonumber(readgame(chars, 0x40, 0x43, true)) -- 0 = off | 1 = on
  1085.                     local respawn_time_growth = tonumber(readgame(chars, 0x44, 0x47, true)) -- 0 = off | 150 = 5 secs | 300 = 10 secs | 450 = 15 secs
  1086.                     local respawn_time = tonumber(readgame(chars, 0x48, 0x4B, true)) -- 0 = Instant | 150 = 5 secs | 300 = 10 secs | 450 = 15 secs
  1087.                     local suicide_penalty = tonumber(readgame(chars, 0x4C, 0x4F, true)) -- 0 = None | 150 = 5 secs | 300 = 10 secs | 450 = 15 secs
  1088.                     local lives = tonumber(readgame(chars, 0x50, 0x53, true)) -- 0 = Unlimited lives | 1, 3, 5 = 1, 3, 5 lives
  1089.                    
  1090.                     local max_health = tonumber(readgame(chars, 0x57, 0x57, true)) -- 64 = 400% | 63 = 100% (Find others)
  1091.                    
  1092.                     local scorelimit = tonumber(readgame(chars, 0x58, 0x5B, true)) -- check how this is stored for timed gametypes
  1093.                     local weapon_set = tonumber(readgame(chars, 0x5C, 0x5F, true)) -- 0 = Normal | 1 = Pistols | 2 = Rifles | 3 = Plasma | 4 = Sniper | 5 = No Sniping | 6 = Rockets | 7 = Shotguns | 8 = Shortrange | 9 = Human | 10 = Covenant | 11 = Classic | 12 = Heavy
  1094.                    
  1095.                     -- Insert Vehicle Stuff Here --
  1096.                    
  1097.                     local friendly_fire = tonumber(readgame(chars, 0x6C, 0x6F, true)) -- 0 = off | 1 = on
  1098.                     local tk_penalty = tonumber(readgame(chars, 0x70, 0x73, true)) -- 0 = off | 150 = 5 secs | 300 = 10 secs | 450 = 15 secs
  1099.                     local team_balance = tonumber(readgame(chars, 0x74, 0x77, true)) -- 0 = off | 1 = on
  1100.                     local timelimit = tonumber(readgame(chars, 0x78, 0x7B, true)) -- 0 = No Timelimit | 18000 = 10 min | 27000 = 15 min | 36000 = 20 min | 45000 = 25 min | 54000 = 30 min | 81000 = 45 min
  1101.                     local assault = tonumber(readgame(chars, 0x7C, 0x7C, true)) -- 0 = CTF | 1 = Assault
  1102.                     local alternating = tonumber(readgame(chars, 0x81, 0x81, true)) -- 0 = Not Alternating | 14 = Alternating Assault | 35 = Alternating CTF (could have to do with single flag time)
  1103.                     local moving_hill = tonumber(readgame(chars, 0x7C, 0x7F, true)) -- 0 = off | 1 = on
  1104.                     local race_type = tonumber(readgame(chars, 0x7C, 0x7F, true)) -- 0 = Normal | 1 = Any Order | 2 = Rally
  1105.                     local oddball_random_start = tonumber(readgame(chars, 0x7C, 0x7F, true)) -- 0 = off | 1 = on                   
  1106.                     local oddball_speed = tonumber(readgame(chars, 0x80, 0x82, true)) -- 0 = Slow | 1 = Normal | 2 = Fast                  
  1107.                     local oddball_trait = tonumber(readgame(chars, 0x83, 0x83, true)) -- 0 = None | 1 = Invisible | 2 = Extra Damage | 3 = Damage Resistant
  1108.                     local no_oddball_trait = tonumber(readgame(chars, 0x88, 0x8B, true)) -- 0 = None | 1 = Invisible | 2 = Extra Damage | 3 = Damage Resistant
  1109.                     local oddball_type = tonumber(readgame(chars, 0x8C, 0x8C, true)) -- 0 = Normal | 1 = Reverse Tag | 2 = Juggernaut
  1110.                     local oddball_count = tonumber(readgame(chars, 0x90, 0x90, true)) -- From 0 - 16
  1111.                    
  1112.                     blam:close()
  1113.                    
  1114.                     local function getgame()
  1115.                         if gametype == 1 then
  1116.                             return "CTF"
  1117.                         elseif gametype == 2 then
  1118.                             return "Slayer"
  1119.                         elseif gametype == 3 then
  1120.                             return "Oddball"
  1121.                         elseif gametype == 4 then
  1122.                             return "KotH"
  1123.                         elseif gametype == 5 then
  1124.                             return "Race"
  1125.                         end
  1126.                     end
  1127.                    
  1128.                     local function getteamplay()
  1129.                    
  1130.                         if teamplay == 1 then
  1131.                             return true
  1132.                         end
  1133.                     end
  1134.                    
  1135.                     local function getallonradar()
  1136.                    
  1137.                         if players_on_radar == 1 then
  1138.                             return true
  1139.                         end
  1140.                     end
  1141.                    
  1142.                     local function getfriendindicators()
  1143.                    
  1144.                         if friend_indicators == 1 then
  1145.                             return true
  1146.                         end
  1147.                     end
  1148.                    
  1149.                     local function getinfgrenades()
  1150.                    
  1151.                         if infinite_grenades == 1 then
  1152.                             return true
  1153.                         end
  1154.                     end
  1155.                    
  1156.                     local function getshields()
  1157.                    
  1158.                         if shields == 1 then
  1159.                             return true
  1160.                         end
  1161.                     end
  1162.                    
  1163.                     local function getinvisibleplayers()
  1164.                    
  1165.                         if invisible_players == 1 then
  1166.                             return true
  1167.                         end
  1168.                     end
  1169.                    
  1170.                     local function getstarteqip()
  1171.                    
  1172.                         if starting_equipment == 1 then
  1173.                             return "Generic"
  1174.                         else
  1175.                             return "Custom"
  1176.                         end
  1177.                     end
  1178.                    
  1179.                     local function getfriendsonradar()
  1180.                    
  1181.                         if only_friends_on_radar == 1 then
  1182.                             return true
  1183.                         end
  1184.                     end
  1185.                    
  1186.                     local function getobjectivesindicator()
  1187.                    
  1188.                         if objectives_indicator == 0 then
  1189.                             return "Motion Tracker"
  1190.                         elseif objectives_indicator == 1 then
  1191.                             return "Navpoints"
  1192.                         elseif objectives_indicator == 2 then
  1193.                             return "None"
  1194.                         end
  1195.                     end
  1196.                    
  1197.                     local function getoddmanout()
  1198.                    
  1199.                         if odd_man_out == 1 then
  1200.                             return true
  1201.                         end
  1202.                     end
  1203.                    
  1204.                     local function getlives()
  1205.                    
  1206.                         if lives == 0 then
  1207.                             return "Unlimited"
  1208.                         else
  1209.                             return lives
  1210.                         end
  1211.                     end
  1212.                    
  1213.                     local function getmaxhealth()
  1214.                    
  1215.                         if max_health == 63 then
  1216.                             return 100
  1217.                         elseif max_health == 64 then
  1218.                             return 400
  1219.                         end
  1220.                     end
  1221.                    
  1222.                     local function getweaponset()
  1223.                    
  1224.                         if weapon_set == 0 then
  1225.                             return "Normal"
  1226.                         elseif weapon_set == 1 then
  1227.                             return "Pistols"
  1228.                         elseif weapon_set == 2 then
  1229.                             return "Rifles"
  1230.                         elseif weapon_set == 3 then
  1231.                             return "Plasmas"
  1232.                         elseif weapon_set == 4 then
  1233.                             return "Snipers"
  1234.                         elseif weapon_set == 5 then
  1235.                             return "No Sniping"
  1236.                         elseif weapon_set == 6 then
  1237.                             return "Rockets"
  1238.                         elseif weapon_set == 7 then
  1239.                             return "Shotguns"
  1240.                         elseif weapon_set == 8 then
  1241.                             return "Short-Range"
  1242.                         elseif weapon_set == 9 then
  1243.                             return "Human"
  1244.                         elseif weapon_set == 10 then
  1245.                             return "Covenant"
  1246.                         elseif weapon_set == 11 then
  1247.                             return "Classic"
  1248.                         elseif weapon_set == 12 then
  1249.                             return "Heavy"
  1250.                         end
  1251.                     end
  1252.                    
  1253.                     local function getfriendlyfire()
  1254.                    
  1255.                         if friendly_fire == 1 then
  1256.                             return true
  1257.                         end
  1258.                     end
  1259.                    
  1260.                     local function getteambalance()
  1261.                    
  1262.                         if team_balance == 1 then
  1263.                             return true
  1264.                         end
  1265.                     end
  1266.                    
  1267.                     local function getassault()
  1268.                    
  1269.                         if assault == 1 then
  1270.                             return true
  1271.                         end
  1272.                     end
  1273.                    
  1274.                     local function getalternating()
  1275.                    
  1276.                         if alternating ~= 0 then
  1277.                             return true
  1278.                         end
  1279.                     end
  1280.                    
  1281.                     local function getmovinghill()
  1282.                    
  1283.                         if moving_hill == 1 then
  1284.                             return true
  1285.                         end
  1286.                     end
  1287.                    
  1288.                     local function getracetype()
  1289.                    
  1290.                         if race_type == 0 then
  1291.                             return "Normal"
  1292.                         elseif race_type == 1 then
  1293.                             return "Any Order"
  1294.                         elseif race_type == 2 then
  1295.                             return "Rally"
  1296.                         end
  1297.                     end
  1298.                    
  1299.                     local function getoddballtype()
  1300.                    
  1301.                         if oddball_type == 0 then
  1302.                             return "Normal"
  1303.                         elseif oddball_type == 1 then
  1304.                             return "Reverse Tag"
  1305.                         elseif oddball_type == 2 then
  1306.                             return "Juggernaut"
  1307.                         end
  1308.                     end
  1309.                    
  1310.                     local function getballrandomstart()
  1311.                    
  1312.                         if oddball_random_start == 1 then
  1313.                             return true
  1314.                         end
  1315.                     end
  1316.                    
  1317.                     local function getoddballspeed()
  1318.                    
  1319.                         if oddball_speed == 0 then
  1320.                             return "Slow"
  1321.                         elseif oddball_speed == 1 then
  1322.                             return "Normal"
  1323.                         elseif oddball_speed == 2 then
  1324.                             return "Fast"
  1325.                         end
  1326.                     end
  1327.                    
  1328.                     local function getoddballtrait()
  1329.                    
  1330.                         if oddball_trait == 0 then
  1331.                             return "None"
  1332.                         elseif oddball_trait == 1 then
  1333.                             return "Invisible"
  1334.                         elseif oddball_trait == 2 then
  1335.                             return "Extra Damage"
  1336.                         elseif oddball_trait == 3 then
  1337.                             return "Damage Resistant"
  1338.                         end
  1339.                     end
  1340.                    
  1341.                     local function getnooddballtrait()
  1342.                    
  1343.                         if no_oddball_trait == 0 then
  1344.                             return "None"
  1345.                         elseif no_oddball_trait == 1 then
  1346.                             return "Invisible"
  1347.                         elseif no_oddball_trait == 2 then
  1348.                             return "Extra Damage"
  1349.                         elseif no_oddball_trait == 3 then
  1350.                             return "Damage Resistant"
  1351.                         end
  1352.                     end
  1353.                    
  1354.                     gametypes[name] = {}
  1355.                     gametypes[name].game = getgame()
  1356.                     gametypes[name].team = getteamplay()
  1357.                     gametypes[name].allonradar = getallonradar()
  1358.                     gametypes[name].friendindicators = getfriendindicators()
  1359.                     gametypes[name].infinitegrenades = getinfgrenades()
  1360.                     gametypes[name].shields = getshields()
  1361.                     gametypes[name].invisibleplayers = getinvisibleplayers()
  1362.                     gametypes[name].startingequipment = getstarteqip()
  1363.                     gametypes[name].friendsonradar = getfriendsonradar()
  1364.                     gametypes[name].objectivesindicator = getobjectivesindicator()
  1365.                     gametypes[name].oddmanout = getoddmanout()
  1366.                     gametypes[name].respawngrowth = respawn_time_growth / 30
  1367.                     gametypes[name].respawntime = respawn_time / 30
  1368.                     gametypes[name].suicidepenalty = suicide_penalty / 30
  1369.                     gametypes[name].lives = getlives()
  1370.                     gametypes[name].maxhealth = getmaxhealth()
  1371.                     gametypes[name].scorelimit = scorelimit
  1372.                     gametypes[name].weaponset = getweaponset()
  1373.                     gametypes[name].friendlyfire = getfriendlyfire()
  1374.                     gametypes[name].tkpenalty = tk_penalty / 30
  1375.                     gametypes[name].teambalance = getteambalance()
  1376.                     gametypes[name].timelimit = timelimit / 1800
  1377.                     if gametypes[name].game == "CTF" then
  1378.                         gametypes[name].assault = getassault()
  1379.                         gametypes[name].alternating = getalternating()
  1380.                     elseif gametypes[name].game == "KotH" then
  1381.                         gametypes[name].movinghill = getmovinghill()
  1382.                     elseif gametypes[name].game == "Race" then
  1383.                         gametypes[name].racetype = getracetype()
  1384.                     elseif gametypes[name].game == "Oddball" then
  1385.                         gametypes[name].oddballtype = getoddballtype()
  1386.                         gametypes[name].randomstart = getballrandomstart()
  1387.                         gametypes[name].oddballspeed = getoddballspeed()
  1388.                         gametypes[name].oddballtrait = getoddballtrait()
  1389.                         gametypes[name].nooddballtrait = getnooddballtrait()
  1390.                         gametypes[name].oddballcount = oddball_count
  1391.                     end
  1392.                 end
  1393.             end
  1394.         end
  1395.     end
  1396. end
  1397.  
  1398. function readgame(chars, first, last, byte)
  1399.  
  1400.     first = first + 1
  1401.     last = last + 1
  1402.     local str = ""
  1403.     for i = first, last do
  1404.         if string.byte(chars[i]) ~= 0 then
  1405.             str = str .. chars[i]
  1406.         end
  1407.     end
  1408.    
  1409.     if byte then
  1410.         if str ~= "" then
  1411.             return string.byte(str)
  1412.         else
  1413.             return 0
  1414.         end
  1415.     end
  1416.    
  1417.     return str
  1418. end
  1419.    
  1420. -- Messages --
  1421.  
  1422.     messages = {}
  1423.    
  1424. -- Values --
  1425.  
  1426.     values = table.load("values") or {}
  1427.  
  1428. --[[ Global Booleans ]]--
  1429.  
  1430.     execute_original = false
  1431.     noprintcmd = false
  1432.  
  1433. --[[ Global Variables ]]--
  1434.  
  1435.     gametype_base = 0x671340
  1436.     teamplay = readbyte(gametype_base, 0x34)
  1437.     this = {}
  1438.    
  1439. -- Loading --
  1440.  
  1441.     LoadScripts()
  1442.     LoadGametypes()
  1443.  
  1444. function GetRequiredVersion()
  1445.  
  1446.     return 10058
  1447. end
  1448.  
  1449. function OnScriptLoad(process)
  1450.  
  1451.     hprinttimer = registertimer(334, "HprintTimer", 334)
  1452.     registertimer(1000, "BanTimer")
  1453.    
  1454.     local file = io.open("lastman", "r")
  1455.     if file then
  1456.         previous_lastman = file:read("*line")
  1457.         file:close()
  1458.     end
  1459.     os.remove("lastman")
  1460. end
  1461.  
  1462. function OnScriptUnload()
  1463.  
  1464.     if lastman_hash then
  1465.         local file = io.open("lastman", "w")
  1466.         file:write(lastman_hash)
  1467.         file:close()
  1468.     end
  1469.  
  1470.     for k,v in pairs(mute_table) do
  1471.         if tonumber(k, 16) then
  1472.             if mute_table[k].muted then
  1473.                 if mute_table[k].duration >= -1 then
  1474.                     unmute(k)
  1475.                     mutelog(k, "Unmuted at End of Game by SERVER")
  1476.                 end
  1477.             end
  1478.             mute_table[k].swears.count = 0
  1479.             mute_table[k].swears.game = 0
  1480.         end
  1481.     end
  1482.  
  1483.     table.save(mute_table, "mutelist")
  1484.  
  1485.     local swear_save = {}
  1486.     swear_save.exact = sweartable.exact
  1487.     swear_save.anywhere = sweartable.anywhere
  1488.     swear_save.automute = automute
  1489.     swear_save.tomute = swears_to_mute
  1490.     swear_save.action = swear_action
  1491.     swear_save.append = swear_append
  1492.     swear_save.message = swear_message
  1493.     swear_save.penalty = swear_penalty
  1494.     swear_save.mutenotify = notify_of_mutes
  1495.     table.save(swear_save, "sweartable")
  1496.  
  1497.     for k,v in pairs(players.recent) do
  1498.         players.recent[k] = players.recent[k] - 1
  1499.         if players.recent[k] <= 0 then
  1500.             players.recent[k] = nil
  1501.             players[k].name = mostUsedAlias(k)
  1502.         end
  1503.     end
  1504.  
  1505.     table.save(players, "players")
  1506.     table.save(banned, "banlist")
  1507. end
  1508.  
  1509. function OnNewGame(map)
  1510.  
  1511.     this.map = map
  1512.     this.gametype = readstring(gametype_base, 0x0, 0x2C)
  1513.    
  1514.     updateAdmins()
  1515.     updateBanlist()
  1516.    
  1517.     registertimer(1000, "BeginGame")
  1518.     if anti_block then
  1519.         registertimer(50, "AntiBlock", map)
  1520.     end
  1521. end
  1522.  
  1523. function OnGameEnd(mode)
  1524.  
  1525.  
  1526. end
  1527.  
  1528. function OnServerChat(player, chattype, message)
  1529.  
  1530.     local hash = gethash(player)
  1531.  
  1532.     -- If you want to change the order of importance of the following blocks of code, place the most important first and least important last.
  1533.     -- For example, Admin Chat Commands comes first so even when an admin is muted, he/she can use commands.  He/she may also use admin commands that contain swears.
  1534.     -- If you don't want the Swear Filter to affect Private Chat, just cut and paste the Private Chat (and Message Tokenization) code above the Swear Check.
  1535.  
  1536.     -- Admin Checking
  1537.     if isAdmin(player) then
  1538.  
  1539.         -- Admin Chat Commands
  1540.         local cmd, args = ParseCommand(message)
  1541.         local cmd_words = {cmd, unpack(args)}
  1542.  
  1543.         if #cmd_words > 0 then
  1544.             if validCommand(cmd) then
  1545.                 chat[gethash(player)] = true
  1546.                 svcmd(message, player)
  1547.                 chat[gethash(player)] = nil
  1548.                 return 0
  1549.             end
  1550.         end
  1551.     end
  1552.  
  1553.     -- Mute Check
  1554.     if mute_table[hash].muted then
  1555.         if mute_table[hash].duration < 0 then
  1556.             privatesay(player, mute_table[hash].message)
  1557.         else
  1558.             privatesay(player, mute_table[hash].message .. " (" .. mute_table[hash].duration .. " seconds left)")
  1559.         end
  1560.         return 0
  1561.     end
  1562.  
  1563.     -- Swear Check
  1564.     local swears = getSwears(message)
  1565.     if swears then
  1566.         if swear_action > 0 then
  1567.             swear(player, swears)
  1568.             if swear_action == 1 then
  1569.                 return 0
  1570.             else
  1571.                 local appended = appendMessage(message, swears)
  1572.                 if not mute_table[hash].muted then
  1573.                     return appended
  1574.                 else
  1575.                     return 0
  1576.                 end
  1577.             end
  1578.         end
  1579.     end
  1580.  
  1581.     -- Message Tokenization
  1582.     local words = string.split(message, " ")
  1583.     local chatcmd = words[1]
  1584.  
  1585.     -- Private Chat
  1586.     if string.sub(chatcmd, 1, 1) == "@" and tonumber(string.sub(chatcmd, 2, string.len(chatcmd))) then
  1587.         local receivernum = tonumber(string.sub(chatcmd, 2, string.len(chatcmd)))
  1588.         local receiver = rresolveplayer(receivernum)
  1589.         local sendernum = resolveplayer(player)
  1590.         local sender = player
  1591.         if gethash(receiver) then
  1592.             if gethash(sender) then
  1593.                 local privatemessage = table.concat(words, " ", 2, #words)
  1594.                 hprint(sender, "to " .. getname(receiver) .. ": (" .. receivernum .. ") " .. privatemessage, 15)
  1595.                 hprint(receiver, getname(sender) .. ": (" .. sendernum .. ") " .. privatemessage, 15)
  1596.                 privatesay(sender, "Message sent.")
  1597.             end
  1598.         else
  1599.             privatesay(sender, "There is no player with an ID of " .. receivernum .. ".")
  1600.         end
  1601.  
  1602.         return 0
  1603.     end
  1604.  
  1605.     -- Chat Commands
  1606.     if message == "cls" then
  1607.         if hash then
  1608.             messages[hash] = {}
  1609.             privatesay(player, "Messages cleared.")
  1610.             return 0
  1611.         end
  1612.     end
  1613.    
  1614.     return 1
  1615. end
  1616.  
  1617. function OnServerCommand(player, command)
  1618.  
  1619.     local hash = gethash(player)
  1620.  
  1621.     if hash then
  1622.         messages[hash] = {}
  1623.     end
  1624.  
  1625.     -- Admin Checking
  1626.     if isAdmin(player) or noAdmins() then
  1627.  
  1628.         local allow = 1
  1629.  
  1630.         if not execute_original then
  1631.             --local tokens = getcmdtokens(command)
  1632.             local cmd, args = ParseCommand(command)
  1633.             local tokens = {cmd, unpack(args)}
  1634.  
  1635.             if #tokens > 0 then
  1636.                 if validCommand(cmd) then
  1637.                     if canExecute(player, cmd) then
  1638.                         local executed = Command(player, cmd, tokens)
  1639.                         if not executed then
  1640.                             console(getSyntax(cmd) or "<Need a syntax entry here>")
  1641.                         end
  1642.                     else
  1643.                         console("You are not authorized to use this command.")
  1644.                     end
  1645.  
  1646.                     allow = 0
  1647.                 end
  1648.             end
  1649.         end
  1650.  
  1651.         if not noprintcmd then
  1652.             if #sprint > 0 then
  1653.                 for _,v in ipairs(sprint) do
  1654.                     say(v)
  1655.                 end
  1656.             else
  1657.                 if pprint[player] then
  1658.                     if #pprint[player] > 0 then
  1659.                         for _,v in ipairs(pprint[player]) do
  1660.                             hprint(player, v, 10)
  1661.                         end
  1662.                     else
  1663.                         for _,v in ipairs(cprint) do
  1664.                             if gethash(player) then
  1665.                                 if chat[gethash(player)] then
  1666.                                     hprint(player, v, #cprint * 4)
  1667.                                 else
  1668.                                     hprintf(v, player)
  1669.                                 end
  1670.                             else
  1671.                                 hprintf(v)
  1672.                             end
  1673.                         end
  1674.                     end
  1675.                 else
  1676.                     for _,v in ipairs(cprint) do
  1677.                         hprintf(v)
  1678.                     end
  1679.                 end
  1680.             end
  1681.         end
  1682.  
  1683.         sprint = {}
  1684.         cprint = {}
  1685.  
  1686.         for k,v in pairs(pprint) do
  1687.             pprint[k] = {}
  1688.         end
  1689.  
  1690.         execute_original = false
  1691.  
  1692.         return allow
  1693.     end
  1694.  
  1695.     hprintf("You are not an administrator in this server.")
  1696.     return 0
  1697. end
  1698.  
  1699. function OnTeamDecision(team)
  1700.  
  1701.     return zombie_team
  1702. end
  1703.  
  1704. function OnPlayerJoin(player, team)
  1705.  
  1706.     messages[gethash(player)] = {}
  1707.     updatePlayer(player)
  1708.    
  1709.     cur_players = cur_players + 1
  1710.  
  1711.     local hash = gethash(player)
  1712.     table.insert(cur_hashes, hash)
  1713.  
  1714.     privatesay(player, welcome_message)
  1715.    
  1716.     if game_begin then
  1717.         if cur_players == 1 then
  1718.             changeteam(player, human_team)
  1719.         else
  1720.             if no_zombies then
  1721.                 changeteam(player, zombie_team)
  1722.                 removetimer(nozombiestimer)
  1723.                 no_zombies = false
  1724.             else
  1725.                 if hashes[hash] then
  1726.                     changeteam(player, hashes[hash])
  1727.                 end
  1728.             end
  1729.         end
  1730.  
  1731.         local team = getteam(player)
  1732.         if team == human_team then
  1733.             privatesay(player, human_message)
  1734.         else
  1735.             privatesay(player, zombie_message)
  1736.         end
  1737.  
  1738.         hashes[hash] = team
  1739.     end
  1740. end
  1741.  
  1742. function OnPlayerLeave(player, team)
  1743.  
  1744.     local hash = gethash(player)
  1745.     players[hash].lastseen = os.time()
  1746.    
  1747.     cur_players = cur_players - 1
  1748.  
  1749.     local hash = gethash(player)
  1750.     cur_hashes[hash] = nil
  1751.     hashes[hash] = team
  1752.    
  1753.     if cur_players > 0 then
  1754.         if getteamsize(zombie_team) == 0 then
  1755.             if cur_players > 1 then
  1756.                 say(no_zombies_left_message)
  1757.                 no_zombies = true
  1758.                 nozombiestimer = registertimer(2000, "NoZombiesTimer")
  1759.             end
  1760.         end
  1761.        
  1762.         if getteamsize(human_team) == 0 then
  1763.             svcmd("sv_map_next")
  1764.         end
  1765.     else
  1766.         if nozombiestimer then
  1767.             removetimer(nozombiestimer)
  1768.             no_zombies = false
  1769.         end
  1770.     end
  1771. end
  1772.  
  1773. function OnPlayerKill(killer, victim, mode)
  1774.  
  1775.     if game_begin then
  1776.         if getteam(victim) == human_team then
  1777.             if mode == 0 then
  1778.                 if infected_by_server then
  1779.                     zombify(victim)
  1780.                 end
  1781.             elseif mode == 1 then
  1782.                 if infected_by_fall then
  1783.                     zombify(victim)
  1784.                 end
  1785.             elseif mode == 2 then
  1786.                 if infected_by_guardians then
  1787.                     zombify(victim)
  1788.                 end
  1789.             elseif mode == 3 then
  1790.                 if infected_by_vehicle then
  1791.                     zombify(victim)
  1792.                 end
  1793.             elseif mode == 4 then
  1794.                 if infected_by_zombie then
  1795.                     zombify(victim)
  1796.                 end
  1797.             elseif mode == 5 then
  1798.                 if infected_by_betrayal then
  1799.                     zombify(killer)
  1800.                 end
  1801.             elseif mode == 6 then
  1802.                 if infected_by_suicide then
  1803.                     zombify(victim)
  1804.                 end
  1805.             end
  1806.         end
  1807.     end
  1808.    
  1809.     local hash = gethash(victim)
  1810.     if balls[hash] then
  1811.         destroyobject(balls[hash])
  1812.         balls[hash] = nil
  1813.     end
  1814. end
  1815.  
  1816. function OnKillMultiplier(player, multiplier)
  1817.  
  1818.  
  1819. end
  1820.  
  1821. function OnPlayerSpawn(player, m_objId)
  1822.  
  1823.     local hash = gethash(player)
  1824.     local team = getteam(player)
  1825.     local m_object = getobject(m_objId)
  1826.  
  1827.     -- Speed
  1828.     if team == human_team then
  1829.         setspeed(player, human_speed)
  1830.     else
  1831.         setspeed(player, zombie_speed)
  1832.         if zombies_invisible then
  1833.             applycamo(player, 0)
  1834.         end
  1835.     end
  1836.    
  1837.     -- Zombie Camo
  1838.     if team == zombie_team then
  1839.         if zombies_invisible then
  1840.             applycamo(player, 0)
  1841.         end
  1842.     end
  1843.  
  1844.     -- Weapons
  1845.     if game_begin then
  1846.         if team == human_team then
  1847.             if #human_weapons == 1 and human_weapons[1] == "weapons\\ball\\ball" then
  1848.                 balls[hash] = readdword(m_object, 0x2F8)
  1849.             end
  1850.         else
  1851.             if #zombie_weapons == 1 and zombie_weapons[1] == "weapons\\ball\\ball" then
  1852.                 balls[hash] = readdword(m_object, 0x2F8)
  1853.             end
  1854.         end
  1855.     end
  1856.    
  1857.     for i = 0,1 do
  1858.         local m_weapId = readdword(m_object, 0x2F8 + i * 4)
  1859.         local m_weapon = getobject(m_weapId)
  1860.         if team == human_team then
  1861.             if human_weapons[i + 1] then
  1862.                 if human_ammo[i + 1] then
  1863.                     writeword(m_weapon, 0x2B6, human_ammo[i + 1])
  1864.                     writeword(m_weapon, 0x240, (1 - human_ammo[i + 1] / 100))
  1865.                 end
  1866.                 if human_clip[i + 1] then
  1867.                     writeword(m_weapon, 0x2B8, human_clip[i + 1])
  1868.                 end
  1869.                 updateammo(m_weapId)
  1870.             end
  1871.         else
  1872.             if zombie_weapons[i + 1] then
  1873.                 if zombie_ammo[i + 1] then
  1874.                     writeword(m_weapon, 0x2B6, zombie_ammo[i + 1])
  1875.                     writeword(m_weapon, 0x240, (1 - zombie_ammo[i + 1] / 100))
  1876.                 end
  1877.                 if zombie_clip[i + 1] then
  1878.                     writeword(m_weapon, 0x2B8, zombie_clip[i + 1])
  1879.                 end
  1880.                 updateammo(m_weapId)
  1881.             end
  1882.         end
  1883.     end
  1884.        
  1885.     --[[for i = 3,0,-1 do
  1886.         local m_weapId = readdword(m_object, 0x2F8 + i * 4)
  1887.         local m_weapon = getobject(m_weapId)
  1888.         if team == human_team then
  1889.             if human_weapons[i + 1] ~= "" and human_weapons[i + 1] then
  1890.                 if m_weapon then
  1891.                     destroyobject(m_weapId)
  1892.                 end
  1893.                
  1894.                 local m_objId = createobject("weap", human_weapons[i + 1], 0, 30, false, 0, 0, 0)
  1895.                 local m_object = getobject(m_objId)
  1896.                 registertimer((i * 1000) + 10, "DelayAssign", player, m_objId, i + 1)
  1897.                
  1898.             elseif not human_weapons[i + 1] then
  1899.                 if m_weapon then
  1900.                     destroyobject(m_weapId)
  1901.                 end
  1902.             else
  1903.                 if human_ammo[i + 1] then
  1904.                     writeword(m_weapon, 0x2B6, human_ammo[i + 1])
  1905.                     writefloat(m_weapon, 0x240, (1 - human_ammo[i + 1] / 100))
  1906.                 end
  1907.                 if human_clip[i + 1] then
  1908.                     writeword(m_weapon, 0x2B8, human_clip[i + 1])
  1909.                 end
  1910.  
  1911.                 updateammo(m_weapId)
  1912.             end
  1913.         else
  1914.             if zombie_weapons[i + 1] ~= "" and zombie_weapons[i + 1] then
  1915.                 if m_weapon then
  1916.                     destroyobject(m_weapId)
  1917.                 end
  1918.                
  1919.                 local m_objId = createobject("weap", human_weapons[i + 1], 0, 30, false, 0, 0, 0)
  1920.                 local m_object = getobject(m_objId)
  1921.                 registertimer((i * 1000) + 10, "DelayAssign", player, m_objId, i + 1)
  1922.                
  1923.             elseif not zombie_weapons[i + 1] then
  1924.                 if m_weapon then
  1925.                     destroyobject(m_weapId)
  1926.                 end
  1927.             else
  1928.                 if zombie_ammo[i + 1] then
  1929.                     writeword(m_weapon, 0x2B6, zombie_ammo[i + 1])
  1930.                     writefloat(m_weapon, 0x240, (1 - zombie_ammo[i + 1] / 100))
  1931.                 end
  1932.                 if zombie_clip[i + 1] then
  1933.                     writeword(m_weapon, 0x2B8, zombie_clip[i + 1])
  1934.                 end
  1935.  
  1936.                 updateammo(m_weapId)
  1937.             end
  1938.         end
  1939.     end--]]
  1940.  
  1941.     -- Grenades
  1942.     if game_begin then
  1943.         if team == human_team then
  1944.             if human_frags then
  1945.                 writebyte(m_object, 0x31E, human_frags)
  1946.             end
  1947.             if human_plasmas then
  1948.                 writebyte(m_object, 0x31F, human_plasmas)
  1949.             end
  1950.         elseif team == zombie_team then
  1951.             if zombie_frags then
  1952.                 writebyte(m_object, 0x31E, zombie_frags)
  1953.             end
  1954.             if zombie_plasmas then
  1955.                 writebyte(m_object, 0x31F, zombie_plasmas)
  1956.             end
  1957.         end
  1958.     else
  1959.         writebyte(m_object, 0x31E, 0)
  1960.         writebyte(m_object, 0x31F, 0)
  1961.     end
  1962. end
  1963.  
  1964. function OnPlayerSpawnEnd(player, m_objId)
  1965.  
  1966.    
  1967. end
  1968.  
  1969. function OnTeamChange(relevant, player, cur_team, dest_team)
  1970.  
  1971.     if not no_zombies then
  1972.         return 0
  1973.     else
  1974.         removetimer(nozombiestimer)
  1975.         no_zombies = false
  1976.         say(no_zombies_team_change_message)
  1977.         return 1
  1978.     end
  1979. end
  1980.  
  1981. function OnObjectCreation(m_objId, player, tagName)
  1982.  
  1983.     newObject(m_objId)
  1984. end
  1985.  
  1986. function OnObjectDestruction(m_objId, tagType, tagName)
  1987.  
  1988.  
  1989. end
  1990.  
  1991. function OnObjectInteraction(player, m_objId, tagType, tagName)
  1992.    
  1993.     local team = getteam(player)
  1994.     local hash = gethash(player)
  1995.     if m_objId == balls[hash] then
  1996.         assignweapon(player, m_objId)
  1997.     end
  1998.     if team == human_team then
  1999.         if table.find(human_blocked, tagName) then
  2000.             return 0
  2001.         end
  2002.     else
  2003.         if table.find(zombie_blocked, tagName) then
  2004.             return 0
  2005.         end
  2006.     end
  2007.  
  2008.     return 1
  2009. end
  2010.  
  2011. function OnWeaponAssignment(player, m_objId, slot, tagName)
  2012.    
  2013.         local team = getteam(player)
  2014.     if team == human_team then
  2015.         if human_weapons[slot + 1] == "" then
  2016.             return 0
  2017.         elseif human_weapons[slot + 1] then
  2018.             return lookuptag("weap", human_weapons[slot + 1])
  2019.         else
  2020.             return lookuptag("weap", human_weapons[1])
  2021.         end
  2022.     else
  2023.         if zombie_weapons[slot + 1] == "" then
  2024.             return 0
  2025.         elseif zombie_weapons[slot + 1] then
  2026.             return lookuptag("weap", zombie_weapons[slot + 1])
  2027.         else
  2028.             return lookuptag("weap", zombie_weapons[1])
  2029.         end
  2030.     end
  2031. end
  2032.  
  2033. function OnWeaponReload(player, m_weapId)
  2034.  
  2035.     return 1
  2036. end
  2037.  
  2038. function OnDamageLookup(receiver, causer, tagData, tagName)
  2039.  
  2040.     local c_player = objecttoplayer(causer)
  2041.     if c_player then
  2042.         local c_hash = gethash(c_player)
  2043.         local c_team = getteam(c_player)
  2044.         local min_damage = readfloat(tagData, 0x1D0)
  2045.         local med_damage = readfloat(tagData, 0x1D4)
  2046.         local max_damage = readfloat(tagData, 0x1D8)
  2047.         if c_team == human_team then
  2048.             if c_hash ~= lastman_hash then
  2049.                 writefloat(tagData, 0x1D0, min_damage * human_damage)
  2050.                 writefloat(tagData, 0x1D4, med_damage * human_damage)
  2051.                 writefloat(tagData, 0x1D8, max_damage * human_damage)
  2052.             else
  2053.                 writefloat(tagData, 0x1D0, min_damage * lastman_damage)
  2054.                 writefloat(tagData, 0x1D4, med_damage * lastman_damage)
  2055.                 writefloat(tagData, 0x1D8, max_damage * lastman_damage)
  2056.             end
  2057.         else
  2058.             if string.find(tagName, "melee") then
  2059.                 writefloat(tagData, 0x1D0, zombie_melee_damage)
  2060.                 writefloat(tagData, 0x1D4, zombie_melee_damage)
  2061.                 writefloat(tagData, 0x1D8, zombie_melee_damage)
  2062.             else
  2063.                 writefloat(tagData, 0x1D0, zombie_damage)
  2064.                 writefloat(tagData, 0x1D4, zombie_damage)
  2065.                 writefloat(tagData, 0x1D8, zombie_damage)
  2066.             end
  2067.         end
  2068.     end
  2069.  
  2070.     local r_player = objecttoplayer(receiver)
  2071.     if r_player then
  2072.         local r_hash = gethash(r_player)
  2073.         local r_team = getteam(r_player)
  2074.         local min_edit = readfloat(tagData, 0x1D0)
  2075.         local med_edit = readfloat(tagData, 0x1D4)
  2076.         local max_edit = readfloat(tagData, 0x1D8)
  2077.         if r_team == human_team then
  2078.             if r_hash ~= lastman_hash then
  2079.                 if human_vitality then
  2080.                     writefloat(tagData, 0x1D0, min_edit / human_vitality)
  2081.                     writefloat(tagData, 0x1D4, med_edit / human_vitality)
  2082.                     writefloat(tagData, 0x1D8, max_edit / human_vitality)
  2083.                 end
  2084.             else
  2085.                 if lastman_vitality then
  2086.                     writefloat(tagData, 0x1D0, min_edit / lastman_vitality)
  2087.                     writefloat(tagData, 0x1D4, med_edit / lastman_vitality)
  2088.                     writefloat(tagData, 0x1D8, max_edit / lastman_vitality)
  2089.                 end
  2090.             end
  2091.         else
  2092.             if zombie_vitality then
  2093.                 writefloat(tagData, 0x1D0, min_edit / zombie_vitality)
  2094.                 writefloat(tagData, 0x1D4, med_edit / zombie_vitality)
  2095.                 writefloat(tagData, 0x1D8, max_edit / zombie_vitality)
  2096.             end
  2097.         end
  2098.     end
  2099. end
  2100.  
  2101. function OnVehicleEntry(relevant, player, m_vehicleId, tagName, seat)
  2102.  
  2103.     local team = getteam(player)
  2104.     if team == human_team then
  2105.         if not human_vehicle then
  2106.             privatesay(player, vehicle_block_message)
  2107.             return 0
  2108.         end
  2109.     else
  2110.         if not zombie_vehicle then
  2111.             privatesay(player, vehicle_block_message)
  2112.             return 0
  2113.         end
  2114.     end
  2115.  
  2116.     return 1
  2117. end
  2118.  
  2119. function OnVehicleEject(player, forced)
  2120.  
  2121.     return 1
  2122. end
  2123.  
  2124. function OnClientUpdate(player, m_objId)
  2125.  
  2126.     for k,v in pairs(objects) do
  2127.         if k ~= "unique" then
  2128.             if not objects[k].destroyed then
  2129.                 if not getobject(k) then
  2130.                     objects[k].destroyed = true
  2131.                     OnObjectDestruction(k, objects[k].tagtype, objects[k].tagname)
  2132.                 end
  2133.             end
  2134.         end
  2135.     end
  2136. end
  2137.  
  2138. -- Infection Functions --
  2139.  
  2140. function BeginGame(id, count)
  2141.  
  2142.     if count < 5 then
  2143.         say("The game will begin in " .. 5 - count .. " seconds.")
  2144.     else
  2145.         local zombie_size = 0
  2146.         if cur_players > 1 then
  2147.             for i = 0,15 do
  2148.                 local hash = gethash(i)
  2149.                 if hash then
  2150.                     if hash == previous_lastman then
  2151.                         changeteam(i, zombie_team)
  2152.                         privatesay(i, zombie_message)
  2153.                         zombie_size = zombie_size + 1
  2154.                         break
  2155.                     end
  2156.                 end
  2157.             end
  2158.            
  2159.             for i in irand(0, 15) do
  2160.                 local hash = gethash(i)
  2161.                 if hash then
  2162.                     if hash ~= previous_lastman then
  2163.                         if starting_zombies >= 1 then
  2164.                             if zombie_size < starting_zombies then
  2165.                                 changeteam(i, zombie_team)
  2166.                                 privatesay(i, zombie_message)
  2167.                                 zombie_size = zombie_size + 1
  2168.                             else
  2169.                                 changeteam(i, human_team)
  2170.                                 privatesay(i, human_message)
  2171.                             end
  2172.                         else
  2173.                             if zombie_size / cur_players < starting_zombies then
  2174.                                 changeteam(i, zombie_team)
  2175.                                 privatesay(i, zombie_message)
  2176.                                 zombie_size = zombie_size + 1
  2177.                             else
  2178.                                 changeteam(i, human_team)
  2179.                                 privatesay(i, human_message)
  2180.                             end
  2181.                         end
  2182.                     end
  2183.                 end
  2184.             end
  2185.         else
  2186.             for i = 0,15 do
  2187.                 if gethash(i) then
  2188.                     changeteam(i, human_team)
  2189.                     privatesay(human_message)
  2190.                     break
  2191.                 end
  2192.             end
  2193.         end
  2194.        
  2195.         for i = 0,15 do
  2196.             if gethash(i) then
  2197.                 local m_player = getplayer(i)
  2198.                 local m_objId = readdword(m_player, 0x34)
  2199.                 local m_object = getobject(m_objId)
  2200.                 if m_object then
  2201.                     destroyobject(m_objId)
  2202.                 end
  2203.             end
  2204.         end
  2205.        
  2206.         game_begin = true
  2207.         return 0
  2208.     end
  2209.    
  2210.     return 1
  2211. end
  2212.  
  2213. function DelayAssign(id, count, player, m_objId, slot)
  2214.  
  2215.     local team = getteam(player)
  2216.     local hash = gethash(player)
  2217.     local m_object = getobject(m_objId)
  2218.     if team == human_team then
  2219.         if #human_weapons == 1 and human_weapons[1] == "weapons\\ball\\ball" then
  2220.             balls[hash] = m_objId
  2221.         end
  2222.         if human_ammo[slot] then
  2223.             writeword(m_object, 0x2B6, human_ammo[slot])
  2224.             writefloat(m_object, 0x240, (1 - human_ammo[slot]) / 100)
  2225.         end
  2226.         if human_clip[slot] then
  2227.             writeword(m_object, 0x2B8, human_clip[slot])
  2228.         end
  2229.     else
  2230.         if #zombie_weapons == 1 and zombie_weapons[1] == "weapons\\ball\\ball" then
  2231.             balls[hash] = m_objId
  2232.         end
  2233.         if zombie_ammo[slot] then
  2234.             writeword(m_object, 0x2B6, zombie_ammo[slot])
  2235.             writefloat(m_object, 0x240, (1 - zombie_ammo[slot]) / 100)
  2236.         end
  2237.         if zombie_clip[slot] then
  2238.             writeword(m_object, 0x2B8, zombie_clip[slot])
  2239.         end
  2240.     end
  2241.  
  2242.     updateammo(m_objId)
  2243.     assignweapon(player, m_objId)
  2244.     return 0
  2245. end
  2246.  
  2247. function NoZombiesTimer(id, count)
  2248.  
  2249.     if count < 5 then
  2250.         say(no_zombies_timer_message .. " in " .. (10 - 2 * count) .. " seconds!")
  2251.     else
  2252.         changeteam(getrandomplayer(), zombie_team)
  2253.         return 0
  2254.     end
  2255.    
  2256.     return 1
  2257. end
  2258.  
  2259. block_coords = {}
  2260. block_coords.dangercanyon = {}
  2261. block_coords.dangercanyon[1] = {12, 3, -2.5, 0.9, 0.9, 0.9}
  2262. block_coords.dangercanyon[2] = {-12, 3, -2.5, 0.9, 0.9, 0.9}
  2263. block_coords.beavercreek = {}
  2264. block_coords.beavercreek[1] = {10.949, 20.900, 0.76, 0.1, 0.1, 2.2}
  2265. block_coords.beavercreek[2] = {17.918, 6.419, 1.045, 0.1, 0.1, 2.55}
  2266. block_coords.chillout = {}
  2267. block_coords.chillout[1] = {8, 5.672, 3.55, 2, 0.3, 1}
  2268.  
  2269. function AntiBlock(id, count, map)
  2270.  
  2271.     for i = 0,15 do
  2272.         local hash = gethash(i)
  2273.         if hash then
  2274.             local m_player = getplayer(i)
  2275.             local m_objId = readdword(m_player, 0x34)
  2276.             local m_object = getobject(m_objId)
  2277.             if m_object then
  2278.                 local bool
  2279.                 for k,v in ipairs(block_coords[map]) do
  2280.                     if inVolume(m_objId, unpack(v)) then
  2281.                         bool = true
  2282.                         local old_time
  2283.                         if not blocking[hash] then
  2284.                             old_time = 0
  2285.                             blocking[hash] = 0
  2286.                         else
  2287.                             old_time = blocking[hash]
  2288.                             blocking[hash] = blocking[hash] + 50
  2289.                         end
  2290.                         if old_time < block_time_warning and blocking[hash] >= block_time_warning then
  2291.                             if block_time_warning_message then
  2292.                                 privatesay(i, block_time_warning_message)
  2293.                             end
  2294.                         elseif old_time < block_time_action and blocking[hash] >= block_time_action then
  2295.                             if block_time_action_message then
  2296.                                 privatesay(i, block_time_action_message)
  2297.                             end
  2298.                             svcmd(string.gsub(block_action, "<player>", resolveplayer(i)))
  2299.                             if multiple_offense_action_amount then
  2300.                                 block_offenses[hash] = (block_offenses[hash] or 0) + 1
  2301.                                 if block_offenses[hash] >= multiple_offense_action_amount then
  2302.                                     if multiple_offense_action_message then
  2303.                                         privatesay(i, multiple_offense_action_message)
  2304.                                     end
  2305.                                     svcmd(string.gsub(multiple_offense_action, "<player>", resolveplayer(i)))
  2306.                                 end
  2307.                             end
  2308.                         end
  2309.                     end
  2310.                 end
  2311.                 if not bool then
  2312.                     blocking[hash] = nil
  2313.                 end
  2314.             end
  2315.         end
  2316.     end
  2317.                            
  2318.     return 1
  2319. end
  2320.  
  2321. function inVolume(m_objId, x, y, z, xd, yd, zd)
  2322.  
  2323.     local m_object = getobject(m_objId)
  2324.     if m_object then
  2325.         local ox, oy, oz = getobjectcoords(m_objId)
  2326.         local x_dist = math.abs(x - ox)
  2327.         local y_dist = math.abs(y - oy)
  2328.         local z_dist = math.abs(z - oz)
  2329.         if x_dist < xd and y_dist < yd and z_dist < zd then
  2330.             return true
  2331.         end
  2332.     end
  2333.    
  2334.     return false
  2335. end
  2336.  
  2337. function getrandomplayer()
  2338.  
  2339.     local players = {}
  2340.     for i = 0,15 do
  2341.         if gethash(i) then
  2342.             table.insert(players, i)
  2343.         end
  2344.     end
  2345.    
  2346.     if unpack(players) then
  2347.         return players[getrandomnumber(1, #players + 1)]
  2348.     end
  2349. end
  2350.  
  2351. function zombify(player)
  2352.  
  2353.     local hash = gethash(player)
  2354.     changeteam(player, false)
  2355.     hashes[hash] = zombie_team
  2356.     setspeed(player, zombie_speed)
  2357.     privatesay(player, zombie_message)
  2358.     say(getname(player) .. infected_message)
  2359.  
  2360.     if getteamsize(human_team) == 1 then
  2361.         OnLastMan()
  2362.     elseif getteamsize(human_team) == 0 then
  2363.         svcmd("sv_map_next")
  2364.     end
  2365. end
  2366.  
  2367. function changeteam(player, dest_team, killed)
  2368.  
  2369.     local cur_team = getteam(player)
  2370.     if cur_team ~= dest_team then
  2371.         phasor_changeteam(player, killed or false)
  2372.     end
  2373. end
  2374.  
  2375. function OnLastMan()
  2376.  
  2377.     for i = 0,15 do
  2378.         if getteam(i) == human_team then
  2379.             lastman_hash = gethash(i)
  2380.             local m_player = getplayer(i)
  2381.             local m_objId = readdword(m_player, 0x34)
  2382.             local m_object = getobject(m_objId)
  2383.             if m_object then
  2384.                 for i = 0,3 do
  2385.                     local m_weapId = readdword(m_object, 0x2F8 + i * 4)
  2386.                     local m_weapon = getobject(m_weapId)
  2387.                     local ammo = readword(m_object, 0x2B6)
  2388.                     local clip = readword(m_object, 0x2B8)
  2389.                     writeword(m_object, 0x2B6, lastman_ammo or ammo)
  2390.                     writeword(m_object, 0x2B8, lastman_clip or clip)
  2391.                 end
  2392.             end
  2393.             local frags = readbyte(m_object, 0x31E)
  2394.             local plasmas = readbyte(m_object, 0x31F)
  2395.             writebyte(m_object, 0x31E, lastman_frags or frags)
  2396.             writebyte(m_object, 0x31F, lastman_plasmas or plasmas)
  2397.             setspeed(i, lastman_speed)
  2398.             if lastman_invistime then
  2399.                 applycamo(i, lastman_invistime)
  2400.             end
  2401.             say(getname(i) .. lastman_message)
  2402.         end
  2403.     end
  2404. end
  2405.  
  2406. function irand(min, max)
  2407.  
  2408.     local u = {}
  2409.     for i = min,max do
  2410.         table.insert(u, i)
  2411.     end
  2412.     return function()
  2413.         if unpack(u) then
  2414.             local rand = getrandomnumber(1, #u + 1)
  2415.             local value = u[rand]
  2416.             table.remove(u, rand)
  2417.             return value
  2418.         end
  2419.     end
  2420. end
  2421.  
  2422. -- Player and Admin Functions --
  2423.  
  2424. -- Returns the hash of the specified index.
  2425. local function validIndex(id)
  2426.    
  2427.     if id then
  2428.         for k,_ in pairs(players) do
  2429.             if tonumber(k, 16) then
  2430.                 if string.lower(id) == string.lower(players[k].index) then
  2431.                     return k
  2432.                 end
  2433.             end
  2434.         end
  2435.     end
  2436.    
  2437.     return nil
  2438. end
  2439.  
  2440. local function invalidIndex(id)
  2441.  
  2442.     if id == "red" or id == "blue" or id == "all" or id == "me" or id == "this"  then
  2443.         return true
  2444.     elseif tonumber(id) then
  2445.         if tonumber(id) < 17 and tonumber(id) > 0 then
  2446.             if string.len(id) ~= 3 then
  2447.                 return true
  2448.             end
  2449.         end
  2450.     end
  2451. end
  2452.  
  2453. -- Creates a new Server Index based on amount of unique players.
  2454. local function newIndex()
  2455.  
  2456.     local x = 0
  2457.     local id
  2458.     repeat
  2459.         id = convertbase((players.unique or 1) - 1 + x, 36)
  2460.         while string.len(id) < 3 do
  2461.             id = "0" .. id
  2462.         end
  2463.         x = x + 1
  2464.    
  2465.     until not validIndex(id) and not invalidIndex(id)
  2466.  
  2467.     return id
  2468. end
  2469.  
  2470. function mostUsedAlias(hash)
  2471.  
  2472.     local max = 0
  2473.     local name
  2474.     for k,v in pairs(players[hash].alias or {}) do
  2475.         if v > max then
  2476.             max = v
  2477.             name = k
  2478.         end
  2479.     end
  2480.    
  2481.     return name
  2482. end
  2483.  
  2484. function validPlayer(hash, name)
  2485.  
  2486.     if not players[hash] then
  2487.         players.unique = (players.unique or 0) + 1
  2488.         local index = newIndex()
  2489.         players[hash] = {}
  2490.         local player = hashtoplayer(hash)
  2491.         players[hash].name = name or getname(player) or "Anonymous"
  2492.         players[hash].index = index
  2493.         players[hash].alias = {}
  2494.         players[hash].messages = {}
  2495.         players[hash].adminlevels = {}
  2496.         players[hash].commands = {}
  2497.         players[hash].shortcuts = {}
  2498.         players[hash].banned = false
  2499.         players[hash].bancount = 0
  2500.         players[hash].bos = false
  2501.         players[hash].kickcount = 0
  2502.         players[hash].lastseen = math.inf
  2503.     end
  2504. end
  2505.  
  2506. -- Create a new player if they don't already exist and updates that player's information.
  2507. function updatePlayer(player)
  2508.  
  2509.     local hash = gethash(player)
  2510.    
  2511.     if not players[hash] then      
  2512.         players.unique = (players.unique or 0) + 1
  2513.     end
  2514.    
  2515.     local index
  2516.     if players[hash] then
  2517.         index = players[hash].index
  2518.     else
  2519.         index = newIndex()
  2520.     end
  2521.    
  2522.     players[hash] = players[hash] or {}
  2523.     players[hash].name = players[hash].savedname or getname(player) or mostUsedAlias(hash)
  2524.     players[hash].index = index
  2525.     players[hash].alias = players[hash].alias or {}
  2526.     players[hash].messages = players[hash].messages or {}
  2527.    
  2528.     players[hash].adminlevels = {}
  2529.     players[hash].commands = {}
  2530.     players[hash].shortcuts = {}
  2531.    
  2532.     players[hash].banned = players[hash].banned or false
  2533.     players[hash].bancount = players[hash].bancount or 0
  2534.     players[hash].bos = players[hash].bos or false
  2535.    
  2536.     players[hash].kickcount = players[hash].kickcount or 0
  2537.    
  2538.     players[hash].alias[getname(player)] = (players[hash].alias[getname(player)] or 0) + 1
  2539.    
  2540.     players[hash].lastseen = 0
  2541.    
  2542.     players.recent[hash] = players.recentmemory
  2543.    
  2544.     players[hash].maps = players[hash].maps or {}
  2545.     players[hash].gametypes = players[hash].gametypes or {}
  2546.     players[hash].scripts = players[hash].scripts or {}
  2547.    
  2548.     -- Check messages.
  2549.     if #players[hash].messages > 0 then
  2550.    
  2551.         for _,v in ipairs(players[hash].messages) do
  2552.             hprint(player, v, 30)
  2553.         end
  2554.        
  2555.         if not mute_table[hash].muted then
  2556.             hprint(player, "Type cls in the chat to clear this screen.", 30)
  2557.         end
  2558.        
  2559.         players[hash].messages = {}
  2560.     end
  2561.    
  2562.     -- Ban on Sight.
  2563.     if players[hash].bos then
  2564.         ban(hash, players[hash].name, players[hash].bantime)
  2565.         players[hash].bos = false
  2566.     end
  2567.    
  2568.     -- Call other updating functions
  2569.     updateMute(player)
  2570. end
  2571.  
  2572. -- Converts Player ID or Server Index to a hash.
  2573. function tohash(id, rcon, admin, name)
  2574.  
  2575.     local hash
  2576.    
  2577.     if id then
  2578.         if id == "me" then
  2579.             return gethash(admin)
  2580.         elseif id == "all" or id == "red" or id == "blue" then
  2581.             local hashes = {}
  2582.             if id == "all" then
  2583.                 for i = 0, 15 do
  2584.                     if gethash(i) then table.insert(hashes, gethash(i)) end
  2585.                 end
  2586.                 if #hashes == 0 then
  2587.                     console("There are no players in the server.")
  2588.                 end
  2589.             elseif id == "red" then
  2590.                 if teamplay == 1 then
  2591.                     for i = 0, 15 do
  2592.                         if gethash(i) then
  2593.                             if getteam(i) == 0 then table.insert(hashes, gethash(i)) end
  2594.                         end
  2595.                     end
  2596.                 else
  2597.                     console("This is not a team game.")
  2598.                     return nil
  2599.                 end
  2600.                 if #hashes == 0 then
  2601.                     console("There is nobody on the red team.")
  2602.                 end
  2603.             elseif id == "blue" then
  2604.                 if teamplay == 1 then
  2605.                     for i = 0, 15 do
  2606.                         if gethash(i) then
  2607.                             if getteam(i) == 1 then table.insert(hashes, gethash(i)) end
  2608.                         end
  2609.                     end
  2610.                 else
  2611.                     console("This is not a team game.")
  2612.                     return nil
  2613.                 end
  2614.                 if #hashes == 0 then
  2615.                     console("There is nobody on the blue team.")
  2616.                 end
  2617.             end
  2618.             return unpack(hashes)
  2619.         end
  2620.        
  2621.         if string.len(id) >= 3 and string.len(id) < 32 then
  2622.        
  2623.             local valid = validIndex(id)
  2624.             if not valid then
  2625.                 for i = 0, 15 do
  2626.                     if getname(i) then
  2627.                         if string.find(getname(i), id) then
  2628.                             hash = gethash(i)
  2629.                         end
  2630.                     end
  2631.                 end
  2632.             else
  2633.                 hash = valid
  2634.             end
  2635.            
  2636.         elseif string.len(id) == 32 then
  2637.             hash = id
  2638.         else
  2639.             if rcon then
  2640.                 if (tonumber(id) or 0) > 0 and (tonumber(id) or 17) <= 16 then
  2641.                     hash = gethash(rresolveplayer(id))
  2642.                 end
  2643.             else
  2644.                 if (tonumber(id) or -1) >= 0 and (tonumber(id) or 16) < 16 then
  2645.                     hash = gethash(id)
  2646.                 end
  2647.             end
  2648.         end
  2649.     end
  2650.    
  2651.     if hash then
  2652.         validPlayer(hash, name)
  2653.     end
  2654.    
  2655.     return hash
  2656. end
  2657.  
  2658. function validId(input)
  2659.  
  2660.     if input == "all" or input == "red" or input == "blue" or input == "me" or input == "this" or validIndex(input) or gethash(tonumber(input)) or string.len(input) == 32 then
  2661.         return true
  2662.     end
  2663. end
  2664.  
  2665. function toTeam(input)
  2666.  
  2667.     if input == "red" then
  2668.         return "Red Team"
  2669.     elseif input == "blue" then
  2670.         return "Blue Team"
  2671.     elseif input == "all" then
  2672.         return "All"
  2673.     end
  2674. end
  2675.  
  2676. function sv_unique(admin)
  2677.  
  2678.     console(players.unique .. " unique hashes have joined this server.")
  2679.     return true
  2680. end
  2681.  
  2682. function sv_players(admin, search)
  2683.  
  2684.     if not search then
  2685.         console("Player ID   Server ID   Player Name    Most Common Alias")
  2686.         for i = 0, 15 do
  2687.             local hash = gethash(i)
  2688.             if hash then
  2689.                 local message = "[" .. resolveplayer(i) .. "]              [" .. players[hash].index .. "]          " .. getname(i)
  2690.                 if getname(i) ~= mostUsedAlias(hash) then
  2691.                     message = message .. "                  " .. mostUsedAlias(hash)
  2692.                 end
  2693.                 console(message)
  2694.             end
  2695.         end
  2696.        
  2697.         local t = {}
  2698.         for k,_ in pairs(players.recent) do
  2699.             if not hashtoplayer(k) then
  2700.                 table.insert(t, "[" .. players[k].index .. "] " .. players[k].name)
  2701.             end
  2702.         end
  2703.        
  2704.         if #t > 0 then
  2705.             console("Recent Players:")
  2706.             local mprint = printlist(t, 5, "  |  ")
  2707.             for _,v in ipairs(mprint) do
  2708.                 console(v)
  2709.             end
  2710.         end
  2711.     else
  2712.         search = string.lower(search)
  2713.         local matches = {}
  2714.         for k,v in pairs(players) do
  2715.             if tonumber(k, 16) then
  2716.                 if string.find(string.lower(players[k].name), search) then
  2717.                     table.insert(matches, k)
  2718.                 end
  2719.             end
  2720.         end
  2721.        
  2722.         for k,v in pairs(players) do
  2723.             if tonumber(k, 16) then
  2724.                 for a,_ in pairs(players[k].alias) do
  2725.                     if string.find(string.lower(a), search) then
  2726.                         if not table.find(matches, k) then
  2727.                             table.insert(matches, k)
  2728.                         end
  2729.                     end
  2730.                 end
  2731.             end
  2732.         end
  2733.        
  2734.         if #matches > 0 then
  2735.             table.sort(matches, function(a, b) return players[a].lastseen < players[b].lastseen end)
  2736.             console("Player names matching search \"" .. search .. "\":")
  2737.             local min = math.min(25, #matches)
  2738.             for i = 1, min do
  2739.                 console("[" .. players[matches[i]].index .. "] " .. players[matches[i]].name)
  2740.             end
  2741.         else
  2742.             console("Your search returned no matches.")
  2743.         end
  2744.     end
  2745.    
  2746.     return true
  2747. end
  2748.  
  2749. function sv_player_memory(admin, value)
  2750.  
  2751.     if value then
  2752.         value = tonumber(value)
  2753.         if value then
  2754.             players.recentmemory = value
  2755.             console("Players will now be remembered for " .. value .. " games.")
  2756.             return true
  2757.         else
  2758.             console("Invalid Value.")
  2759.         end
  2760.     else
  2761.         console("Players are remembered for " .. players.recentmemory .. " games.")
  2762.         return true
  2763.     end
  2764.    
  2765.     return false
  2766. end
  2767.  
  2768. function sv_player_index(admin, id, index)
  2769.  
  2770.     local hash = tohash(id, true, admin)
  2771.    
  2772.     if hash then
  2773.         if index then
  2774.             if not validIndex(index) then
  2775.                 if not invalidIndex(index) then
  2776.                     if string.len(index) < 32 then
  2777.                         players[hash].index = index
  2778.                         console((players[hash].name or "This player") .. "'s Server Index changed to \"" .. index .. "\".")
  2779.                         return true
  2780.                     else
  2781.                         console("Index must be less than 32 characters.")
  2782.                     end
  2783.                 else
  2784.                     console("Index may not be \"red\", \"blue\", \"all\", \"me\" or an integer between 1 and 16.")
  2785.                 end
  2786.             else
  2787.                 console("\"" .. index .. "\" is already in use.")
  2788.             end
  2789.         else
  2790.             console("[" .. players[hash].index .. "] " .. players[hash].name)
  2791.             return true
  2792.         end
  2793.     else
  2794.         console("Invalid Player.")
  2795.     end
  2796.    
  2797.     return false
  2798. end
  2799.  
  2800. function sv_player_name(admin, id, name)
  2801.  
  2802.     local hash = tohash(id, true, admin)
  2803.    
  2804.     if hash then
  2805.         if name then
  2806.             if name ~= "" then
  2807.                 local oldname = players[hash].name
  2808.                 players[hash].savedname = name
  2809.                 players[hash].name = name
  2810.                 console((oldname or "This player") .. "'s name changed to \"" .. name .. "\".")
  2811.             else
  2812.                 players[hash].savedname = nil
  2813.                 console((players[hash].name or "This player") .. "'s name will now be based on his/her most common alias.")
  2814.                 players[hash].name = mostUsedAlias(hash) or getname(player) or ""
  2815.             end
  2816.         else
  2817.             console("[" .. players[hash].index .. "] " .. players[hash].name)
  2818.         end
  2819.        
  2820.         return true
  2821.     end
  2822.    
  2823.     console("Invalid Player.")
  2824.     return false
  2825. end
  2826.  
  2827. function sv_alias(admin, id)
  2828.  
  2829.     local hash = tohash(id, true, admin)
  2830.    
  2831.     if hash then
  2832.         local aliases = {}
  2833.         for k,_ in pairs(players[hash].alias) do
  2834.             table.insert(aliases, k)
  2835.         end
  2836.        
  2837.         table.sort(aliases, function(a, b) return players[hash].alias[a] > players[hash].alias[b] end)
  2838.        
  2839.         for k,v in ipairs(aliases) do
  2840.             aliases[k] = "[" .. players[hash].alias[v] .. "] " .. v
  2841.         end
  2842.        
  2843.         console("Aliases and number of times joined under an alias:")
  2844.        
  2845.         local mprint = printlist(aliases, 5, "  |  ")
  2846.         for _,v in ipairs(mprint) do
  2847.             console(v)
  2848.         end
  2849.        
  2850.         return true
  2851.     end
  2852.    
  2853.     console("Invalid Player.")
  2854.     return false
  2855. end
  2856.  
  2857. function sv_reset_alias(admin, id)
  2858.  
  2859.     local hash = tohash(id, true, admin)
  2860.    
  2861.     if hash then
  2862.         local name = mostUsedAlias(hash)
  2863.         players[hash].alias = {}
  2864.         console((name or getname(hashtoplayer(hash)) or "This player") .. "'s aliases have been reset.")
  2865.         return true
  2866.     end
  2867.    
  2868.     console("Invalid Player.")
  2869.     return false
  2870. end
  2871.  
  2872. function sv_message(admin, id, message)
  2873.  
  2874.     local hash = tohash(id, true, admin)
  2875.    
  2876.     if hash then
  2877.         if hashtoplayer(hash) then
  2878.             hprint(hashtoplayer(hash), message, 15)
  2879.             console("Message sent.")
  2880.         else
  2881.             table.insert(players[hash].messages, message)
  2882.             console(players[hash].name .. " will receive this message next time they join the server.")
  2883.         end
  2884.        
  2885.         return true
  2886.     end
  2887.    
  2888.     console("Invalid Player.")
  2889.     return false
  2890. end
  2891.  
  2892. --[[ Admin Handling ]]--
  2893.  
  2894. --[[ Levels Table Structure ]]--
  2895.  
  2896. --[[
  2897.  
  2898.     players.levels.default
  2899.     players.levels[k]
  2900.         players.levels[k].id = "L" .. k
  2901.         players.levels[k].name
  2902.         players.levels[k].openaccess
  2903.         players.levels[k].access
  2904.         players.levels[k].members = {}
  2905.         players.levels[k].commands = {}
  2906.        
  2907. --]]
  2908.  
  2909. function validLevel(id)
  2910.  
  2911.     if id then
  2912.         for k,v in ipairs(players.levels) do
  2913.             if string.lower(id) == string.lower(players.levels[k].id) or string.lower(id) == string.lower(players.levels[k].name) then
  2914.                 return k
  2915.             end
  2916.         end
  2917.     end
  2918. end
  2919.  
  2920. function nextLevel()
  2921.  
  2922.     for i = 0,9 do
  2923.         local id = "L" .. i
  2924.         if not validLevel(id) then
  2925.             return i
  2926.         end
  2927.     end
  2928. end
  2929.  
  2930. function sv_levels(admin, search)
  2931.  
  2932.     local matches = {}
  2933.     if search then
  2934.         for k,v in ipairs(players.levels) do
  2935.             if string.find(players.levels[k].name, search) or string.find(players.levels[k].id, search) then
  2936.                 table.insert(matches, k)
  2937.             end
  2938.         end
  2939.     else
  2940.         for k,v in ipairs(players.levels) do
  2941.             table.insert(matches, k)
  2942.         end
  2943.     end
  2944.    
  2945.     table.sort(matches, function(a, b) return players.levels[a].id > players.levels[b].id end)
  2946.    
  2947.     for k,v in ipairs(matches) do
  2948.         console("[" .. players.levels[k].id .. "] " .. players.levels[k].name)
  2949.     end
  2950.    
  2951.     return true
  2952. end
  2953.  
  2954. function sv_level_admins(admin, level)
  2955.  
  2956.     level = validLevel(level)
  2957.     if level then
  2958.         console("Admins in Level \"" .. players.levels[level].name .. "\":")
  2959.         for k,v in ipairs(players.levels[level].members) do
  2960.             console("[" .. players[v].index .. "] " .. players[v].name)
  2961.         end
  2962.         return true
  2963.     end
  2964.    
  2965.     console("Invalid Admin Level.")
  2966.     return false
  2967. end
  2968.  
  2969. function sv_level_add(admin, name)
  2970.  
  2971.     local id = nextLevel()
  2972.    
  2973.     if id then 
  2974.         if not name then
  2975.             local x = id - 1
  2976.             repeat
  2977.                 name = "Level " .. (x + 1)
  2978.             until not validLevel(name)
  2979.         end
  2980.         if string.len(name) > 3 then
  2981.             local index = "L" .. (id)
  2982.             if validLevel(name) then
  2983.                 console("The name \""  .. name .. "\" is already in use.")
  2984.                 return false
  2985.             end
  2986.            
  2987.             if not players.levels.default or players.levels.default == "L" .. (#players.levels - 1) then
  2988.                 players.levels.default = index
  2989.             end
  2990.            
  2991.             local t = {}
  2992.             t.id = index
  2993.             t.name = name
  2994.             t.members = {}
  2995.             t.commands = {"sv_players", "sv_unique", "sv_admins", "sv_commands", "sv_shortcut"}
  2996.             table.insert(players.levels, t)
  2997.            
  2998.             console("New Admin Level \""  .. name .. "\" created with index " .. index .. ".")
  2999.             return true, index
  3000.         else
  3001.             console("Name must be longer than 3 characters.")
  3002.         end
  3003.     else
  3004.         console("You have already reached your maximum of 10 Admin Levels.")
  3005.         console("You may use sv_command_add on individual players, or delete a current Admin Level before creating a new one.")
  3006.     end
  3007.    
  3008.     return false
  3009. end
  3010.  
  3011. function sv_level_del(admin, id)
  3012.  
  3013.     local level = validLevel(id)
  3014.     if level then
  3015.         for _,h in ipairs(players.levels[level].members) do
  3016.             for k,L in ipairs(players[h].adminlevels) do
  3017.                 if L == level then
  3018.                     table.remove(players[h].adminlevels, k)
  3019.                 end
  3020.             end
  3021.         end
  3022.        
  3023.         console("Admin Level \"" .. players.levels[level].name .. "\" has been deleted.")
  3024.         table.remove(players.levels, level)
  3025.         return true
  3026.     else
  3027.         console("Invalid Admin Level.")
  3028.     end
  3029.    
  3030.     return false
  3031. end
  3032.  
  3033. function noAdmins()
  3034.  
  3035.     if #players.admins == 0 then
  3036.         return true
  3037.     end
  3038. end
  3039.  
  3040. function isAdmin(id)
  3041.  
  3042.     local hash = tohash(id)
  3043.     if hash then
  3044.         if players.admins[hash] then
  3045.             return true
  3046.         end
  3047.         if #players[hash].commands > 0 then
  3048.             return true
  3049.         end
  3050.     else
  3051.         return true
  3052.     end
  3053. end
  3054.  
  3055. function sv_admin_add(admin, id, level)
  3056.  
  3057.     local hash = tohash(id, true, admin)
  3058.     if hash then
  3059.         if not level then
  3060.             if #players.levels > 0 then
  3061.                 level = players.levels.default
  3062.             else
  3063.                 ncmd("sv_level_add")
  3064.                 ncmd("sv_openaccess L0")
  3065.                 level = "L0"
  3066.             end
  3067.         end
  3068.         level = validLevel(level)
  3069.         if level then
  3070.             for k,v in ipairs(players[hash].adminlevels) do
  3071.                 if v == level then
  3072.                     console(players[hash].name .. " is already in Admin Level \"" .. players.levels[level].name .. "\".")
  3073.                     return false
  3074.                 end
  3075.             end
  3076.            
  3077.             players.admins[hash] = true
  3078.             table.insert(players[hash].adminlevels, level)     
  3079.             table.insert(players.levels[level].members, hash)
  3080.             console(players[hash].name .. " has been added to Admin Level \""  .. players.levels[level].name .. "\".")
  3081.            
  3082.             if hashtoplayer(hash) then
  3083.                 hprint(hashtoplayer(hash), "You are now an administrator in Admin Level \"" .. players.levels[level].name .. "\".", 20)
  3084.                 hprint(hashtoplayer(hash), "Type sv_commands in the chat to view a list of commands you may execute.", 20)
  3085.                 hprint(hashtoplayer(hash), "Use sv_help on a command to view information about that command.  (For example: sv_help sv_commands)", 20)
  3086.                 hprint(hashtoplayer(hash), "Ask the server provider on information about how to use the RCON console.", 20)
  3087.                 hprint(hashtoplayer(hash), "Type cls to clear this screen.", 20)
  3088.             end
  3089.            
  3090.             return true
  3091.         else
  3092.             console("Invalid Admin Level.")
  3093.         end
  3094.     else
  3095.         console("Invalid Player.")
  3096.     end
  3097.    
  3098.     return false
  3099. end
  3100.  
  3101. function sv_admin_del(admin, id, level)
  3102.  
  3103.     local hash = tohash(id, true, admin)
  3104.     if hash then
  3105.         if players.admins[hash] then
  3106.             if not level then
  3107.                 for _,v in ipairs(players[hash].adminlevels) do
  3108.                     for k,h in ipairs(players.levels[v].members) do
  3109.                         if h == hash then
  3110.                             table.remove(players.levels[v].members, k)
  3111.                             break
  3112.                         end
  3113.                     end
  3114.                 end
  3115.  
  3116.                 players.admins[hash] = nil
  3117.                 players[hash].adminlevels = {}
  3118.                 players[hash].commands = {}
  3119.                 players[hash].shortcuts = {}
  3120.                
  3121.                 console(players[hash].name .. " is no longer an admin.")
  3122.             else
  3123.                 level = validLevel(level)
  3124.                 if level then
  3125.                     for k,h in ipairs(players.levels[v].members) do
  3126.                         if h == hash then
  3127.                             table.remove(players.levels[v].members, k)
  3128.                             break
  3129.                         end
  3130.                     end
  3131.                    
  3132.                     for k,v in ipairs(players[hash].adminlevels) do
  3133.                         if level == v then
  3134.                             table.remove(players[hash].adminlevels, k)
  3135.                             break
  3136.                         end
  3137.                     end
  3138.                    
  3139.                     console(players[hash].name .. " has been removed from Admin Level " .. players.levels[level].name .. ".")
  3140.                 else
  3141.                     console("Invalid Admin Level.")
  3142.                     return false
  3143.                 end
  3144.             end
  3145.            
  3146.             return true            
  3147.         else
  3148.             console(players[hash].name .. " is not an admin.")
  3149.         end
  3150.     else
  3151.         console("Invalid Player.")
  3152.     end
  3153.    
  3154.     return false           
  3155. end
  3156.  
  3157. function sv_admin_default(admin, level)
  3158.  
  3159.     if level then
  3160.         level = validLevel(level)
  3161.         if level then
  3162.             players.levels.default = players.levels[level].id
  3163.             console("The Default Admin Level is now \"" .. players.levels[level].name .. "\".")
  3164.             console("If an admin is added without a level specification, they will be added to this level.")
  3165.         end
  3166.     else
  3167.         level = validLevel(players.levels.default)
  3168.         if level then
  3169.             console(players.levels[level].name)
  3170.         else
  3171.             console("There are currently no Admin Levels.")
  3172.         end
  3173.     end
  3174.    
  3175.     return true
  3176. end
  3177.  
  3178. function sv_admins(admin, search)
  3179.  
  3180.     local matches = {}
  3181.     if search then
  3182.         for k,v in pairs(players.admins) do
  3183.             if string.find(string.lower(players[k].name), string.lower(search)) then
  3184.                 table.insert(matches, k)
  3185.             else
  3186.                 for a,_ in pairs(players[k].alias) do
  3187.                     if string.find(string.lower(a), string.lower(search)) then
  3188.                         table.insert(matches, k)
  3189.                     end
  3190.                 end
  3191.             end
  3192.         end
  3193.        
  3194.         if #matches > 0 then
  3195.             console("Admins with names matching \"" .. search .. "\":")
  3196.             for k,v in ipairs(matches) do
  3197.                 console("[" .. players[v].index .. "] " .. players[v].name)
  3198.             end
  3199.             return true
  3200.         end
  3201.        
  3202.         if validLevel(search) then
  3203.             local level = validLevel(search)
  3204.             for k,v in ipairs(players.levels[level].members) do
  3205.                 table.insert(matches, v)
  3206.             end
  3207.             console("Admins in Admin Level \"" .. players.levels[level].name .. "\":")
  3208.             for k,v in ipairs(matches) do
  3209.                 console("[" .. players[v].index .. "] " .. players[v].name)
  3210.             end
  3211.             return true
  3212.         end
  3213.        
  3214.         local hash = tohash(search, true, admin)
  3215.         if hash then
  3216.             if players.admins[hash] then
  3217.                 console("true")
  3218.             else
  3219.                 console("false")
  3220.             end
  3221.             return true
  3222.         end
  3223.        
  3224.         if validCommand(search) then
  3225.             for k,v in pairs(players.admins) do
  3226.                 if canExecute(k, search) then
  3227.                     table.insert(matches, k)
  3228.                 end
  3229.             end
  3230.            
  3231.             console("Admins capable of executing \"" .. search .. "\":")
  3232.             for k,v in ipairs(matches) do
  3233.                 console("[" .. players[v].index .. "] " .. players[v].name)
  3234.             end
  3235.             return true
  3236.         end
  3237.        
  3238.         for k,v in pairs(commands.syntax) do
  3239.             if string.find(string.lower(k), string.lower(search)) then
  3240.                 for h,_ in pairs(players.admins) do
  3241.                     if canExecute(h, k) then
  3242.                         table.insert(matches, h)
  3243.                     end
  3244.                 end
  3245.             end
  3246.         end
  3247.        
  3248.         if #matches > 0 then
  3249.             console("Admins capable of executing commands matching \"" .. search .. "\":")
  3250.             for k,v in ipairs(matches) do
  3251.                 console("[" .. players[v].index .. "] " .. players[v].name)
  3252.             end
  3253.             return true
  3254.         end
  3255.        
  3256.         console("Your search returned no results.")
  3257.     else
  3258.         console("Server Administrators:")
  3259.         for k,v in pairs(players.admins) do
  3260.             console("[" .. players[k].index .. "] " .. players[k].name)
  3261.         end
  3262.     end
  3263.    
  3264.     return true        
  3265. end
  3266.  
  3267. function canExecute(id, command)
  3268.  
  3269.     if noAdmins() then
  3270.         return true
  3271.     else
  3272.         local hash = tohash(id)
  3273.         if hash then
  3274.             if validCommand(command) then
  3275.                 local cmds = {}
  3276.                 for k,v in ipairs(players[hash].commands) do
  3277.                     if command == v then
  3278.                         return true
  3279.                     end
  3280.                 end
  3281.                
  3282.                 for k,v in ipairs(players[hash].adminlevels) do
  3283.                     for _,c in ipairs(players.levels[v].commands) do
  3284.                         if command == c then
  3285.                             return true
  3286.                         end
  3287.                     end
  3288.                 end
  3289.             else
  3290.                 for k,v in ipairs(players[hash].shortcuts) do
  3291.                     if command == v then
  3292.                         return true
  3293.                     end
  3294.                 end
  3295.             end
  3296.         else
  3297.             return true
  3298.         end
  3299.     end
  3300. end
  3301.  
  3302. function sv_commands(admin, search)
  3303.  
  3304.     local matches = {}
  3305.    
  3306.     if search then
  3307.         if validLevel(search) then
  3308.             local level = validLevel(search)
  3309.             for k,v in ipairs(players.levels[level].commands) do
  3310.                 table.insert(matches, v)
  3311.             end        
  3312.             console("Commands executable by Admin Level \"" .. players.levels[level].name .. "\":")
  3313.             table.sort(matches)
  3314.             local mprint = printlist(matches, 4, "  ")
  3315.             for k,v in ipairs(mprint) do
  3316.                 console(v)
  3317.             end
  3318.             return true
  3319.         end
  3320.  
  3321.         for k,v in pairs(commands.syntax) do
  3322.             if string.find(k, search) then
  3323.                 table.insert(matches, k)
  3324.             end
  3325.         end
  3326.        
  3327.         if #matches > 0 then
  3328.             console("Commands matching search \"" .. search .. "\":")
  3329.             table.sort(matches)
  3330.             local mprint = printlist(matches, 4, "  ")
  3331.             for k,v in ipairs(mprint) do
  3332.                 console(v)
  3333.             end
  3334.             return true
  3335.         end
  3336.        
  3337.         local hash = tohash(search, true, admin)
  3338.         if hash then
  3339.             for k,v in pairs(commands.syntax) do
  3340.                 if canExecute(hash, k) then
  3341.                     table.insert(matches, k)
  3342.                 end
  3343.             end
  3344.            
  3345.             if #matches > 0 then
  3346.                 console("Commands executable by [" .. players[hash].index .. "] " .. players[hash].name .. ":")
  3347.                 local m = {}
  3348.                 for k,v in ipairs(matches) do
  3349.                     if not table.find(m, v) then
  3350.                         table.insert(m, v)
  3351.                     end
  3352.                 end
  3353.                 table.sort(m)
  3354.                 local mprint = printlist(m, 4, "  ")
  3355.                 for k,v in ipairs(mprint) do
  3356.                     console(v)
  3357.                 end
  3358.                 return true
  3359.             else
  3360.                 console(players[hash].name .. " is not an administrator.")
  3361.             end
  3362.         end
  3363.     else
  3364.         local hash = gethash(admin)
  3365.         if hash then
  3366.             sv_commands(admin, hash)
  3367.         else
  3368.             for k,v in pairs(commands.syntax) do
  3369.                 table.insert(matches, k)
  3370.             end
  3371.             table.sort(matches)
  3372.             local mprint = printlist(matches, 4, "   ")
  3373.             for k,v in ipairs(mprint) do
  3374.                 console(v)
  3375.             end
  3376.         end
  3377.         return true
  3378.     end
  3379.    
  3380.     console("Your search returned no results.")
  3381.     return false
  3382. end
  3383.  
  3384. function sv_command_add(admin, id, command)
  3385.  
  3386.     if validCommand(command) then
  3387.         if validLevel(id) then
  3388.             local level = validLevel(id)
  3389.             if not table.find(players.levels[level].commands, command) then
  3390.                 table.insert(players.levels[level].commands, command)
  3391.                 console("\"" .. command .. "\" can now be executed by Admin Level \"" .. players.levels[level].name .. "\".")
  3392.             else
  3393.                 console("Admin Level \"" .. players.levels[level].name .. "\" can already execute \"" .. command .. "\".")
  3394.             end
  3395.            
  3396.             return true
  3397.         else
  3398.             local hash = tohash(id, true, admin)
  3399.             if hash then
  3400.                 if not table.find(players[hash].commands, command) then
  3401.                     table.insert(players[hash].commands, command)
  3402.                     players.admins[hash] = true
  3403.                     console(players[hash].name .. " can now execute \"" .. command .. "\".")
  3404.                 else
  3405.                     console(players[hash].name .. " can already execute \"" .. command .. "\".")
  3406.                 end
  3407.                
  3408.                 return true
  3409.             else
  3410.                 console("Invalid Player or Admin Level.")
  3411.             end
  3412.         end
  3413.     else
  3414.         console("Invalid Command.")
  3415.     end
  3416.    
  3417.     return false
  3418. end
  3419.  
  3420. function sv_command_del(admin, id, command)
  3421.  
  3422.     if validCommand(command) then
  3423.         if validLevel(id) then
  3424.             local level = validLevel(id)
  3425.             for k,v in ipairs(players.levels[level].commands) do
  3426.                 if v == command then                   
  3427.                     table.remove(players.levels[level].commands, k)
  3428.                     console("\"" .. command .. "\" can no longer be executed by Admin Level \"" .. players.levels[level].name .. "\".")
  3429.                     return true
  3430.                 end
  3431.             end
  3432.            
  3433.             console("Admin Level \"" .. players.levels[level].name .. "\" is not able to execute \"" .. command .. "\".")
  3434.             return true
  3435.         else
  3436.             local hash = tohash(id, true, admin)
  3437.             if hash then
  3438.                 for k,v in ipairs(players[hash].commands) do
  3439.                     if v == command then
  3440.                         table.remove(players[hash].commands, k)
  3441.                         console(players[hash].name .. " can no longer execute \"" .. command .. "\".")
  3442.                         return true
  3443.                     end
  3444.                 end
  3445.                
  3446.                 console(players[hash].name .. " is not able to execute \"" .. command .. "\".")
  3447.                 return true
  3448.             else
  3449.                 console("Invalid Player or Admin Level.")
  3450.             end
  3451.         end
  3452.     else
  3453.         console("Invalid Command.")
  3454.     end
  3455.    
  3456.     return false
  3457. end
  3458.  
  3459. function openaccess(id)
  3460.  
  3461.     local hash = tohash(id)
  3462.     if hash then
  3463.         if players[hash].openaccess then
  3464.             for c,_ in pairs(commands.syntax) do
  3465.                 if not table.find(players[hash].commands, c) then
  3466.                     table.insert(players[hash].commands, c)
  3467.                 end
  3468.             end
  3469.         end
  3470.     end
  3471. end
  3472.  
  3473. function sv_openaccess(admin, id, boolean)
  3474.  
  3475.     if validLevel(id) then
  3476.         local level = validLevel(id)
  3477.         if boolean then
  3478.             if boolean == "true" or boolean == "1" then
  3479.                 if players.levels[level].openaccess then
  3480.                     console("Admin Level \"" .. players.levels[level].name .. "\" is already Open-Access.")
  3481.                 else
  3482.                     players.levels[level].openaccess = true
  3483.                     for k,v in pairs(commands.syntax) do
  3484.                         table.insert(players.levels[level].commands, k)
  3485.                     end
  3486.                     for k,v in ipairs(players.levels[level].members) do
  3487.                         players[v].openaccess = true
  3488.                         openaccess(v)
  3489.                     end
  3490.                     console("Admin Level \"" .. players.levels[level].name .. "\" is now Open-Access.")
  3491.                 end
  3492.             elseif boolean == "false" or boolean == "0" then
  3493.                 if players.levels[level].openaccess then
  3494.                     players.levels[level].openaccess = nil
  3495.                     for k,v in ipairs(players.levels[level].members) do
  3496.                         players[v].openaccess = nil
  3497.                     end
  3498.                     console("Admin Level \"" .. players.levels[level].name .. "\" is no longer Open-Access.")
  3499.                 else
  3500.                     console("Admin Level \"" .. players.levels[level].name .. "\" isn't Open-Access.")
  3501.                 end
  3502.             else
  3503.                 console("Invalid Boolean.")
  3504.                 return false
  3505.             end
  3506.         else
  3507.             if players.levels[level].openaccess then
  3508.                 console("true")
  3509.             else
  3510.                 console("false")
  3511.             end
  3512.         end
  3513.     else   
  3514.         local hash = tohash(id, true, admin)
  3515.         if hash then
  3516.             if boolean then
  3517.                 if boolean == "true" or boolean == "1" then
  3518.                     if players[hash].openaccess then
  3519.                         console(players[hash].name .. " is already an Open-Access administrator.")
  3520.                     else
  3521.                         players[hash].openaccess = true
  3522.                         if not table.find(players.admins, hash) then
  3523.                             table.insert(players.admins, hash)
  3524.                         end
  3525.                         openaccess(hash)
  3526.                         console(players[hash].name .. " is now an Open-Access administrator.")
  3527.                     end
  3528.                 elseif boolean == "false" or boolean == "0" then
  3529.                     if players[hash].openaccess then
  3530.                         players[hash].openaccess = nil
  3531.                         console(players[hash].name .. " is no longer an Open-Access administrator.")
  3532.                     else
  3533.                         console(players[hash].name .. " isn't an Open-Access administrator.")
  3534.                     end
  3535.                 else
  3536.                     console("Invalid Boolean.")
  3537.                     return false
  3538.                 end
  3539.             else
  3540.                 if players[hash].openaccess then
  3541.                     console("true")
  3542.                 else
  3543.                     console("false")
  3544.                 end
  3545.             end
  3546.         else
  3547.             console("Invalid Player or Admin Level.")
  3548.             return false
  3549.         end
  3550.     end
  3551.    
  3552.     return true
  3553. end
  3554.  
  3555. function addAdmin(hash, name, level)
  3556.  
  3557.     validPlayer(hash, name)
  3558.     local index = newLevelFromAccess(level, hash)
  3559.     if index then
  3560.         if not players.admins[hash] then
  3561.             svcmd("sv_admin_add " .. hash .. " " .. index)
  3562.         end
  3563.     end
  3564. end
  3565.  
  3566. function getaccess(level)
  3567.  
  3568.     local dir = getprofilepath()
  3569.     local access = io.open(dir .. "\\access.ini", "r")
  3570.     if access then
  3571.         local bool
  3572.         for line in access:lines() do
  3573.             if not bool then
  3574.                 if string.find(line, "[" .. level .. "]") then
  3575.                     bool = true
  3576.                 end
  3577.             else
  3578.                 if string.find(line, "data=") then
  3579.                     return string.split(line:gsub("data=", ""), ",")
  3580.                 end
  3581.             end            
  3582.         end
  3583.         access:close()
  3584.     end
  3585. end
  3586.  
  3587. function newLevelFromAccess(id, hash)
  3588.  
  3589.     for k,v in ipairs(players.levels) do
  3590.         if players.levels[k].access == id then
  3591.             return players.levels[k].id
  3592.         end
  3593.     end
  3594.    
  3595.     local level = id - 1
  3596.     local overshoot
  3597.     repeat
  3598.         level = level + 1
  3599.         if level == 10 then
  3600.             level = 0
  3601.         end
  3602.         local index = "L" .. level
  3603.         if level == id - 1 then
  3604.             overshoot = true
  3605.         end
  3606.     until not validLevel(index) or level == id - 1
  3607.     if overshoot then
  3608.         return "L9"
  3609.     else
  3610.         local index = "L" .. level
  3611.         local cmds = getaccess(id)
  3612.         if cmds then
  3613.             local t = {}
  3614.             t.id = index
  3615.             t.name = "Level " .. level
  3616.             t.access = id
  3617.             t.members = {}
  3618.             t.commands = {"sv_players", "sv_unique", "sv_admins", "sv_commands", "sv_shortcut"}
  3619.             table.insert(players.levels, t)
  3620.             if tonumber(cmds[1]) == -1 then
  3621.                 svcmd("sv_openaccess " .. index .. " true")
  3622.             else
  3623.                 for k,v in ipairs(cmds) do
  3624.                     svcmd("sv_command_add " .. index .. " " .. v)
  3625.                 end
  3626.             end
  3627.         end
  3628.        
  3629.         return index
  3630.     end
  3631. end
  3632.  
  3633. --[[ Open-Access Handling ]]--
  3634.  
  3635.     for k,v in pairs(players) do
  3636.         if tonumber(k, 16) then
  3637.             openaccess(k)
  3638.         end
  3639.     end
  3640.  
  3641.     for k,v in ipairs(players.levels) do
  3642.         if players.levels[k].openaccess then
  3643.             for _,h in ipairs(players.levels[k].members) do
  3644.                 openaccess(h)
  3645.             end
  3646.         end
  3647.     end
  3648.    
  3649. -- Command Functions --
  3650.  
  3651. -- Executes the given command.
  3652. function Command(admin, cmd, tokens, noprint)
  3653.  
  3654.     local command = formatCommand(cmd, tokens, admin)
  3655.     if command then
  3656.         local bool, returned = execute(cmd, admin, unpack(command))
  3657.         if bool then
  3658.             return returned
  3659.         end
  3660.     end
  3661.    
  3662.     if noprint then
  3663.         clear()
  3664.     end
  3665. end
  3666.  
  3667. -- Formats command into a table in the correct order to be executed.
  3668. function formatCommand(cmd, tokens, admin)
  3669.  
  3670.     admin = resolveplayer(admin)
  3671.    
  3672.     if validCommand(cmd) then
  3673.    
  3674.         if cmd == "sv_ban" or cmd == "sv_ban_penalty" then
  3675.             if tokens[3] then
  3676.                 tokens[3] = table.concat(tokens, " ", 3, #tokens)
  3677.                 for i = 4, #tokens do
  3678.                     table.remove(tokens, 4)
  3679.                 end
  3680.             end
  3681.         end
  3682.        
  3683.         local min_tokens = getMandatory(cmd)
  3684.         local max_tokens = getMaxTokens(cmd)
  3685.        
  3686.         if #tokens >= min_tokens and #tokens <= max_tokens then
  3687.        
  3688.             local command = {}
  3689.            
  3690.             if #commands.syntax[cmd] == 1 then
  3691.            
  3692.                 command = {}
  3693.            
  3694.             elseif #commands.syntax[cmd] == 2 then
  3695.                
  3696.                 command = {tokens[2]}
  3697.                
  3698.             elseif #commands.syntax[cmd] == 3 then
  3699.                
  3700.                 command = {tokens[2], tokens[3]}
  3701.                
  3702.             else
  3703.  
  3704.                 if cmd == "sv_mute" then
  3705.                    
  3706.                     local duration, message
  3707.                     if tonumber(tokens[3]) then
  3708.                         duration = tokens[3]
  3709.                         message = tokens[4]
  3710.                     else
  3711.                         message = tokens[3]
  3712.                     end
  3713.                    
  3714.                     command = {tokens[2], duration, message}
  3715.                    
  3716.                 elseif cmd == "sv_mutelist" then
  3717.                
  3718.                     local search, direction, length
  3719.                     if tonumber(tokens[2]) then
  3720.                         length = tokens[2]
  3721.                     elseif tonumber(tokens[3]) then
  3722.                         search = tokens[2]
  3723.                         length = tokens[3]
  3724.                     else
  3725.                         search = tokens[2]
  3726.                         direction = tokens[3]
  3727.                         length = tokens[4]
  3728.                     end
  3729.                    
  3730.                     command = {search, direction, length}
  3731.                    
  3732.                 elseif cmd == "sv_swear_add" then
  3733.            
  3734.                     local append, sweartype
  3735.                     if #tokens == 3 then
  3736.                         if getSweartype(tokens[3]) then
  3737.                             sweartype = tokens[3]
  3738.                         else
  3739.                             append = tokens[3]
  3740.                         end
  3741.                     elseif #tokens == 4 then
  3742.                         append = tokens[3]
  3743.                         sweartype = tokens[4]
  3744.                     end
  3745.                    
  3746.                     command = {tokens[2], append, sweartype}
  3747.                    
  3748.                 elseif cmd == "sv_create" then
  3749.  
  3750.                     local player, object, respawn_time, x, y, z
  3751.                     if #tokens == 7 then
  3752.                         player = tokens[2]
  3753.                         object = tokens[3]
  3754.                         respawn_time = tokens[4]
  3755.                         x = tokens[5]
  3756.                         y = tokens[6]
  3757.                         z = tokens[7]
  3758.                     elseif #tokens == 6 then
  3759.                         if tohash(tokens[2]) then
  3760.                             player = tokens[2]
  3761.                             object = tokens[3]
  3762.                             respawn_time = 0
  3763.                             x = tokens[4]
  3764.                             y = tokens[5]
  3765.                             z = tokens[6]
  3766.                         else
  3767.                             player = admin
  3768.                             object = tokens[2]
  3769.                             respawn_time = tokens[3]
  3770.                             x = tokens[4]
  3771.                             y = tokens[5]
  3772.                             z = tokens[6]
  3773.                         end
  3774.                     elseif #tokens == 5 then
  3775.                         player = admin
  3776.                         object = tokens[2]
  3777.                         respawn_time = 0
  3778.                         x = tokens[3]
  3779.                         y = tokens[4]
  3780.                         z = tokens[5]
  3781.                     elseif #tokens == 4 then
  3782.                         player = tokens[2]
  3783.                         object = tokens[3]
  3784.                         respawn_time = tokens[4]
  3785.                     elseif #tokens == 3 then
  3786.                         if tohash(tokens[2]) then
  3787.                             player = tokens[2]
  3788.                             object = tokens[3]
  3789.                         else
  3790.                             player = admin
  3791.                             object = tokens[2]
  3792.                             respawn_time = tokens[3]
  3793.                         end
  3794.                     elseif #tokens == 2 then
  3795.                         player = admin
  3796.                         object = tokens[2]
  3797.                     end
  3798.  
  3799.                     command = {player, object, respawn_time, x, y, z}
  3800.                    
  3801.                 elseif cmd == "sv_ammo" then
  3802.                    
  3803.                     local weap, ammo, clip
  3804.                     if #tokens == 5 then
  3805.                         weap = tokens[3]
  3806.                         ammo = tokens[4]
  3807.                         clip = tokens[5]
  3808.                     elseif #tokens == 4 then
  3809.                         weap = "all"
  3810.                         ammo = tokens[3]
  3811.                         clip = tokens[4]
  3812.                     end
  3813.                    
  3814.                     command = {tokens[2], weap, ammo, clip}
  3815.                    
  3816.                 else
  3817.                     for i = 2, #tokens do
  3818.                         table.insert(command, tokens[i])
  3819.                     end
  3820.                 end
  3821.             end
  3822.            
  3823.             return command
  3824.         end
  3825.     end
  3826. end
  3827.  
  3828. -- Returns the amount of mandatory parameters for a given command.
  3829. function getMandatory(cmd)
  3830.  
  3831.     local count = 0
  3832.     for _,v in ipairs(commands.syntax[cmd]) do
  3833.         if not string.find(v, "opt: ") then
  3834.             count = count + 1
  3835.         end
  3836.     end
  3837.    
  3838.     return count
  3839. end
  3840.  
  3841. function getMaxTokens(cmd)
  3842.  
  3843.     for k,v in ipairs(commands.syntax[cmd]) do
  3844.         if string.find(v, "...") then
  3845.             return math.inf
  3846.         end
  3847.     end
  3848.    
  3849.     return #commands.syntax[cmd]
  3850. end
  3851.  
  3852. function validCommand(cmd)
  3853.  
  3854.     for k,_ in pairs(commands.syntax) do
  3855.         if cmd == k then
  3856.             return true
  3857.         end
  3858.     end
  3859. end
  3860.  
  3861. function getSyntax(cmd)
  3862.  
  3863.     if commands.syntax[cmd] then
  3864.         return "Syntax: " .. table.concat(commands.syntax[cmd], " ")
  3865.     end
  3866. end
  3867.  
  3868. function ncmd(tokens, player)
  3869.  
  3870.     local cmd = tokens[1]
  3871.     if validCommand(cmd) then
  3872.         Command(admin, cmd, tokens, true)
  3873.     end
  3874. end
  3875.  
  3876. function clear()
  3877.  
  3878.     cprint = {}
  3879.     sprint = {}
  3880.    
  3881.     for k,v in ipairs(pprint) do
  3882.         pprint[k] = {}
  3883.     end
  3884. end
  3885.  
  3886. -- Help Command
  3887.  
  3888. function sv_help(admin, cmd)
  3889.  
  3890.     if validCommand(cmd) then
  3891.         console(cmd .. ":")
  3892.         for _,v in ipairs(commands.syntax[cmd]) do
  3893.             if v == cmd then
  3894.                 console(commands.info[cmd][1] .. "\n ")
  3895.                 console("Syntax: " .. table.concat(commands.syntax[cmd], " ") .. "\n ")
  3896.             else
  3897.                 local s = string.gsub(v, "opt: ", "")
  3898.                 local p = string.gsub(s, "...", "")
  3899.                 if commands.info[p] then
  3900.                     for __,value in ipairs(commands.info[p]) do
  3901.                         console(value)
  3902.                     end
  3903.                 else
  3904.                     console(p .. ": <Need an Information Entry here>")
  3905.                 end
  3906.             end
  3907.         end
  3908.        
  3909.         console("\n ")
  3910.         for i = 2, #commands.info[cmd] do
  3911.             console(commands.info[cmd][i])
  3912.         end
  3913.        
  3914.         return true
  3915.     end
  3916.    
  3917.     console("Invalid Command.")
  3918.     return false
  3919. end
  3920.  
  3921. -- Command Rewrites --
  3922.  
  3923. -- Rewrites
  3924.  
  3925. --[[ Rewritten Halo DS Command Functions ]]--
  3926.  
  3927. local function getPrint(command)
  3928.  
  3929.     local msg = svcmd(command, 16)
  3930.     return string.split(msg, "\n")
  3931. end
  3932.  
  3933. function defcmd(player, command)
  3934.  
  3935.     local hash = gethash(player)
  3936.     execute_original = true
  3937.     if hash then
  3938.         if chat[hash] then
  3939.             local msgs = getPrint(command)
  3940.             for _,v in ipairs(msgs) do
  3941.                 console(v)
  3942.             end
  3943.         else
  3944.             svcmd(command, player)
  3945.         end
  3946.     else
  3947.         svcmd(command)
  3948.     end
  3949. end
  3950.  
  3951. -- Ban Commands
  3952.  
  3953.     banned = table.load("banlist") or {}
  3954.  
  3955. local function toSeconds(entry)
  3956.  
  3957.     if entry then
  3958.         if string.find(entry, "inf") then
  3959.             return -1
  3960.         elseif tonumber(entry) then
  3961.             return tonumber(entry) * 60 * 60 * 24
  3962.         elseif entry == "0s" then
  3963.             return 0
  3964.         else
  3965.             local time = 0
  3966.             local num = ""
  3967.             for i = 1, string.len(entry) do
  3968.                 local char = string.sub(entry, i, i)
  3969.                 if tonumber(char) then
  3970.                     num = num .. char
  3971.                 else
  3972.                     local seconds = 0
  3973.                     if char == "s" then
  3974.                         seconds = tonumber(num)
  3975.                     elseif char == "m" then
  3976.                         seconds = tonumber(num) * 60
  3977.                     elseif char == "h" then
  3978.                         seconds = tonumber(num) * 60 * 60
  3979.                     elseif char == "d" then
  3980.                         seconds = tonumber(num) * 60 * 60 * 24
  3981.                     end
  3982.                    
  3983.                     time = time + seconds
  3984.                     num = ""
  3985.                 end
  3986.             end
  3987.            
  3988.             if time > 0 then
  3989.                 return time
  3990.             end
  3991.         end
  3992.     end
  3993. end
  3994.  
  3995. function banpenalty(bancount, penalty)
  3996.  
  3997.     if tonumber(bancount) then
  3998.         bancount = tonumber(bancount)
  3999.         if penalty ~= "" then
  4000.        
  4001.             local bantime = toSeconds(penalty)
  4002.        
  4003.             if bantime then
  4004.                 values.banpenalty = values.banpenalty or {}
  4005.                 values.banpenalty[bancount] = bantime
  4006.             else
  4007.                 return "Invalid Ban Penalty."
  4008.             end
  4009.         else
  4010.             values.banpenalty[bancount] = nil
  4011.         end
  4012.     else
  4013.         return "Invalid Bancount."
  4014.     end
  4015. end
  4016.  
  4017. function sv_ban_penalty(admin, bancount, penalty)
  4018.  
  4019.     if bancount then
  4020.         if penalty then
  4021.             local err = banpenalty(bancount, penalty)
  4022.            
  4023.             if not err then
  4024.                 if penalty ~= "" then
  4025.                     local bantime = toSeconds(penalty)
  4026.                     console("Bancount   Penalty")
  4027.                     console("[" .. bancount .. "]       " .. secondsToTime(bantime))
  4028.                 else
  4029.                     console("There is no longer a default Ban Penalty for players who have been banned " .. bancount .. " times.")
  4030.                 end
  4031.                
  4032.                 return true
  4033.             end
  4034.            
  4035.             console(err)
  4036.             return false
  4037.         else
  4038.             if tonumber(bancount) then
  4039.                 bancount = tonumber(bancount)
  4040.                 if values.banpenalty[bancount] then
  4041.                     console("Bancount: " .. bancount .. " | Penalty: " .. secondsToTime(values.banpenalty[bancount]))
  4042.                     return true
  4043.                 else
  4044.                     console("There is no specific penalty for being banned " .. bancount .. " times.")
  4045.                 end
  4046.             else
  4047.                 console("Invalid Bancount.")
  4048.             end
  4049.            
  4050.             return false
  4051.         end
  4052.     else
  4053.         local bancounts = {}
  4054.         for k,v in pairs(values.banpenalty) do
  4055.             table.insert(bancounts, k)
  4056.         end
  4057.         table.sort(bancounts, function(a, b) return a < b end)
  4058.         console("Bancount   Penalty")
  4059.         for k,v in ipairs(bancounts) do
  4060.             console("[" .. v .. "]       " .. secondsToTime(values.banpenalty[v]))
  4061.         end
  4062.        
  4063.         return true
  4064.     end
  4065. end
  4066.  
  4067. -- Ban Updating
  4068.     if not values.banpenalty then
  4069.         banpenalty(1, "inf")
  4070.     end
  4071.  
  4072. function BanTimer(id, count)
  4073.  
  4074.     for k,v in ipairs(banned) do
  4075.         players[v].bantime = players[v].bantime - 1
  4076.         if math.ceil(players[v].bantime) == 0 then
  4077.             unban(v)
  4078.         end
  4079.     end
  4080.    
  4081.     return 1
  4082. end
  4083.  
  4084. function ban(id, name, bantime)
  4085.    
  4086.     if not toSeconds(bantime) then
  4087.         name = bantime
  4088.         bantime = nil
  4089.     end
  4090.    
  4091.     local hash = tohash(id, false, -1, name)
  4092.    
  4093.     if hash then
  4094.         if not players[hash].banned then
  4095.             local player = hashtoplayer(hash)
  4096.             if player then
  4097.                 local playernum = resolveplayer(player)
  4098.                
  4099.                 execute_original = true
  4100.                 svcmd("sv_ban " .. playernum)
  4101.                
  4102.                 players[hash].banned = true
  4103.                 players[hash].bancount = players[hash].bancount + 1
  4104.                 players[hash].bantime = players[hash].bantime or toSeconds(bantime) or values.banpenalty[players[hash].bancount] or -1
  4105.                
  4106.                 table.insert(banned, hash)
  4107.             else
  4108.                 players[hash].bos = true
  4109.                 players[hash].bantime = toSeconds(bantime) or values.banpenalty[players[hash].bancount] or -1
  4110.             end
  4111.         else
  4112.              return players[hash].name .. " is already banned."
  4113.         end
  4114.     else
  4115.         return "Invalid Player."
  4116.     end
  4117. end
  4118.  
  4119. function sv_ban(admin, id, bantime)
  4120.  
  4121.     local hash = tohash(id, true, admin)
  4122.    
  4123.     if hash then
  4124.         local name
  4125.         if players[hash] then
  4126.             name = players[hash].name
  4127.         else
  4128.             name = "Anonymous"
  4129.         end
  4130.  
  4131.         local err = ban(hash, name, bantime)
  4132.         if not err then
  4133.             if hashtoplayer(hash) then
  4134.                 console("[" .. players[hash].index .. "] " .. getname(hashtoplayer(hash)) .. " has been banned for " .. secondsToTime(players[hash].bantime) .. ".")
  4135.                 say(getname(hashtoplayer(hash)) .. " has been banned.")
  4136.             else
  4137.                 console("[" .. players[hash].index .. "] " .. players[hash].name .. " will be banned on sight.")
  4138.             end
  4139.            
  4140.             return true
  4141.         else
  4142.             console(err)
  4143.         end
  4144.     else
  4145.         console("Invalid Player.")
  4146.     end
  4147.    
  4148.     return false
  4149. end
  4150.  
  4151. function unban(id)
  4152.  
  4153.     local hash = tohash(id)
  4154.    
  4155.     if hash then
  4156.         local dir = getprofilepath()
  4157.         local banlist = io.open(dir .. "\\banned.txt", "r")
  4158.         if banlist then
  4159.             local index = -1
  4160.             for line in banlist:lines() do
  4161.                 local info = string.split(line, ",")
  4162.                 if hash == info[2] then
  4163.                
  4164.                     execute_original = true
  4165.                     svcmd("sv_unban " .. index)
  4166.                     banlist:close()
  4167.                    
  4168.                     for k,v in ipairs(banned) do
  4169.                         if v == hash then
  4170.                             table.remove(banned, k)
  4171.                         end
  4172.                     end
  4173.                    
  4174.                     players[hash].banned = false
  4175.                     players[hash].bantime = nil
  4176.                     return nil
  4177.                 end
  4178.                 index = index + 1
  4179.             end
  4180.             banlist:close()
  4181.             return players[hash].name .. " is not banned."
  4182.         else
  4183.             return "Unable to access banlist file."
  4184.         end
  4185.     else
  4186.         return "Invalid Player."
  4187.     end    
  4188. end
  4189.  
  4190. function sv_unban(admin, id)
  4191.  
  4192.     local hash = tohash(id, true, admin)
  4193.     local err = unban(hash)
  4194.     if not err then
  4195.         console("[" .. players[hash].index .. "] " .. players[hash].name .. " has been unbanned.")
  4196.         return true
  4197.     end
  4198.    
  4199.     console(err)
  4200.     return false
  4201. end
  4202.  
  4203. function sv_banlist(admin)
  4204.    
  4205.     local banlist = {}
  4206.     for _,v in ipairs(banned) do
  4207.         table.insert(banlist, "[" .. players[v].index .. "] " .. players[v].name .. " (" .. players[v].bancount .. ")")
  4208.     end
  4209.    
  4210.     if #banlist > 0 then
  4211.         console("Banned players by Server Index, Name, and Bancount:")
  4212.         local mprint = printlist(banlist, 3, " | ")
  4213.         for _,v in ipairs(mprint) do
  4214.             console(v)
  4215.         end
  4216.     else
  4217.         console("The banlist is empty.")
  4218.     end
  4219.    
  4220.     return true
  4221. end
  4222.  
  4223. -- Kick
  4224. function sv_kick(admin, id)
  4225.  
  4226.     local hash = tohash(id, true, admin)
  4227.    
  4228.     if hash then
  4229.         local player = hashtoplayer(hash)
  4230.         if player then
  4231.             local playernum = resolveplayer(player)
  4232.            
  4233.             execute_original = true
  4234.             svcmd("sv_kick " .. playernum)
  4235.            
  4236.             players[hash].kickcount = players[hash].kickcount + 1
  4237.            
  4238.             console("[" .. players[hash].index .. "] " .. getname(player) .. " has been kicked.")
  4239.             say(getname(player) .. " has been kicked.")
  4240.            
  4241.             if players[hash].kickcount > 4 then
  4242.                 console(getname(player) .. " has been kicked " .. players[hash].kickcount .. " times.  Consider a ban if their behavior continues.")
  4243.             end
  4244.            
  4245.             return true
  4246.         else
  4247.             console(players[hash].name .. " is not currently in the server.")
  4248.         end
  4249.     else
  4250.         console("Invalid Player.")
  4251.     end
  4252.    
  4253.     return false
  4254. end
  4255.  
  4256. -- Friendly Fire
  4257. function sv_friendly_fire(admin, entry)
  4258.  
  4259.     if entry then
  4260.         local value
  4261.        
  4262.         if string.find(entry, "def") then
  4263.             value = 0
  4264.         elseif entry == "off" then
  4265.             value = 1
  4266.         elseif string.find(entry, "shiel") then
  4267.             value = 2
  4268.         elseif entry == "on" then
  4269.             value = 3
  4270.         else
  4271.             value = tonumber(entry)
  4272.         end
  4273.        
  4274.         if value then
  4275.             defcmd(admin, "sv_friendly_fire " .. value)
  4276.         else
  4277.             console("Invalid Value.")
  4278.         end
  4279.     else
  4280.         defcmd(admin, "sv_friendly_fire")
  4281.         return true
  4282.     end
  4283.        
  4284.     return false
  4285. end
  4286.  
  4287. -- Gamelist
  4288. function sv_gamelist(admin, search)
  4289.  
  4290.     defcmd(admin, "sv_gamelist " .. (search or '""'))
  4291.     return true
  4292. end
  4293.  
  4294. -- Map Commands
  4295. function sv_map(admin, map, gametype, ...)
  4296.  
  4297.     defcmd(admin, "sv_map " .. map .. " " .. gametype .. " " .. table.concat({...}, " "))  
  4298.     return true
  4299. end
  4300.  
  4301. function sv_map_next(admin)
  4302.  
  4303.     defcmd(admin, "sv_map_next")
  4304.     return true
  4305. end
  4306.  
  4307. function sv_map_reset(admin, count)
  4308.  
  4309.     if count then
  4310.         if tonumber(count) then
  4311.             registertimer(500, "MapResetTimer", tonumber(count))
  4312.             console("Map reset " .. count .. " times.")
  4313.             return true
  4314.         else
  4315.             console("Invalid Count.")
  4316.         end
  4317.     else
  4318.         defcmd(admin, "sv_map_reset")
  4319.         return true
  4320.     end
  4321.    
  4322.     return false
  4323. end
  4324.  
  4325. function MapResetTimer(id, count, times)
  4326.  
  4327.     if count <= times then
  4328.         svcmd("sv_map_reset")
  4329.         return 1
  4330.     end
  4331.    
  4332.     return 0
  4333. end
  4334.  
  4335. function sv_mapcycle(admin)
  4336.  
  4337.     defcmd(admin, "sv_mapcycle")
  4338.     return true
  4339. end
  4340.  
  4341. function sv_mapcycle_add(admin, map, gametype, ...)
  4342.  
  4343.     defcmd(admin, "sv_mapcycle_add " .. map .. " " .. gametype .. " " .. (... or ""))
  4344.     return true
  4345. end
  4346.  
  4347. function sv_mapcycle_del(admin, index)
  4348.  
  4349.     defcmd(admin, "sv_mapcycle_del " .. index)
  4350.     return true
  4351. end
  4352.  
  4353. function sv_mapcycle_begin(admin)
  4354.  
  4355.     defcmd(admin, "sv_mapcycle_begin")
  4356.     return true
  4357. end
  4358.  
  4359. function sv_mapvote(admin, bool)
  4360.  
  4361.     defcmd(admin, "sv_mapvote " .. bool)
  4362. end
  4363.  
  4364. function sv_mapvote_add(admin, map, gametype, description, ...)
  4365.  
  4366.     defcmd(admin, "sv_mapvote_add " .. map .. " " .. gametype .. " " .. (... or ""))
  4367.     return true
  4368. end
  4369.  
  4370. function sv_mapvote_del(admin, index)
  4371.  
  4372.     defcmd(admin, "sv_mapvote_del " .. index)
  4373.     return true
  4374. end
  4375.  
  4376. function sv_mapvote_list(admin)
  4377.  
  4378.     defcmd(admin, "sv_mapvote_list")
  4379.     return true
  4380. end
  4381.  
  4382. function sv_mapcycle_timeout(admin, value)
  4383.  
  4384.     if value then
  4385.         if tonumber(value) then
  4386.             defcmd(admin, "sv_mapcycle_timeout " .. value)
  4387.             return true
  4388.         end
  4389.        
  4390.         console("Invalid Value.")
  4391.         return false
  4392.     end
  4393.    
  4394.     defcmd(admin, "sv_mapcycle_timeout")
  4395.     return true
  4396. end
  4397.  
  4398. function sv_maplist(admin, search)
  4399.  
  4400.     defcmd(admin, "sv_maplist " .. (search or "\b"))
  4401.     return true
  4402. end
  4403.  
  4404. function sv_maxplayers(admin, value)
  4405.  
  4406.     if value then
  4407.         if tonumber(value) then
  4408.             if tonumber(value) <= 16 then
  4409.                 defcmd(admin, "sv_maxplayers " .. value)
  4410.                 return true
  4411.             else
  4412.                 console("Maxplayers must be between 0 and 16.")
  4413.             end
  4414.         else
  4415.             console("Invalid Value.")
  4416.         end
  4417.     else
  4418.         defcmd(admin, "sv_maxplayers")
  4419.         return true
  4420.     end
  4421.    
  4422.     return false
  4423. end
  4424.  
  4425. function sv_name(admin, name)
  4426.  
  4427.     if name then
  4428.         defcmd(admin, "sv_name " .. name)
  4429.     else
  4430.         defcmd(admin, "sv_name")
  4431.     end
  4432.    
  4433.     return true
  4434. end
  4435.  
  4436. function sv_password(admin, password)
  4437.    
  4438.     local server_password = readstring(0x69B93C, 0x1, 8) -- Confirmed. Current server password for the server (will be nullstring if there is no password)
  4439.  
  4440.     if password then
  4441.         if string.len(password) <= 8 then
  4442.             defcmd(admin, "sv_password " .. password)
  4443.             return true
  4444.         else
  4445.             console("Password must be 8 characters or less.")
  4446.         end
  4447.     else
  4448.         defcmd(admin, "sv_password")
  4449.         return true
  4450.     end
  4451.    
  4452.     return false
  4453. end
  4454.  
  4455. function sv_public(admin, boolean)
  4456.    
  4457.     if boolean then
  4458.         if boolean == "1" or boolean == "true" then
  4459.             defcmd(admin, "sv_public 1")
  4460.         elseif boolean == "0" or boolean == "false" then
  4461.             defcmd(admin, "sv_public 0")
  4462.         else
  4463.             console("Invalid Boolean.")
  4464.             return false
  4465.         end
  4466.     else
  4467.         defcmd(admin, "sv_public")
  4468.     end
  4469.    
  4470.     return true
  4471. end
  4472.  
  4473. function sv_rcon_password(admin, password)
  4474.  
  4475.     local rcon_password = readstring(0x69BA5C, 0x0, 0x2C) -- Confirmed. Current rcon password for the server.
  4476.    
  4477.     if password then
  4478.         if string.len(password) <= 8 then
  4479.             defcmd(admin, "sv_rcon_password " .. password)
  4480.             return true
  4481.         else
  4482.             console("Password must be 8 characters or less.")
  4483.         end
  4484.     else
  4485.         defcmd(admin, "sv_rcon_password")
  4486.         return true
  4487.     end
  4488.    
  4489.     return false
  4490. end
  4491.  
  4492. function sv_single_flag_force_reset(admin, boolean)
  4493.  
  4494.     if boolean then
  4495.         if boolean == "1" or boolean == "true" then
  4496.             defcmd(admin, "sv_single_flag_force_reset 1")
  4497.         elseif boolean == "0" or boolean == "false" then
  4498.             defcmd(admin, "sv_single_flag_force_reset 0")
  4499.         else
  4500.             console("Invalid Boolean.")
  4501.             return false
  4502.         end
  4503.     else
  4504.         defcmd(admin, "sv_single_flag_force_reset")
  4505.     end
  4506.    
  4507.     return true
  4508. end
  4509.  
  4510. function sv_status(admin)
  4511.    
  4512.     defcmd(admin, "sv_status")
  4513.     return true
  4514. end
  4515.  
  4516. function sv_timelimit(admin, timelimit)
  4517.  
  4518.     local gametype_time_passed = readdword(readdword(gametype_base, 0xE0), 0xC) -- Confirmed. (1 second = 30 ticks)
  4519.  
  4520.     defcmd(admin, "sv_timelimit " .. (timelimit or "\b"))
  4521.     return true
  4522. end
  4523.  
  4524. function sv_tk_ban(admin, value)
  4525.  
  4526.     defcmd(admin, "sv_tk_ban " .. (value or "\b"))
  4527.     return true
  4528. end
  4529.  
  4530. function sv_tk_cooldown(admin, value)
  4531.  
  4532.     defcmd(admin, "sv_tk_cooldown " .. (value or "\b"))
  4533.     return true
  4534. end
  4535.  
  4536. function sv_tk_grace(admin, value)
  4537.  
  4538.     defcmd(admin, "sv_tk_grace " .. (value or "\b"))
  4539.     return true
  4540. end
  4541.  
  4542. --[[ Rewritten Phasor Command Functions ]]--
  4543.  
  4544. phasorinvis = applycamo
  4545.  
  4546. function sv_reloadscripts(admin)
  4547.  
  4548.     defcmd(admin, "sv_reloadscripts")
  4549.     return true
  4550. end
  4551.  
  4552. function sv_mapvote_begin(admin)
  4553.  
  4554.     defcmd(admin, "sv_mapvote_begin")
  4555.     return true
  4556. end
  4557.  
  4558. function sv_teams_balance(admin)
  4559.  
  4560.     defcmd(admin, "sv_teams_balance")
  4561.     return true
  4562. end
  4563.  
  4564. function sv_teams_lock(admin)
  4565.  
  4566.     defcmd(admin, "sv_teams_lock")
  4567.     return true
  4568. end
  4569.  
  4570. function sv_teams_unlock(admin)
  4571.  
  4572.     defcmd(admin, "sv_teams_unlock")
  4573.     return true
  4574. end
  4575.  
  4576. function sv_changeteam(admin, id)
  4577.  
  4578.     local hash = tohash(id, true, admin)
  4579.    
  4580.     if hash then
  4581.         local player = hashtoplayer(hash)
  4582.         if player then
  4583.             local playerId = resolveplayer(player)
  4584.             defcmd(admin, "sv_changeteam " .. playerId)
  4585.             return true
  4586.         else
  4587.             console(players[hash].name .. " is not currently in the server.")
  4588.         end
  4589.     else
  4590.         console("Invalid Player.")
  4591.     end
  4592.    
  4593.     return false
  4594. end
  4595.  
  4596. function teleport(id, ...)
  4597.  
  4598.     local hash = tohash(id)
  4599.    
  4600.     if hash then
  4601.         local player = hashtoplayer(hash)
  4602.         if player then
  4603.             if #args > 0 then
  4604.                 if #args == 1 then
  4605.                     local dir = getprofilepath()
  4606.                     local locations = io.open(dir .. "\\data\\locations.txt")
  4607.                     for line in locations:lines() do
  4608.                         local tokens = string.split(line, ",")
  4609.                         local map = tokens[1]
  4610.                         local name = tokens[2]
  4611.                         local x = tonumber(tokens[3])
  4612.                         local y = tonumber(tokens[4])
  4613.                         local z = tonumber(tokens[5])
  4614.                         if map == this.map then
  4615.                             if string.lower(args[1]) == string.lower(name) then
  4616.                                 teleport(id, x, y, z)
  4617.                             end
  4618.                         end
  4619.                     end
  4620.                     locations:close()
  4621.                 elseif #args == 3 then
  4622.                     local x = tonumber(args[1])
  4623.                     local y = tonumber(args[2])
  4624.                     local z = tonumber(args[3])
  4625.                    
  4626.                     local m_player = getplayer(player)
  4627.                     local m_objId = readdword(m_player, 0x34)
  4628.                     if m_objId ~= 0xFFFFFFFF then
  4629.                         movobjcoords(m_objId, x, y, z)
  4630.                     else
  4631.                         return getname(player) .. " is dead."
  4632.                     end
  4633.                 else
  4634.                     return "Invalid Location."
  4635.                 end
  4636.             else
  4637.                 return "Invalid Location."
  4638.             end
  4639.         else
  4640.             return players[hash].name .. " is not currently in the server."
  4641.         end
  4642.     else
  4643.         return "Invalid Player."
  4644.     end        
  4645. end
  4646.  
  4647. function sv_teleport(admin, id, ...)
  4648.  
  4649.     local hash = tohash(id, true, admin)
  4650.     local err = teleport(hash, ...)
  4651.    
  4652.     if not err then
  4653.         local player = hashtoplayer(hash)
  4654.         if #args == 1 then
  4655.             private(player, "You have been teleported to location \"" .. args[1] .. "\".")
  4656.             console(getname(player) .. " has been teleported to location \"" .. args[1] .. "\".")
  4657.         else
  4658.             private(player, "You have been teleported to [" .. args[1] .. "  " .. args[2] .. "  " .. args[3] .. "].")
  4659.             console(getname(player) .. " has been teleported to [" .. args[1] .. "  " .. args[2] .. "  " .. args[3] .. "].")
  4660.         end
  4661.        
  4662.         return true
  4663.     end
  4664.    
  4665.     console(err)
  4666.     return false
  4667. end
  4668.  
  4669. function sv_teleport_to(admin, tp_id, dest_id)
  4670.  
  4671.     local tp_hash = tohash(tp_id, true, admin)
  4672.     local dest_hash = tohash(dest_id, true, admin)
  4673.    
  4674.     if tp_hash then
  4675.         if dest_hash then
  4676.             local tp_player = hashtoplayer(tp_hash)
  4677.             local dest_player = hashtoplayer(dest_hash)
  4678.             if tp_player then
  4679.                 if dest_player then
  4680.                     local tp_playerId = resolveplayer(tp_player)
  4681.                     local dest_playerId = resolveplayer(dest_player)
  4682.                     defcmd(admin, "sv_teleport_pl " .. tp_playerId .. " " .. dest_playerId)
  4683.                     return true
  4684.                 else
  4685.                     console(players[dest_hash].name .. " is not currently in the server.")
  4686.                 end
  4687.             else
  4688.                 console(players[tp_hash].name .. " is not currently in the server.")
  4689.             end
  4690.         else
  4691.             console("Invalid Destination Player.")
  4692.         end
  4693.     else
  4694.         console("Invalid Teleporting Player.")
  4695.     end
  4696.    
  4697.     return false
  4698. end
  4699.  
  4700. function sv_teleport_add(admin, location, x, y, z)
  4701.  
  4702.     if not y and not z then
  4703.         defcmd(admin, "sv_teleport_add " .. location)
  4704.     else
  4705.         defcmd(admin, "sv_teleport_add " .. location .. " " .. x .. " " .. y .. " " .. (z or ""))
  4706.     end
  4707.    
  4708.     return true
  4709. end
  4710.  
  4711. function sv_teleport_del(admin, index)
  4712.  
  4713.     defcmd(admin, "sv_teleport_del " .. index)
  4714.     return true
  4715. end
  4716.  
  4717. function sv_teleport_list(admin)
  4718.  
  4719.     defcmd(admin, "sv_teleport_list")
  4720.     return true
  4721. end
  4722.  
  4723. function sv_kickafk(admin, time)
  4724.  
  4725.     defcmd(admin, "sv_kickafk " .. (time or ""))
  4726.     return true
  4727. end
  4728.  
  4729. function sv_host(admin, details)
  4730.  
  4731.     defcmd(admin, "sv_host " .. details)
  4732.     return true
  4733. end
  4734.  
  4735. function sv_say(admin, message)
  4736.  
  4737.     server(message)
  4738.     hprintf("**SERVER** " .. message)
  4739.     return true
  4740. end
  4741.  
  4742. function sv_gethash(admin, id)
  4743.  
  4744.     local hash = tohash(id, true, admin)
  4745.     if hash then
  4746.         console(hash)
  4747.         return true
  4748.     end
  4749.    
  4750.     console("Invalid Player.")
  4751.     return false
  4752. end
  4753.  
  4754. function sv_chatids(admin, boolean)
  4755.  
  4756.     defcmd(admin, "sv_chatids " .. (boolean or ""))
  4757.     return true
  4758. end
  4759.  
  4760. function sv_disablelog(admin)
  4761.  
  4762.     defcmd(admin, "sv_disablelog")
  4763.     return true
  4764. end
  4765.  
  4766. function sv_logname(admin, logtype, logname)
  4767.  
  4768.     defcmd(admin, "sv_logname " .. logtype .. " " .. logname)
  4769.     return true
  4770. end
  4771.  
  4772. function sv_savelog(admin)
  4773.  
  4774.     defcmd(admin, "sv_savelog")
  4775.     return true
  4776. end
  4777.  
  4778. function sv_loglimit(admin, logtype, logsize)
  4779.  
  4780.     defcmd(admin, "sv_loglimit " .. logtype .. " " .. logsize)
  4781.     return true
  4782. end
  4783.  
  4784. function sv_getobject(admin, id)
  4785.  
  4786.     local hash = tohash(id, true, admin)
  4787.     if hash then
  4788.         local player = hashtoplayer(hash)
  4789.         if player then
  4790.             local playerId = resolveplayer(player)
  4791.             defcmd(admin, "sv_getobject " .. playerId)
  4792.             return true
  4793.         else
  4794.             console(players[hash].name .. " is not currently in the server.")
  4795.         end
  4796.     else
  4797.         console("Invalid Player.")
  4798.     end
  4799.    
  4800.     return false
  4801. end
  4802.  
  4803. function sv_kill(admin, victim, killer)
  4804.  
  4805.     local hashes = pack(tohash(victim, true, admin))
  4806.     if #hashes > 1 then
  4807.         for _,v in ipairs(hashes) do
  4808.             sv_kill(admin, v, message)
  4809.         end
  4810.         server(toTeam(id) .. " players have been killed by the server.")
  4811.         return true
  4812.     else
  4813.         local hash = unpack(hashes)
  4814.         if hash then
  4815.             local player = hashtoplayer(hash)
  4816.             if player then
  4817.                 local m_player = getplayer(player)
  4818.                 local m_objId = readdword(m_player, 0x34)
  4819.                 local m_object = getobject(m_objId)
  4820.                 if m_object then
  4821.                     if not killer then
  4822.                         kill(player)
  4823.                         private(player, "You have been killed by the server.")
  4824.                         console(getname(player) .. " has been killed.")
  4825.                         return true
  4826.                     --[[else
  4827.                         local khash = tohash(killer, true, admin)
  4828.                         if khash then
  4829.                             local kplayer = hashtoplayer(khash)
  4830.                             if kplayer then
  4831.                                 local k_objId = readdword(m_player, 0x34)
  4832.                                 local k_object = getobject(k_objId)
  4833.                                 for i = 1, 50 do
  4834.                                     local x, y, z = getobjectcoords(m_objId)
  4835.                                     createobject("jpt!", "globals\\flaming_death", k_objId, 0, false, x, y, z)
  4836.                                 end
  4837.                                 console(getname(player) .. " was killed by " .. getname(kplayer))
  4838.                                 return true
  4839.                             else
  4840.                                 console(players[khash].name .. " is not currently in the server.")
  4841.                             end
  4842.                         else
  4843.                             console("Invalid Killer.")
  4844.                         end--]]
  4845.                     end
  4846.                 else
  4847.                     console(getname(player) .. " is already dead.")
  4848.                 end
  4849.             else
  4850.                 console(players[hash].name .. " is not currently in the server.")
  4851.             end
  4852.            
  4853.         else
  4854.             console("Invalid Player.")
  4855.         end
  4856.     end
  4857.    
  4858.     return false
  4859. end
  4860.  
  4861. -- Camo Stuff --
  4862. invis = {}
  4863.  
  4864. function applycamo(id, duration)
  4865.  
  4866.     local hash = tohash(id)
  4867.     if hash then
  4868.         local player = hashtoplayer(hash)
  4869.         if player then
  4870.             duration = tonumber(duration)
  4871.             if duration then
  4872.                 if duration > 0 then
  4873.                     invis[hash] = duration
  4874.                     registertimer(1000, "InvisTimer", player, duration)
  4875.                 else
  4876.                     invis[hash] = math.inf
  4877.                     registertimer(1000, "InvisTimer", player, math.inf)
  4878.                 end
  4879.             end
  4880.         end
  4881.     end
  4882. end
  4883.  
  4884. function sv_invis(admin, id, duration)
  4885.    
  4886.     if id then
  4887.         if not duration or tonumber(duration) then
  4888.             local hashes = pack(tohash(id, true, admin))
  4889.             if #hashes > 1 then
  4890.                 for _,v in ipairs(hashes) do
  4891.                     sv_invis(admin, v, duration)
  4892.                 end
  4893.                 if duration then
  4894.                     server(toTeam(id) .. " players have been given camouflage for " .. duration .. " seconds.")
  4895.                 else
  4896.                     server(toTeam(id) .. " players have been given camouflage until death.")
  4897.                 end
  4898.                 return true
  4899.             else
  4900.                 local hash = unpack(hashes)
  4901.                 if hash then
  4902.                     local player = hashtoplayer(hash)
  4903.                     if player then
  4904.                         duration = tonumber(duration)
  4905.                         if duration then
  4906.                             if duration >= 1093 then
  4907.                                 duration = nil
  4908.                             end
  4909.                         end
  4910.                         if duration then
  4911.                             invis[hash] = duration
  4912.                             registertimer(1000, "InvisTimer", player, duration)
  4913.                             private(player, "You have been given camouflage for " .. duration .. " seconds.")
  4914.                             console(getname(player) .. " has been given camouflage for " .. duration .. " seconds.")
  4915.                         else
  4916.                             invis[hash] = math.inf
  4917.                             registertimer(1000, "InvisTimer", player, math.inf)
  4918.                             private(player, "You have been given camouflage until death.")
  4919.                             console(getname(player) .. " has been given camouflage until death.")
  4920.                         end
  4921.                        
  4922.                         return true
  4923.                     else
  4924.                         console(players[hash].name .. " is not currently in the server.")
  4925.                     end
  4926.                 else
  4927.                     console("Invalid Player.")
  4928.                 end
  4929.             end
  4930.         else
  4931.             console("Invalid Duration.")
  4932.         end
  4933.     else
  4934.         local pl = {}
  4935.         for i = 0, 15 do
  4936.             local hash = gethash(i)
  4937.             if hash then
  4938.                 local invistime = invis[hash]
  4939.                 if invistime then
  4940.                     if invistime > 0 then
  4941.                         if invistime < 1093 then
  4942.                             table.insert(pl, getname(i) .. ": " .. invistime .. " seconds")
  4943.                         else
  4944.                             table.insert(pl, getname(i) .. ": Until Death")
  4945.                         end
  4946.                     end
  4947.                 end
  4948.             end
  4949.         end
  4950.         if #pl > 0 then
  4951.             console("Invisible players and Invis Time left:")
  4952.             for k,v in ipairs(pl) do
  4953.                 console(v)
  4954.             end
  4955.         else
  4956.             console("No players are currently invisible.")
  4957.         end
  4958.        
  4959.         return true
  4960.     end
  4961.    
  4962.     return false
  4963. end
  4964.  
  4965. function InvisTimer(id, count, player, duration)
  4966.  
  4967.     local hash = gethash(player)
  4968.     if hash then
  4969.         if invis[hash] then
  4970.             invis[hash] = invis[hash] - 1
  4971.             if invis[hash] > 0 then
  4972.                 phasorinvis(player, 1)
  4973.                 return 1
  4974.             end
  4975.         end
  4976.     end
  4977.    
  4978.     return 0
  4979. end
  4980.  
  4981. function sv_uninvis(admin, id)
  4982.  
  4983.     local hashes = pack(tohash(id, true, admin))
  4984.     if #hashes > 1 then
  4985.         for _,v in ipairs(hashes) do
  4986.             sv_uninvis(admin, v)
  4987.         end
  4988.         server(toTeam(id) .. " players are no longer invisible.")
  4989.     else
  4990.         local hash = unpack(hashes)
  4991.         if hash then
  4992.             local player = hashtoplayer(hash)
  4993.             if player then
  4994.                 if invis[hash] then
  4995.                     invis[hash] = nil
  4996.                     console(players[hash].name .. " is no longer invisible.")
  4997.                 else
  4998.                     console(players[hash].name .. " is not invisible.")
  4999.                 end
  5000.                
  5001.                 return true
  5002.             else
  5003.                 console(players[hash].name .. " is not currently in the server.")
  5004.             end
  5005.         else
  5006.             console("Invalid Player.")
  5007.         end
  5008.     end
  5009.    
  5010.     return false
  5011. end
  5012.  
  5013. function setspeed(id, speed, duration)
  5014.  
  5015.     local hash = tohash(id)
  5016.     if hash then
  5017.         local player = hashtoplayer(hash)
  5018.         if player then
  5019.             local m_player = getplayer(player)
  5020.             if m_player then
  5021.                 local cur_speed = readfloat(m_player, 0x6C)
  5022.                 if tonumber(speed) then
  5023.                     writefloat(m_player, 0x6C, tonumber(speed))
  5024.                     if duration then
  5025.                         if tonumber(duration) then
  5026.                             registertimer(1000, "SpeedTimer", player, tonumber(duration), cur_speed)
  5027.                         else
  5028.                             return "Invalid Duration Entry."
  5029.                         end
  5030.                     end
  5031.                 else
  5032.                     local value = editValue(cur_speed, speed)
  5033.                     if value then
  5034.                         writefloat(m_player, 0x6C, value)
  5035.                     else
  5036.                         return "Invalid Speed Entry."
  5037.                     end
  5038.                 end
  5039.             else
  5040.                 return players[hash].name .. " is inaccessible at this time."
  5041.             end
  5042.         else
  5043.             return players[hash].name .. " is not currently in the server."
  5044.         end
  5045.     else
  5046.         return "Invalid Player."
  5047.     end
  5048. end
  5049.  
  5050. function getspeed(id)
  5051.  
  5052.     local hash = tohash(id)
  5053.     if hash then
  5054.         local player = hashtoplayer(id)
  5055.         if player then
  5056.             local m_player = getplayer(player)
  5057.             if m_player then
  5058.                 return readfloat(m_player, 0x6C)
  5059.             end
  5060.         end
  5061.     end
  5062. end
  5063.  
  5064. function sv_setspeed(admin, id, speed, duration)
  5065.  
  5066.     local hashes = pack(tohash(id, true, admin))
  5067.     if #hashes > 1 then
  5068.         for _,v in ipairs(hashes) do
  5069.             local executed = sv_setspeed(v, speed, duration)
  5070.             if not executed then
  5071.                 return false
  5072.             end
  5073.         end
  5074.         if tonumber(speed) then
  5075.             server(toTeam(id) .. " players' speeds have been changed to " .. speed)
  5076.         else
  5077.             server(toTeam(id) .. " players' speeds have been edited.")
  5078.         end
  5079.         return true
  5080.     else
  5081.         local hash = unpack(hashes)
  5082.         if hash then
  5083.             local err = setspeed(hash, speed, duration)
  5084.             if not err then
  5085.                 local player = hashtoplayer(hash)
  5086.                 local cur_speed = getspeed(hash)
  5087.                 local new_speed = editValue(cur_speed, speed)
  5088.                 if not duration then
  5089.                     private(player, "Your speed has been changed to " .. math.round(new_speed, 2) .. ".")
  5090.                 else
  5091.                     private(player, "Your speed has been changed to " .. math.round(new_speed, 2) .. " for " .. duration .. " seconds.")
  5092.                 end
  5093.                 return true
  5094.             else
  5095.                 console(err)
  5096.             end
  5097.         else
  5098.             console("Invalid Player.")
  5099.         end
  5100.     end
  5101.    
  5102.     return false
  5103. end
  5104.  
  5105. function SpeedTimer(id, count, player, duration, old_speed)
  5106.  
  5107.     if count >= duration then
  5108.         setspeed(player, old_speed)
  5109.         hprint(player, "Your speed is now " .. math.round(old_speed, 2) .. ".")
  5110.         return 0
  5111.     elseif count >= duration - 5 then
  5112.         hprint(player, "Your speed will return to " .. math.round(old_speed, 2) .. " in " .. math.ceil(duration - count) .. " seconds.", 1)
  5113.     end
  5114.    
  5115.     return 1
  5116. end
  5117.  
  5118. -- Object Functions --
  5119.  
  5120. local function newObjectIndex()
  5121.  
  5122.     local id = convertbase((objects.unique or 1) - 1, 36)
  5123.     while string.len(id) < 4 do
  5124.         id = "0" .. id
  5125.     end
  5126.  
  5127.     return id
  5128. end
  5129.  
  5130. function isDestroyed(m_objId)
  5131.  
  5132.     if getobject(m_objId) then
  5133.         return false
  5134.     end
  5135.    
  5136.     return true
  5137. end
  5138.  
  5139. function newObject(m_objId)
  5140.  
  5141.     objects.unique = (objects.unique or 0) + 1
  5142.     local tagtype, tagname = getobjecttag(m_objId)
  5143.     m_objId = tostring(m_objId)
  5144.    
  5145.     objects[m_objId] = {}
  5146.     objects[m_objId].tagtype = tagtype
  5147.     objects[m_objId].tagname = tagname
  5148.     objects[m_objId].index = newObjectIndex()
  5149. end
  5150.  
  5151. function getobjid(id)
  5152.  
  5153.     if string.len(id) == 4 then
  5154.         for k,v in pairs(objects) do
  5155.             if k ~= "unique" then
  5156.                 if objects[k].index == id then
  5157.                     return k
  5158.                 end
  5159.             end
  5160.         end
  5161.     else
  5162.         if getobject(id) then
  5163.             return id
  5164.         end
  5165.     end
  5166. end
  5167.  
  5168. function toTag(search)
  5169.  
  5170.     search = string.lower(search)
  5171.     local matches = {}
  5172.    
  5173.     local function matchAdd(tagtype, tagname)
  5174.    
  5175.         local tag = {tagtype, tagname}
  5176.         table.insert(matches, tag)
  5177.     end
  5178.    
  5179.     -- Check if search is a tag type (i.e. "weap", "proj", "jpt!", etc)
  5180.     for t,v in pairs(tags) do
  5181.         t = string.lower(t)
  5182.         if search == t then
  5183.             for n,s in pairs(v) do
  5184.                 matchAdd(t, n)
  5185.             end
  5186.             return unpack(matches)
  5187.         end
  5188.     end
  5189.    
  5190.     -- Check if search is a tag name (i.e. "weapons\\assault rifle\\assault rifle") or a shortcut exactly (i.e. "Assault Rifle")
  5191.     for t,v in pairs(tags) do
  5192.         for n,s in pairs(v) do
  5193.             n = string.lower(n)
  5194.             s = string.lower(s)
  5195.             if search == n or search == s then
  5196.                 return {t, n}
  5197.             end
  5198.         end
  5199.     end
  5200.    
  5201.     -- Key words
  5202.     -- Exact matches:
  5203.     -- Scenery Items:
  5204.     if search == "rock" or search == "rocks" or search == "boulder" or search == "boulders" then
  5205.         for n,s in pairs(tags.scen) do
  5206.             s = string.lower(s)
  5207.             if string.find(s, "rock") or string.find(s, "boulder") then
  5208.                 matchAdd("scen", n)
  5209.             end
  5210.         end
  5211.         return unpack(matches)
  5212.     elseif search == "tree" or search == "trees" then
  5213.         for n,s in pairs(tags.scen) do
  5214.             s = string.lower(s)
  5215.             if string.find(s, "tree") then
  5216.                 matchAdd("scen", n)
  5217.             end
  5218.         end
  5219.         return unpack(matches)
  5220.     elseif search == "bush" or search == "bushes" or search == "shrub" or search == "shrubs" then
  5221.         for n,s in pairs(tags.scen) do
  5222.             s = string.lower(s)
  5223.             if string.find(s, "shrub") or string.find(s, "fern") or string.find(s, "broadleaf") then
  5224.                 matchAdd("scen", n)
  5225.             end
  5226.         end
  5227.         return unpack(matches)
  5228.     elseif search == "shield" then
  5229.         return {"scen", "scenery\\c_field_generator\\c_field_generator"}
  5230.     -- Projectile:
  5231.     elseif search == "needle" then
  5232.         return {"proj", "weapons\\needler\\mp_needle"}
  5233.     -- Weapons:
  5234.     elseif search == "rocket" then
  5235.         return {"weap", "weapons\\rocket launcher\\rocket launcher"}
  5236.     elseif search == "ar" or search == "assaultrifle" then
  5237.         return {"weap", "weapons\\assault rifle\\assault rifle"}
  5238.     elseif search == "pp" or search == "plasmapistol" then
  5239.         return {"weap", "weapons\\plasma pistol\\plasma pistol"}
  5240.     elseif search == "pr" or search == "plasmarifle" then
  5241.         return {"weap", "weapons\\plasma rifle\\plasma rifle"}
  5242.     elseif search == "sniper" then
  5243.         return {"weap", "weapons\\sniper rifle\\sniper rifle"}
  5244.     elseif search == "ball" then
  5245.         return {"weap", "weapons\\ball\\ball"}
  5246.     elseif search == "flag" then
  5247.         return {"weap", "weapons\\flag\\flag"}
  5248.     -- Powerups:
  5249.     elseif search == "camo" or search == "invis" then
  5250.         return {"eqip", "powerups\\active camouflage"}
  5251.     elseif search == "os" then
  5252.         return {"eqip", "powerups\\over shield"}
  5253.     elseif search == "doublespd" or search == "dblspd" then
  5254.         return {"eqip", "powerups\\double speed"}
  5255.     -- Vehicles:
  5256.     elseif search == "hog" then
  5257.         return {"vehi", "vehicles\\warthog\\mp_warthog"}
  5258.     elseif search == "rockethog" or search == "rocket hog" then
  5259.         return {"vehi", "vehicles\\rwarthog\\rwarthog"}
  5260.     elseif search == "shee" then
  5261.         return {"vehi", "vehicles\\banshee\\banshee_mp"}
  5262.     elseif search == "turret" then
  5263.         return {"vehi", "vehicles\\c gun turret\\c gun turret_mp"}
  5264.     elseif search == "tank" or search == "scorp" then
  5265.         return {"vehi", "vehicles\\scorpion\\scorpion_mp"}
  5266.     -- Biped:
  5267.     elseif search == "cyborg" or search == "masterchief" or search == "mc" then
  5268.         return {"bipd", "characters\\cyborg_mp\\cyborg_mp"}
  5269.     end
  5270.    
  5271.     -- Loose search
  5272.     -- Projectiles:
  5273.     if string.find(search, "proj") then
  5274.         if string.find(search, "rocket") then
  5275.             return {"proj", "weapons\\rocket launcher\\rocket"}
  5276.         elseif string.find(search, "flamethrower") then
  5277.             return {"proj", "weapons\\flamethrower\\flame"}
  5278.         end
  5279.     end
  5280.     search = search:gsub("tank", "scorpion")
  5281.     search = search:gsub("rocket", "Rocket")
  5282.     search = search:gsub("rock", "rock boulder")
  5283.     search = search:gsub("boulder", "rock boulder")
  5284.     search = string.lower(search)
  5285.     for t,v in pairs(tags) do
  5286.         for n,s in pairs(v) do
  5287.             n = string.lower(n)
  5288.             s = string.lower(s)
  5289.             if string.find(n, search) or string.find(s, search) then
  5290.                 matchAdd(t, n)
  5291.             end
  5292.         end
  5293.     end
  5294.    
  5295.     return unpack(matches)
  5296. end
  5297.  
  5298. function sv_objects(admin, search)
  5299.  
  5300.     local matches = {}
  5301.     if not search then
  5302.         for k,v in pairs(objects) do
  5303.             if k ~= "unique" then
  5304.                 table.insert(matches, k)
  5305.             end
  5306.         end
  5307.     else
  5308.         local tags = pack(toTag(search))
  5309.         if unpack(tags) then
  5310.             for k,v in pairs(objects) do
  5311.                 if k ~= "unique" then
  5312.                     for _,t in ipairs(tags) do
  5313.                         if objects[k].tagname == t[2] then
  5314.                             table.insert(matches, k)
  5315.                         end
  5316.                     end
  5317.                 end
  5318.             end
  5319.         end
  5320.     end
  5321.    
  5322.     if unpack(matches) then
  5323.         table.sort(matches)
  5324.         console("Objects matching search \"" .. (search or "") .. "\":")
  5325.         local count = 0
  5326.         for k,v in ipairs(matches) do
  5327.             if gethash(admin) then
  5328.                 if count == 20 then break end
  5329.             else
  5330.                 console("[" .. objects[v].index .. "] " .. objects[v].tagname)
  5331.                 count = count + 1
  5332.             end
  5333.         end
  5334.     else
  5335.         console("Your search returned no matches.")
  5336.     end
  5337.    
  5338.     return true
  5339. end
  5340.  
  5341. function sv_destroy(admin, id)
  5342.  
  5343.     local m_objId = getobjid(id)
  5344.     if m_objId then
  5345.         destroyobject(m_objId)
  5346.         console("[" .. id .. "] \"" .. objects[m_objId].tagname .. "\" destroyed.")
  5347.     else
  5348.         local matches = {}
  5349.         local tagmatches = pack(toTag(id))
  5350.         if unpack(tagmatches) then                     
  5351.             for _,t in ipairs(tagmatches) do
  5352.                 for k,v in pairs(objects) do
  5353.                     if k ~= "unique" then
  5354.                         if not objects[k].destroyed then
  5355.                             if objects[k].tagname == t[2] then
  5356.                                 local tagType, tagName = objects[k].tagtype, objects[k].tagname
  5357.                                 local name = tags[tagType][tagName]
  5358.                                 destroyobject(k)
  5359.                                 table.insert(matches, name)
  5360.                             end
  5361.                         end
  5362.                     end
  5363.                 end
  5364.             end
  5365.         end
  5366.        
  5367.         if unpack(matches) then
  5368.             local matches2 = {}
  5369.             for k,v in ipairs(matches) do
  5370.                 if not table.find(matches2, v) then
  5371.                     table.insert(matches2, v)
  5372.                 end
  5373.             end
  5374.             console("Objects destroyed:")
  5375.             local mprint = printlist(matches2, 5, "   ")
  5376.             for k,v in ipairs(mprint) do
  5377.                 console(v)
  5378.             end
  5379.             server("The following objects have been destroyed:")
  5380.             local mprint2 = printlist(matches2, 5, " | ")
  5381.             for k,v in ipairs(mprint2) do
  5382.                 server(v)
  5383.             end
  5384.         else
  5385.             console("Your search returned no matches.")
  5386.         end
  5387.     end
  5388.    
  5389.     return true
  5390. end
  5391.  
  5392. function sv_create(admin, id, search, respawn_time, x, y, z)
  5393.  
  5394.     id = id or admin
  5395.     respawn_time = tonumber(respawn_time or 0)
  5396.    
  5397.     local tagTable = toTag(search)
  5398.     local tagType, tagName = unpack(tagTable)
  5399.     if tagType and tagName then
  5400.         if respawn_time then
  5401.             if (not x and not y and not z) or (tonumber(x) and tonumber(y) and tonumber(z)) then
  5402.                 local hashes = pack(tohash(id, true, admin))
  5403.                 if #hashes > 1 then
  5404.                     for _,v in ipairs(hashes) do
  5405.                         sv_create(admin, v, object, respawn_time, x, y, z)
  5406.                     end
  5407.                     server("A " .. tags[tagType][tagName] .. " has spawned at " .. toTeam(id) .. " players' locations.")
  5408.                     return true
  5409.                 else
  5410.                     local hash = unpack(hashes)
  5411.                     if hash then
  5412.                         local player = hashtoplayer(hash)
  5413.                         if player then
  5414.                             local m_player = getplayer(player)
  5415.                             local m_objId = readdword(m_player, 0x34)
  5416.                             local m_object = getobject(m_objId)
  5417.                             if m_object then
  5418.                                 local px, py, pz = getobjectcoords(m_objId)
  5419.                                 local camera_base = 0x69C2F8
  5420.                                 local aim = readfloat(camera_base, 0x30 * player)
  5421.                                 if not x and not y and not z then
  5422.                                     if tagType == "vehi" then
  5423.                                         aim = aim - math.pi / 12
  5424.                                         x = px + math.cos(aim) * 4
  5425.                                         y = py + math.sin(aim) * 4
  5426.                                         z = pz + 1
  5427.                                     elseif tagType == "weap" or tagType == "eqip" then
  5428.                                         x = px + math.cos(aim) * 2.5
  5429.                                         y = py + math.sin(aim) * 2.5
  5430.                                         z = pz + 1
  5431.                                     elseif tagType == "proj" then
  5432.                                         x = px
  5433.                                         y = py
  5434.                                         z = pz + 1.5
  5435.                                     else
  5436.                                         x = px
  5437.                                         y = py
  5438.                                         z = pz
  5439.                                     end
  5440.                                 end
  5441.                                
  5442.                                 x, y, z = tonumber(x), tonumber(y), tonumber(z)
  5443.                                
  5444.                                 local respawn = false
  5445.                                 if respawn_time > 0 then
  5446.                                     respawn = true
  5447.                                 end
  5448.                                
  5449.                                 local new_objId = createobject(tagType, tagName, 0, respawn_time, respawn, x, y, z)
  5450.                                
  5451.                                 if tagType == "proj" then
  5452.                                     local new_object = getobject(new_objId)
  5453.                                     local z_aim = readfloat(camera_base, (0x30 * player) + 0x4)
  5454.                                     local vx = readfloat(new_object, 0x68)
  5455.                                     local vy = readfloat(new_object, 0x6C)
  5456.                                     local vz = readfloat(new_object, 0x70)
  5457.                                     local velocity = math.sqrt(vx ^ 2 + vy ^ 2 + vz ^ 2)
  5458.                                     writefloat(new_object, 0x68, velocity * math.cos(aim))
  5459.                                     writefloat(new_object, 0x6C, velocity * math.sin(aim))
  5460.                                     writefloat(new_object, 0x70, velocity * math.sin(z_aim))
  5461.                                 end
  5462.                                
  5463.                                 console("A " .. tags[tagType][tagName] .. " has spawned at " .. players[hash].name .. "'s location.")
  5464.                                 console("Coords |  x: " .. x .. " | y: " .. " | z: " .. z)
  5465.                                 console("Respawn: " .. tostring(respawn) .. " | Respawn Time: " .. respawn_time)
  5466.                                
  5467.                                 private(player, "A " .. tags[tagType][tagName] .. " has spawned at your location.")
  5468.                                
  5469.                                 return true
  5470.                             else
  5471.                                 console(players[hash].name .. " is dead.")
  5472.                             end
  5473.                         else
  5474.                             console(players[hash].name .. " is not currently in the server.")
  5475.                         end
  5476.                     else
  5477.                         console("Invalid Player.")
  5478.                     end
  5479.                 end
  5480.             else
  5481.                 console("Invalid Coordinates.")
  5482.             end
  5483.         else
  5484.             console("Invalid Respawn Time.")
  5485.         end
  5486.     else
  5487.         console("Invalid Object Search.")
  5488.     end
  5489.    
  5490.     return false
  5491. end
  5492.  
  5493. -- Message Functions --
  5494.  
  5495. -- Messages
  5496.  
  5497. function hprint(player, message, time)
  5498.  
  5499.     time = time or 5
  5500.     local hash = gethash(player)
  5501.     if hash then
  5502.         if string.len(message) > 79 then
  5503.             message = wordwrap(message, 79, true)
  5504.         end
  5505.         table.insert(messages[hash], {["message"] = message, ["time"] = time})
  5506.     end
  5507. end
  5508.  
  5509. function HprintTimer(id, count, delay)
  5510.  
  5511.     if messages ~= {} then
  5512.         for k,v in pairs(messages) do
  5513.             if messages[k] ~= {} then
  5514.                 for key,value in ipairs(messages[k]) do
  5515.                     messages[k][key].time = messages[k][key].time - (delay / 1000)
  5516.                     if messages[k][key].time < 0 then
  5517.                         table.remove(messages[k], key)
  5518.                     end
  5519.                 end
  5520.             end
  5521.         end
  5522.        
  5523.         for k,v in pairs(messages) do
  5524.             if #messages[k] > 0 then
  5525.                 local player = hashtoplayer(k)
  5526.                 local newline = ""
  5527.                 for i = 1, 30 do
  5528.                     newline = newline .. "\n "
  5529.                 end
  5530.                 hprintf(newline, player)
  5531.                 for key,value in ipairs(messages[k]) do
  5532.                     hprintf(messages[k][key].message, player)
  5533.                 end
  5534.             end
  5535.         end
  5536.     end
  5537.    
  5538.     return 1
  5539. end
  5540.  
  5541. function wordwrap(str, linelength, tabbed)
  5542.  
  5543.     local newstr = ""
  5544.     local count = 0
  5545.     local space_index = 0
  5546.     local begin = 1
  5547.    
  5548.     for i = 1, string.len(str) do
  5549.         local sub = string.sub(str, i, i)
  5550.         if sub == " " then
  5551.             space_index = i
  5552.         end
  5553.         count = count + 1
  5554.         if count == linelength then
  5555.             newstr = newstr .. string.sub(str, begin, space_index) .. "\n"
  5556.             begin = space_index + 1
  5557.             count = 0
  5558.             if tabbed then
  5559.                 repeat
  5560.                     newstr = newstr .. " "
  5561.                     count = count + 1
  5562.                 until count == math.floor(1 + linelength / 10)
  5563.             end
  5564.         end
  5565.        
  5566.         if i == string.len(str) then
  5567.             newstr = newstr .. string.sub(str, begin, string.len(str))
  5568.             break
  5569.         end
  5570.     end
  5571.    
  5572.     return newstr
  5573. end
  5574.  
  5575. function console(message)
  5576.  
  5577.     table.insert(cprint, message)
  5578. end
  5579.  
  5580. function private(player, message)
  5581.  
  5582.     table.insert(pprint[player], message)
  5583. end
  5584.  
  5585. function server(message)
  5586.  
  5587.     if not table.find(sprint, message) then
  5588.         table.insert(sprint, message)
  5589.     end
  5590. end
  5591.  
  5592. -- Update Functions
  5593.  
  5594. function updateBanlist()
  5595.  
  5596.     local dir = getprofilepath()
  5597.     local banlist = io.open(dir .. "\\banned.txt", "r")
  5598.     if banlist then
  5599.         local index = -1
  5600.         local hashes = {}
  5601.         for line in banlist:lines() do
  5602.             if not string.find(line, "# Name, CD key hash, ban count,") then
  5603.                 local info = string.split(line, ",")
  5604.                 local name = info[1]
  5605.                 local hash = info[2]
  5606.                 local numBans = info[3]
  5607.                 local banEnd = info[4]
  5608.                
  5609.                 validPlayer(hash, name)
  5610.                 table.insert(hashes, hash)
  5611.                
  5612.                 if not players[hash].banned then
  5613.                
  5614.                     players[hash].bancount = (players[hash].bancount or 0) + (tonumber(numBans) or 0)
  5615.                    
  5616.                     local seconds
  5617.                    
  5618.                     if not string.find(banEnd, "--") then
  5619.                    
  5620.                         local today = os.date()
  5621.                         local date_time = string.split(today, " ")
  5622.                         local date = string.split(date_time[1], "/")
  5623.                         local month = date[1]
  5624.                         local day = date[2]
  5625.                         local year = date[3]
  5626.                        
  5627.                         local formatted = "20" .. year .. "-" .. month .. "-" .. day .. " " .. date_time[2]        
  5628.                         seconds = dateDiff(banEnd, formatted)
  5629.                        
  5630.                         if seconds < 0 then
  5631.                             seconds = 1
  5632.                         end
  5633.                     else
  5634.                         seconds = -1
  5635.                     end
  5636.                    
  5637.                     table.insert(banned, hash)
  5638.                     players[hash].banned = true
  5639.                     players[hash].bantime = seconds
  5640.                     hprintf("Banning " .. players[hash].name .. "...")
  5641.                 end
  5642.             end
  5643.         end
  5644.        
  5645.         banlist:close()
  5646.        
  5647.         for k,h in ipairs(banned) do
  5648.             if not table.find(hashes, h) then
  5649.                 table.remove(banned, k)
  5650.                 players[h].banned = false
  5651.                 players[h].bantime = nil
  5652.                 hprintf("Unbanning " .. players[h].name .. "...")
  5653.             end
  5654.         end
  5655.     end
  5656. end
  5657.  
  5658. function updateAdmins()
  5659.  
  5660.     local dir = getprofilepath()
  5661.     local adminlist = io.open(dir .. "\\admin.txt", "r")
  5662.     if adminlist then
  5663.         for line in adminlist:lines() do
  5664.             local split = string.split(line, ",")
  5665.             local name = split[1]
  5666.             local hash = split[2]
  5667.             local level = tonumber(split[3])
  5668.             addAdmin(hash, name, level)
  5669.         end
  5670.         adminlist:close()
  5671.     end
  5672. end
  5673.  
  5674. -- Swear Functions --
  5675.  
  5676. --[[ Functions ]]--
  5677.  
  5678. function getSwears(message)
  5679.  
  5680.     local swears = {}  
  5681.     local words = string.split(message, " ")
  5682.    
  5683.     for k,_ in pairs(sweartable.exact) do
  5684.         for __,v in ipairs(words) do
  5685.             if k == string.lower(v) then
  5686.                 table.insert(swears, v)
  5687.             end
  5688.         end
  5689.     end
  5690.    
  5691.     for k,_ in pairs(sweartable.anywhere) do
  5692.         if string.find(string.lower(message), k) then
  5693.             local i1, i2 = string.find(string.lower(message), k)
  5694.             local swear = string.sub(message, i1, i2)
  5695.             table.insert(swears, swear)
  5696.         end
  5697.     end
  5698.    
  5699.     if #swears > 0 then
  5700.         return swears
  5701.     end
  5702. end
  5703.  
  5704. function swear(player, swears)
  5705.  
  5706.     local hash = gethash(player)
  5707.    
  5708.     for _,v in ipairs(swears) do
  5709.         table.insert(mute_table[hash].swears, v)
  5710.     end
  5711.    
  5712.     mute_table[hash].swears.count = mute_table[hash].swears.count + 1
  5713.     mute_table[hash].swears.game = mute_table[hash].swears.game + 1
  5714.    
  5715.     if automute then
  5716.         if mute_table[hash].swears.count == swears_to_mute then
  5717.             mute(player, swear_penalty, "You have been auto-muted.")
  5718.             privatesay(player, "You have been auto-muted " .. getDuration(hash, true) .. " due to excessive swearing.")
  5719.             say(getname(player) .. " has been auto-muted " .. getDuration(hash, true) .. ".")
  5720.             mutelog(hash, getname(player) .. " | " .. getDuration(hash) .. " | " .. mute_table[hash].message .. " | Auto-muted")
  5721.         elseif mute_table[hash].swears.count == swears_to_mute - 1 then
  5722.             if swear_message ~= "" then
  5723.                 privatesay(player, "Swearing again will get you auto-muted.")
  5724.             end
  5725.         else
  5726.             if swear_message ~= "" then
  5727.                 privatesay(player, swear_message)
  5728.             end
  5729.         end
  5730.     else
  5731.         if swear_message ~= "" then
  5732.             privatesay(player, swear_message)
  5733.         end
  5734.     end
  5735. end
  5736.  
  5737. function appendMessage(message, swears)
  5738.  
  5739.     for _,s in ipairs(swears) do
  5740.  
  5741.         if sweartable.anywhere[string.lower(s)] then
  5742.             message = string.gsub(message, s, sweartable.anywhere[string.lower(s)])
  5743.         else
  5744.             message = string.gsub(message, s, sweartable.exact[string.lower(s)])
  5745.         end
  5746.     end
  5747.    
  5748.     return message
  5749. end
  5750.  
  5751. function getSweartype(entry)
  5752.  
  5753.     if entry then
  5754.         if string.find(entry, "any") or tonumber(entry) == 1 then
  5755.             return "anywhere"
  5756.         elseif string.find(entry, "exa") or tonumber(entry) == 0 then
  5757.             return "exact"
  5758.         else
  5759.             if sweartable.anywhere[entry] then
  5760.                 return "anywhere"
  5761.             elseif sweartable.exact[entry] then
  5762.                 return "exact"
  5763.             end
  5764.         end
  5765.     end
  5766. end
  5767.  
  5768. function addSwear(word, append, sweartype)
  5769.  
  5770.     word = string.lower(word)
  5771.    
  5772.     -- Make sure values are assigned to the correct variable.
  5773.     if not sweartype then
  5774.         if getSweartype(append) then
  5775.             sweartype = getSweartype(append)
  5776.             append = nil
  5777.         else
  5778.             sweartype = "exact"
  5779.         end
  5780.     end
  5781.    
  5782.     if not sweartable[sweartype][word] then
  5783.         if sweartype == "exact" and string.find(word, " ") then
  5784.             return "Exact swears cannot contain spaces."
  5785.         end
  5786.        
  5787.         sweartable[sweartype][word] = append or swear_append
  5788.     else
  5789.         return "\"" .. word .. "\" is already in the " .. capitalize(sweartype) .. " Sweartable."
  5790.     end
  5791. end
  5792.  
  5793. function sv_swear_add(admin, word, append, sweartype)
  5794.  
  5795.     -- Call function; check for errors.
  5796.     local err = addSwear(word, append, sweartype)
  5797.     if not err then
  5798.         console("Word: \"" .. word .. "\" | Replaced by: \"" .. (append or swear_append) .. "\" | " .. capitalize(getSweartype(word)) .. " Sweartable")
  5799.         return true
  5800.     end
  5801.    
  5802.     console(err)
  5803.     return false
  5804. end
  5805.  
  5806. function removeSwear(word, sweartype)
  5807.  
  5808.     word = string.lower(word)
  5809.     local found
  5810.     if not sweartype then      
  5811.         for k,_ in pairs(sweartable.exact) do
  5812.             if word == k then
  5813.                 sweartable.exact[k] = nil
  5814.                 found = true
  5815.             end
  5816.         end
  5817.        
  5818.         for k,_ in pairs(sweartable.anywhere) do
  5819.             if word == k then
  5820.                 sweartable.anywhere[k] = nil
  5821.                 found = true
  5822.             end
  5823.         end
  5824.     else
  5825.         if getSweartype(sweartype) then
  5826.             local sweartype = getSweartype(sweartype)
  5827.             for k,v in pairs(sweartable[sweartype]) do
  5828.                 if word == k then
  5829.                     sweartable[sweartype][k] = nil
  5830.                     found = true
  5831.                 end
  5832.             end
  5833.         else
  5834.             return removeSwear(word, "exact")
  5835.         end
  5836.     end
  5837.    
  5838.     if not found then
  5839.         return "\"" .. word .. "\" is not in the sweartable."
  5840.     end                
  5841. end
  5842.  
  5843. function sv_swear_del(admin, word, sweartype)
  5844.  
  5845.     local old_sweartype = getSweartype(word)
  5846.     local err = removeSwear(word, sweartype)
  5847.     if not err then
  5848.         console("\"" .. word .. "\" has been removed from the " .. capitalize(old_sweartype or "") .. " Sweartable.")
  5849.         return true
  5850.     end
  5851.    
  5852.     console(err)
  5853.     return false
  5854. end
  5855.  
  5856. function sv_swear_type(admin, word)
  5857.  
  5858.     if getSweartype(word) then
  5859.         return getSweartype(word)
  5860.     end
  5861.    
  5862.     console("\"" .. word .. "\" is not in the sweartable.")
  5863.     return false
  5864. end
  5865.  
  5866. function sv_sweartable(admin, sweartype)
  5867.  
  5868.     if sweartype then
  5869.         sweartype = getSweartype(sweartype) or "exact"
  5870.         local swears = {}
  5871.         for k,_ in pairs(sweartable[sweartype]) do
  5872.             table.insert(swears, k)
  5873.         end
  5874.         if #swears > 0 then
  5875.             console(sweartype .. " sweartable:")
  5876.             local mprint = printlist(swears, 7, " | ")
  5877.             for _,v in ipairs(mprint) do
  5878.                 console(v)
  5879.             end
  5880.         else
  5881.             console("There are no swears in the " .. capitalize(sweartype) .. " Sweartable.")
  5882.         end
  5883.     else
  5884.         sv_sweartable(admin, "exact")
  5885.         sv_sweartable(admin, "anywhere")
  5886.     end
  5887.  
  5888.     return true
  5889. end
  5890.  
  5891. function sv_automute(admin, boolean)
  5892.  
  5893.     if boolean ~= nil then
  5894.         if boolean == "true" then
  5895.             boolean = true
  5896.         elseif boolean == "false" then
  5897.             boolean = false
  5898.         else
  5899.             console("Invalid Boolean.")
  5900.             return false
  5901.         end
  5902.  
  5903.         if boolean then
  5904.             if automute then
  5905.                 console("Automute is already enabled.")
  5906.                 return false
  5907.             else
  5908.                 console("Automute is now enabled.")
  5909.             end
  5910.         else
  5911.             if automute then
  5912.                 console("Automute is now disabled.")
  5913.             else
  5914.                 console("Automute is already disabled.")
  5915.                 return false
  5916.             end
  5917.         end
  5918.        
  5919.         automute = boolean
  5920.         return true
  5921.     else
  5922.         console(tostring(automute))
  5923.         return true
  5924.     end
  5925.    
  5926.     return false
  5927. end
  5928.  
  5929. function sv_swears_to_mute(admin, num)
  5930.  
  5931.     if num then
  5932.         if tonumber(num) then
  5933.             num = math.ceil(tonumber(num))
  5934.             swears_to_mute = num
  5935.             console("Swears to Mute changed to " .. num)
  5936.             return true
  5937.         else
  5938.             console("Invalid Swears to Mute.")
  5939.         end
  5940.     else
  5941.         console("Swears to Mute: " .. swears_to_mute)
  5942.         return true
  5943.     end
  5944.    
  5945.     return false
  5946. end
  5947.  
  5948. local function getSwearAction(entry)
  5949.    
  5950.     if entry == "none" or tonumber(entry) == 0 then
  5951.         return "None", 0
  5952.     elseif entry == "block" or tonumber(entry) == 1 then
  5953.         return "Block", 1
  5954.     elseif entry == "append" or tonumber(entry) == 2 then
  5955.         return "Append", 2
  5956.     end
  5957. end
  5958.  
  5959. function sv_swear_action(admin, action)
  5960.  
  5961.     if action then
  5962.         local action, id = getSwearAction(action)
  5963.         if id then
  5964.             swear_action = id
  5965.             console("Swear Action changed to \"" .. action .. "\"")
  5966.             return true
  5967.         else
  5968.             console("Invalid Swear Action.")
  5969.         end
  5970.     else       
  5971.         console("Swear Action: " .. getSwearAction(swear_action))
  5972.         return true
  5973.     end
  5974.    
  5975.     return false
  5976. end
  5977.  
  5978. function sv_swear_append(admin, append)
  5979.  
  5980.     if append then
  5981.         swear_append = append
  5982.         console("Default Swear Append changed to \"" .. append .. "\"")
  5983.     else
  5984.         console("Default Swear Append: \"" .. swear_append .. "\"")
  5985.     end
  5986.    
  5987.     return true
  5988. end
  5989.  
  5990. function sv_swear_message(admin, message)
  5991.  
  5992.     if message then
  5993.         swear_message = message
  5994.         console("Swear Message changed to \"" .. message .. "\"")
  5995.     else
  5996.         console("Swear Message: \"" .. swear_message .. "\"")
  5997.     end
  5998.    
  5999.     return true
  6000. end
  6001.  
  6002. function sv_swear_penalty(admin, penalty)
  6003.  
  6004.     if penalty then
  6005.         if toDuration(penalty) then
  6006.             swear_penalty = toDuration(penalty)
  6007.             console("Automute Swear Penalty changed to " .. getDuration(swear_penalty))
  6008.             return true
  6009.         else
  6010.             console("Invalid Automute Swear Penalty.")
  6011.         end
  6012.     else
  6013.         console("Automute Swear Penalty: " .. getDuration(swear_penalty))
  6014.         return true
  6015.     end
  6016.    
  6017.     return false
  6018. end
  6019.  
  6020. function sv_mute_notify(admin, mutes)
  6021.  
  6022.     if mutes then
  6023.         if tonumber(mutes) then
  6024.             mutes = math.ceil(tonumber(mutes))
  6025.             console("Mutes Until Notified changed to " .. mutes)
  6026.             return true
  6027.         else
  6028.             console("Invalid Mutes Until Notified.")
  6029.         end
  6030.     else
  6031.         console("Mutes Until Notified: " .. notify_of_mutes)
  6032.         return true
  6033.     end
  6034.    
  6035.     return false
  6036. end
  6037.  
  6038. --[[ Validity Checks ]]--
  6039.    
  6040.     if not type(automute) == "boolean" then
  6041.         automute = true
  6042.     end
  6043.  
  6044.     if not tonumber(swear_action) then
  6045.         swear_action = getSwearAction(swear_action) or 0
  6046.     end
  6047.    
  6048.     if not tonumber(swear_penalty) then
  6049.         swear_penalty = -1
  6050.     end
  6051.  
  6052. --[[ Miscellaneous Updating ]]--
  6053.  
  6054.     -- Update tables with values from the swear table, making sure sweartable.exact and sweartable.anywhere have been initialized as arrays and making sure no repeats are inserted.
  6055.     for _,v in ipairs(swear_default.exact) do
  6056.         addSwear(v, "exact")
  6057.     end
  6058.    
  6059.     for _,v in ipairs(swear_default.anywhere) do
  6060.         addSwear(v, "anywhere")
  6061.     end
  6062.    
  6063. -- Mute Functions
  6064.  
  6065. --[[ Functions ]]--
  6066.  
  6067. -- Logs the specified player's mute information with the given message.
  6068. function mutelog(hash, message)
  6069.  
  6070.     -- Nil check
  6071.     mute_table[hash] = mute_table[hash] or {}
  6072.     mute_table[hash].mutelog = mute_table[hash].mutelog or {}
  6073.     table.insert(mute_table[hash].mutelog, "[" .. os.date() .. "]: " .. message)
  6074. end
  6075.  
  6076. -- Update player's mute information (meant to be called OnPlayerJoin).
  6077. function updateMute(player)
  6078.  
  6079.     local hash = gethash(player)
  6080.  
  6081.     -- Make sure all mute values exist
  6082.     mute_table[hash] = mute_table[hash] or {}
  6083.     mute_table[hash].muted = mute_table[hash].muted or false
  6084.     mute_table[hash].duration = mute_table[hash].duration or 0
  6085.     mute_table[hash].message = mute_table[hash].message or ""
  6086.     mute_table[hash].swears = mute_table[hash].swears or {}
  6087.     mute_table[hash].swears.count = mute_table[hash].swears.count or 0
  6088.     mute_table[hash].swears.game = mute_table[hash].swears.game or 0
  6089.     mute_table[hash].mutes = mute_table[hash].mutes or 0
  6090.     mute_table[hash].mutelog = mute_table[hash].mutelog or {}
  6091. end
  6092.  
  6093. -- Returns the actual duration as an int value.
  6094. function toDuration(input)
  6095.  
  6096.     if string.find(input, "perm") then
  6097.         return -2
  6098.     elseif string.find(input, "temp") or string.find(input, "game") then
  6099.         return -1
  6100.     end
  6101.    
  6102.     return tonumber(input)
  6103. end
  6104.  
  6105. -- Returns a string formatted for a sentence or a list based on mute duration.
  6106. function getDuration(input, sentence)
  6107.  
  6108.     if tonumber(input, 16) and string.len(input) == 32 then
  6109.         return getDuration(mute_table[input].duration, sentence)
  6110.     else
  6111.         local duration = toDuration(input)
  6112.         if sentence then
  6113.             if duration == -2 then
  6114.                 return "permanently"
  6115.             elseif duration == -1 then
  6116.                 return "for the rest of the game"
  6117.             else
  6118.                 return "for " .. duration .. " seconds"
  6119.             end
  6120.         else
  6121.             if duration == -2 then
  6122.                 return "Permanent"
  6123.             elseif duration == -1 then
  6124.                 return "Rest of Game"
  6125.             else
  6126.                 return duration .. " seconds"
  6127.             end
  6128.         end
  6129.     end
  6130. end
  6131.  
  6132. function MuteTimer(id, count, hash)
  6133.  
  6134.     if mute_table[hash].duration > 0 then
  6135.         mute_table[hash].duration = mute_table[hash].duration - 1
  6136.         return 1
  6137.     end
  6138.     -- Unmute player and log the unmute.
  6139.     local err = unmute(hash)
  6140.     if not err then
  6141.         mutelog(hash, "Mute Expired. Unmuted by SERVER.")
  6142.     end
  6143.     local player = hashtoplayer(hash)
  6144.     if player then
  6145.         privatesay(player, "Your mute has expired.")
  6146.         say(getname(player) .. " has been unmuted.")
  6147.     end
  6148.    
  6149.     return 0
  6150. end
  6151.  
  6152. -- Mute by Player ID, hash, or Server Index with a specified Duration (-1: rest of game) (-2: permanent) (all other values in seconds) with a specified Mute Message.
  6153. function mute(id, duration, message)
  6154.  
  6155.     -- Find hash based on input
  6156.     local hash = tohash(id)
  6157.     if hash then
  6158.         -- Make sure "duration" and "message" are assigned the correct values
  6159.         duration = duration or -1
  6160.         if not toDuration(duration) then
  6161.             message = duration
  6162.             duration = -1
  6163.         end
  6164.            
  6165.         if not mute_table[hash].muted then         
  6166.             -- Set all mute values accordingly.
  6167.             mute_table[hash].muted = true
  6168.             mute_table[hash].duration = toDuration(duration)
  6169.             mute_table[hash].message = message or "You have been muted."
  6170.             mute_table[hash].mutes = (mute_table[hash].mutes or 0) + 1
  6171.            
  6172.             if mute_table[hash].duration >= 0 then
  6173.                 registertimer(1000, "MuteTimer", hash)
  6174.             end
  6175.         else
  6176.             return (players[hash].name or "This player") .. " is already muted."
  6177.         end
  6178.     else
  6179.         return "Invalid Player."
  6180.     end
  6181. end
  6182.  
  6183. -- sv_mute <Player ID or Server Index> <opt: Duration> <opt: Message>
  6184. function sv_mute(admin, id, duration, message)
  6185.  
  6186.     -- Make sure if a Player ID is entered, it is the player's memory ID.
  6187.     local hash = tohash(id, true, admin)
  6188.     -- Call mute function; make sure there are no errors.
  6189.     local err = mute(hash, duration, message)
  6190.     if not err then
  6191.         -- Server messages
  6192.         local player = hashtoplayer(hash)
  6193.         local name
  6194.         if player then
  6195.             name = getname(player)
  6196.             privatesay(player, "You have been muted " .. getDuration(hash, true) .. ".")
  6197.             say(name .. " has been muted " .. getDuration(hash, true) .. ".")
  6198.         else
  6199.             name = players[hash].name or "Anonymous"
  6200.         end    
  6201.         -- Log this mute.
  6202.         local admin_hash = gethash(admin)
  6203.         mutelog(hash, name .. " | " .. getDuration(mute_table[hash].duration) .. " | \"" .. mute_table[hash].message .. "\" | Muted by: " .. (players[(admin_hash or 0)].name or "SERVER"))
  6204.         -- Console print.
  6205.         console(name .. " | " .. getDuration(hash) .. " | \"" .. mute_table[hash].message .. "\"")
  6206.         -- If this player has been muted many times, let the admin know.
  6207.         duration = duration or -1
  6208.         if toDuration(duration) > -2 then
  6209.             if notify_of_mutes > 0 then
  6210.                 if mute_table[hash].mutes >= notify_of_mutes then
  6211.                     console(name .. " has been muted " .. mute_table[hash].mutes .. " times.")
  6212.                     console("Consider a permamute if their behavior continues.")
  6213.                 end
  6214.             end
  6215.         end
  6216.        
  6217.         return true
  6218.     end
  6219.     -- Print the error.
  6220.     console(err)
  6221.     return false
  6222. end
  6223.  
  6224. -- sv_permamute <Player ID or Server Index> <opt: Message>
  6225. function sv_permamute(admin, id, message)
  6226.  
  6227.     return sv_mute(admin, id, -2, message or "You have been permanently muted.")
  6228. end
  6229.  
  6230. -- Unmutes by Player ID, hash, or Server Index.
  6231. function unmute(id)
  6232.  
  6233.     local hash = tohash(id)
  6234.     if hash then
  6235.         mute_table[hash] = mute_table[hash] or {}
  6236.         if mute_table[hash].muted then
  6237.             mute_table[hash].muted = false
  6238.             mute_table[hash].duration = 0
  6239.             mute_table[hash].message = ""
  6240.             mute_table[hash].swears.count = 0
  6241.         else
  6242.             return (players[hash].name or "This player") .. " is not muted."
  6243.         end
  6244.     else
  6245.         return "Invalid Player."
  6246.     end
  6247. end
  6248.  
  6249. -- sv_unmute <Player ID or Server Index>
  6250. function sv_unmute(admin, id)
  6251.  
  6252.     -- Make sure if a Player ID is entered, it is the player's memory ID.
  6253.     local hash = tohash(id, true, admin)
  6254.     -- Call unmute function; make sure there are no errors.
  6255.     local err = unmute(hash)
  6256.     if not err then
  6257.         -- Server messages
  6258.         local player = hashtoplayer(hash)
  6259.         local name
  6260.         if player then
  6261.             name = getname(player)
  6262.             privatesay(player, "You have been unmuted.")
  6263.             say(name .. " has been unmuted.")
  6264.         else
  6265.             name = players[hash].name or "Anonymous"
  6266.         end
  6267.         -- Log this unmute.
  6268.         mutelog(hash, "Unmuted by " .. (players[(admin_hash or 0)].name or "SERVER"))
  6269.         -- Console print.
  6270.         console(name .. " has been unmuted.")
  6271.         return true
  6272.     end
  6273.     -- Print the error.
  6274.     console(err)
  6275.     return false
  6276. end
  6277.  
  6278. function sv_mute_duration(admin, id, newDuration)
  6279.  
  6280.     local hash = tohash(id, true, admin)
  6281.    
  6282.     if hash then
  6283.         if newDuration then
  6284.             local duration = toDuration(newDuration)
  6285.             if duration then
  6286.                 local old_duration = mute_table[hash].duration
  6287.                 mute_table[hash].duration = duration
  6288.                 if old_duration < 0 and duration >= 0 then
  6289.                     registertimer(1000, "MuteTimer", hash)
  6290.                 end
  6291.                 console(players[hash].name .. "'s Mute Duration has been changed to " .. getDuration(hash) .. ".")
  6292.                 return true
  6293.             else
  6294.                 console("Invalid Duration Entry.")
  6295.             end
  6296.         else
  6297.             if mute_table[hash].muted then
  6298.                 console("[" .. players[hash].index .. "] " .. players[hash].name .. " | " .. getDuration(hash))
  6299.             else
  6300.                 console(players[hash].name .. " is not muted.")
  6301.             end
  6302.            
  6303.             return true
  6304.         end
  6305.     end
  6306.    
  6307.     console("Invalid Player.")
  6308.     return false               
  6309. end
  6310.  
  6311. function sv_mute_message(admin, id, message)
  6312.  
  6313.     local hash = tohash(id, true, admin)
  6314.    
  6315.     if hash then
  6316.         if message then
  6317.             mute_table[hash].message = message
  6318.             console(players[hash].name .. "'s Mute Message has been changed to \"" .. message .. "\".")
  6319.         else
  6320.             if mute_table[hash].muted then
  6321.                 console("[" .. players[hash].index .. "] " .. players[hash].name .. " | \"" .. mute_table[hash].message .. "\"")
  6322.             else
  6323.                 console(players[hash].name .. " is not muted.")
  6324.             end
  6325.         end
  6326.        
  6327.         return true
  6328.     end
  6329.    
  6330.     console("Invalid Player.")
  6331.     return false
  6332. end
  6333.  
  6334. function sv_mute_info(admin, id)
  6335.  
  6336.     local hash = tohash(id, true, admin)
  6337.    
  6338.     if hash then
  6339.         console("[" .. players[hash].index .. "] " .. players[hash].name .. " | Muted: " .. tostring(mute_table[hash].muted))
  6340.         if mute_table[hash].muted then
  6341.             console("Duration: " .. getDuration(hash) .. " | Message: \"" .. mute_table[hash].message .. "\"")
  6342.         end
  6343.         local counts = "# of Mutes: " .. mute_table[hash].mutes .. " | # of Swears | This Game: " .. mute_table[hash].swears.game .. " | Overall: " .. #mute_table[hash].swears
  6344.         if automute then
  6345.             counts = counts .. " | Until Auto-mute: " .. swears_to_mute - mute_table[hash].swears.count
  6346.         end
  6347.         console(counts)
  6348.         return true
  6349.     end
  6350.    
  6351.     console("Invalid Player.")
  6352.     return false
  6353. end
  6354.  
  6355. function sv_swears(admin, id)
  6356.  
  6357.     local hash = tohash(id, true, admin)
  6358.    
  6359.     if hash then
  6360.         mute_table[hash].swears = mute_table[hash].swears or {}
  6361.         if #mute_table[hash].swears > 0 then
  6362.             local mprint = printlist(mute_table[hash].swears, 8, "   ")
  6363.             console(#mute_table[hash].swears .. " total logged swears:")
  6364.             for _,v in ipairs(mprint) do
  6365.                 console(v)
  6366.             end
  6367.         else
  6368.             console("This player has no logged swears.")
  6369.         end
  6370.        
  6371.         return true
  6372.     end
  6373.    
  6374.     console("Invalid Player.")
  6375.     return false
  6376. end
  6377.  
  6378. function sv_mute_players(admin)
  6379.  
  6380.     console("Players and their corresponding Mute Information:")
  6381.     for i = 0, 15 do
  6382.         local hash = gethash(i)
  6383.         if hash then
  6384.             console("[" .. players[hash].index .. "] " .. getname(i) .. " | Muted: " .. tostring(mute_table[hash].muted))
  6385.         end
  6386.     end
  6387.    
  6388.     return true
  6389. end
  6390.  
  6391. function sv_mutelog(admin, id)
  6392.  
  6393.     local hash = tohash(id, true, admin)
  6394.    
  6395.     if hash then
  6396.         mute_table[hash].mutelog = mute_table[hash].mutelog or {}
  6397.         if #mute_table[hash].mutelog > 0 then
  6398.             for _,v in ipairs(mute_table[hash].mutelog) do
  6399.                 console(v)
  6400.             end
  6401.         else
  6402.             console("This player has never been muted.")
  6403.         end
  6404.        
  6405.         return true
  6406.     end
  6407.    
  6408.     console("Invalid Player.")
  6409.     return false
  6410. end
  6411.  
  6412. function sv_reset_mute_info(admin, id)
  6413.  
  6414.     local hash = tohash(id, true, admin)
  6415.    
  6416.     if hash then
  6417.         if mute_table[hash] then
  6418.             local player = hashtoplayer(hash)
  6419.             local name
  6420.             if player then
  6421.                 name = getname(player)
  6422.                 privatesay(player, "Your mute information has been reset.")
  6423.             else
  6424.                 name = ""
  6425.             end
  6426.            
  6427.             players[hash].name = name
  6428.             mute_table[hash].muted = false
  6429.             mute_table[hash].duration = 0
  6430.             mute_table[hash].message = ""
  6431.             mute_table[hash].swears = {}
  6432.             mute_table[hash].swears.count = 0
  6433.             mute_table[hash].swears.game = 0
  6434.             mute_table[hash].mutes = 0
  6435.             mute_table[hash].mutelog = {}
  6436.            
  6437.             console("Player's mute information reset.")
  6438.             return true
  6439.         end
  6440.     end
  6441.    
  6442.     console("Invalid Player.")
  6443.     return false
  6444. end
  6445.  
  6446. local function toCategory(entry)
  6447.  
  6448.     if string.find(entry, "ind") or entry == "id" then
  6449.         return "index"
  6450.     elseif string.find(entry, "name") then
  6451.         return "name"
  6452.     elseif string.find(entry, "duration") then
  6453.         return "duration"
  6454.     elseif string.find(entry, "swears") then
  6455.         return "swears"
  6456.     elseif string.find(entry, "mutes") then
  6457.         return "mutes"
  6458.     end
  6459. end
  6460.  
  6461. local function toDirection(entry)
  6462.  
  6463.     if string.find(entry, "ascend") or string.find(entry, "incre") or entry == "up" or entry == "+" or entry == 1 then
  6464.         return 1
  6465.     elseif string.find(entry, "descend") or string.find(entry, "decre") or entry == "down" or entry == "-" or entry == -1 then
  6466.         return -1
  6467.     end
  6468.    
  6469.     return 0
  6470. end
  6471.  
  6472. function sv_mutelist(admin, search, direction, length)
  6473.  
  6474.     if not search and not direction and not length then
  6475.         local muted = {}
  6476.         for k,_ in ipairs(muted) do
  6477.             if tonumber(k, 16) and string.len(k) == 32 then
  6478.                 if mute_table[k].muted then
  6479.                     local player = hashtoplayer(k)
  6480.                     local name
  6481.                     if player then
  6482.                         name = getname(player)
  6483.                     else
  6484.                         name = players[k].name
  6485.                     end
  6486.                
  6487.                     table.insert(muted, "[" .. players[k].index .. "] " .. name .. " | Duration: " .. getDuration(k))
  6488.                 end
  6489.             end
  6490.         end
  6491.        
  6492.         if #muted > 0 then
  6493.             console("Players in the server who are muted:")
  6494.             for _,v in ipairs(muted) do
  6495.                 console(v)
  6496.             end
  6497.         else
  6498.             console("No players are currently muted.")
  6499.         end    
  6500.     else
  6501.         search = search or ""
  6502.         sortby = toCategory(search)
  6503.         direction = toDirection(direction or 0)
  6504.         length = tonumber(length or 15) or 15
  6505.        
  6506.         if sortby then
  6507.            
  6508.             local hashes = {}
  6509.            
  6510.             for k,v in pairs(mute_table) do
  6511.                 if tonumber(k, 16) and string.len(k) == 32 then
  6512.                     table.insert(hashes, k)
  6513.                 end
  6514.             end
  6515.            
  6516.             if length > #hashes then
  6517.                 length = #hashes
  6518.             end
  6519.            
  6520.             if direction == 0 then
  6521.                 if sortby == "duration" then
  6522.                     table.sort(hashes, function(a, b) return mute_table[a][sortby] < mute_table[b][sortby] end)
  6523.                 elseif sortby == "name" or sortby == "index" then
  6524.                     table.sort(hashes, function(a, b) return string.lower(players[a][sortby]) < string.lower(players[b][sortby]) end)
  6525.                 elseif sortby == "swears" then
  6526.                     table.sort(hashes, function(a, b) return #mute_table[a].swears > #mute_table[b].swears end)
  6527.                 else
  6528.                     table.sort(hashes, function(a, b) return mute_table[a][sortby] > mute_table[b][sortby] end)
  6529.                 end
  6530.             elseif direction == 1 then
  6531.                 if sortby == "swears" then
  6532.                     table.sort(hashes, function(a, b) return #mute_table[a].swears < #mute_table[b].swears end)
  6533.                 else
  6534.                     table.sort(hashes, function(a, b) return mute_table[a][sortby] < mute_table[b][sortby] end)
  6535.                 end
  6536.             else
  6537.                 if sortby == "swears" then
  6538.                     table.sort(hashes, function(a, b) return #mute_table[a].swears > #mute_table[b].swears end)
  6539.                 else
  6540.                     table.sort(hashes, function(a, b) return mute_table[a][sortby] > mute_table[b][sortby] end)
  6541.                 end
  6542.             end
  6543.            
  6544.             local dirprint = ""
  6545.             if direction == 1 then
  6546.                 dirprint = " in ascending order"
  6547.             elseif direction == -1 then
  6548.                 dirprint = " in descending order"
  6549.             end
  6550.            
  6551.             console("Mutelist sorted by \"" .. sortby .. "\"" .. dirprint .. ":")
  6552.            
  6553.             for i = 1, length do
  6554.                 if sortby == "swears" then
  6555.                     console("[" .. players[hashes[i]].index .. "] " .. players[hashes[i]].name .. " | Total Swears: " .. #mute_table[hashes[i]].swears)
  6556.                 elseif sortby == "name" or sortby == "index" then
  6557.                     console("[" .. players[hashes[i]].index .. "] " .. players[hashes[i]].name .. " | " .. capitalize(sortby) .. ": " .. players[hashes[i]][sortby])
  6558.                 else
  6559.                     console("[" .. players[hashes[i]].index .. "] " .. players[hashes[i]].name .. " | " .. capitalize(sortby) .. ": " .. mute_table[hashes[i]][sortby])
  6560.                 end
  6561.             end
  6562.         else
  6563.             local matches = {}
  6564.             for k,_ in pairs(mute_table) do
  6565.                 if tonumber(k, 16) and string.len(k) == 32 then
  6566.                     for key,v in pairs(mute_table[k]) do
  6567.                         if type(v) ~= "table" then
  6568.                             if string.find(tostring(v), search) then                           
  6569.                                 table.insert(matches, "[" .. players[k].index .. "] " .. players[k].name .. " | " .. capitalize(k) .. ": " .. tostring(v))
  6570.                             end
  6571.                         end
  6572.                     end
  6573.                 end
  6574.             end
  6575.            
  6576.             if #matches > 0 then
  6577.                 for i = 1, length do
  6578.                     console(matches[i])
  6579.                 end
  6580.             else
  6581.                 console("Invalid Search")
  6582.             end
  6583.         end
  6584.     end
  6585.  
  6586.     return true
  6587. end
  6588.  
  6589. --[[ Miscellaneous Updating ]]--
  6590.  
  6591.     -- Update mute table with default mutes
  6592.     for k,v in ipairs(mute_default) do
  6593.         mute(v, -2)
  6594.         table.remove(k)
  6595.     end
  6596.  
  6597. -- Gametype Functions
  6598.    
  6599.  
  6600.  
  6601. function sv_gametypes(admin, search)
  6602.  
  6603.     local matches = {}
  6604.    
  6605.     for k,v in pairs(gametypes) do
  6606.         if not search then
  6607.             table.insert(matches, k)
  6608.         else
  6609.             if string.find(string.lower(k), string.lower(search)) then
  6610.                 table.insert(matches, k)
  6611.             end
  6612.         end
  6613.     end
  6614.    
  6615.     table.sort(matches)
  6616.     console("Gametypes matching search \"" .. (search or "") .. "\":")
  6617.     for k,v in ipairs(matches) do
  6618.         console(v)
  6619.     end
  6620.    
  6621.     return true
  6622. end
  6623.  
  6624. function sv_scripts(admin)
  6625.  
  6626.     local mprint = printlist(scripts, 3, "   ")
  6627.     for k,v in ipairs(mprint) do
  6628.         console(v)
  6629.     end
  6630.    
  6631.     return true
  6632. end
  6633.  
  6634. -- Other Command Functions --
  6635.  
  6636. -- Add feature allowing all weapons' ammo to be edited in one command
  6637. function sv_ammo(admin, id, weapon, ammo, clip)
  6638.  
  6639.     if tonumber(ammo) and tonumber(clip) then
  6640.         if toTag(weapon) or (tonumber(weapon) and tonumber(weapon) > 0 and tonumber(weapon) < 5) then
  6641.             local hashes = pack(tohash(id, true, admin))
  6642.             if #hashes > 1 then
  6643.                 for k,v in ipairs(hashes) do
  6644.                     sv_ammo(admin, v, weapon, ammo, clip)
  6645.                 end
  6646.                 if toTag(weapon) then
  6647.                     local tagtype, tagname = unpack(toTag(weapon))
  6648.                     server(toTeam(id) .. " players' " .. tags[tagtype][tagname] .. "s' ammo counts have been edited.")
  6649.                 else
  6650.                     server(toTeam(id) .. " players' weapons' ammo counts in slot " .. weapon .. " have been edited.")
  6651.                 end
  6652.                
  6653.                 return true
  6654.             else
  6655.                 local hash = unpack(hashes)
  6656.                 if hash then
  6657.                     local player = hashtoplayer(hash)
  6658.                     if player then
  6659.                         local m_player = getplayer(player)
  6660.                         local m_objId = readdword(m_player, 0x34)
  6661.                         local m_object = getobject(m_objId)
  6662.                         if m_object then
  6663.                             local slot, m_weapId, m_weapon
  6664.                             if tonumber(weapon) then
  6665.                                 slot = weapon
  6666.                                 m_weapId = readdword(m_object, 0x2F8 + (slot - 1) * 4)
  6667.                                 m_weapon = getobject(m_weapId)
  6668.                                 if not m_weapon then
  6669.                                     console("Invalid Weapon Slot")
  6670.                                 end
  6671.                             else
  6672.                                 local tagtype, tagname = unpack(toTag(weapon))
  6673.                                 for i = 0,3 do
  6674.                                     m_weapId = readdword(m_object, 0x2F8 + (i * 4))
  6675.                                     m_weapon = getweapon(m_weapId)
  6676.                                     if m_weapon then
  6677.                                         if tagname == objects[m_weapId].tagname then break  end
  6678.                                     end
  6679.                                 end
  6680.                             end
  6681.                            
  6682.                             if m_weapId then
  6683.                                 if not string.find(objects[m_weapId].tagname, "plasma") then
  6684.                                     writeword(m_weapon, 0x2B6, ammo)
  6685.                                     writeword(m_weapon, 0x2B8, clip)
  6686.                                     updateammo(m_weapId)
  6687.                                     console(players[hash].name .. "'s ammo has been edited.")
  6688.                                     console("Weapon: " .. tags[objects[m_weapId].tagtype][objects[m_weapId].tagname])
  6689.                                     console("Ammo: " .. ammo .. " | Clip: " .. clip)
  6690.                                 else
  6691.                                     console("Use sv_battery for plasma weapons.")
  6692.                                 end
  6693.                                
  6694.                                 return true
  6695.                             else
  6696.                                 console(players[hash].name .. " does not have a \"" .. weapon .. "\".")
  6697.                             end
  6698.                         else
  6699.                             console(players[hash].name .. " is dead.")
  6700.                         end
  6701.                     else
  6702.                         console(players[hash].name .. " is not currently in the server.")              
  6703.                     end
  6704.                 else
  6705.                     console("Invalid Player.")
  6706.                 end
  6707.             end
  6708.         else
  6709.             console("Invalid Weapon.")
  6710.         end
  6711.     else
  6712.         console("Invalid Ammo or Clip.")
  6713.     end
  6714.    
  6715.     return false
  6716. end
  6717.  
  6718. -- General Functions --
  6719.  
  6720. -- Math Globals
  6721.  
  6722. math.inf = 1 / 0
  6723.  
  6724. -- General Functions
  6725.  
  6726. function hashtoplayer(hash)
  6727.  
  6728.     for i = 0, 15 do
  6729.         if gethash(i) == hash then return i end
  6730.     end
  6731.    
  6732.     return nil
  6733. end
  6734.  
  6735. -- Oxide helped make this better
  6736. function execute(func, ...)
  6737.  
  6738.     if _G[func] and type(_G[func]) == "function" then
  6739.         return true, _G[func](...)
  6740.     end
  6741. end
  6742.  
  6743. function locals()
  6744.  
  6745.     local variables = {}
  6746.     local idx = 1
  6747.     while true do
  6748.         local name, value = debug.getlocal(2, idx)
  6749.         if name then
  6750.             variables[name] = value
  6751.         else break end
  6752.         idx = 1 + idx
  6753.     end
  6754.    
  6755.     return variables
  6756. end
  6757.  
  6758. function pack(...)
  6759.    
  6760.     return arg
  6761. end
  6762.  
  6763. -- String functions
  6764.  
  6765. function string.wild(match, wild, case_sensative)
  6766.  
  6767.     if not case_sensative then
  6768.         match, wild = string.lower(match), string.lower(wild)
  6769.     end
  6770.  
  6771.     -- Initial Checks
  6772.     if string.sub(wild, 1, 1) == "?" then wild = string.gsub(wild, "?", string.sub(match, 1, 1), 1) end
  6773.     if string.sub(wild, string.len(wild), string.len(wild)) == "?" then wild = string.gsub(wild, "?", string.sub(match, string.len(match), string.len(match)), 1) end
  6774.     if not string.find(wild, "*") and not string.find(wild, "?") and wild ~= match then return false end
  6775.     if string.sub(wild, 1, 1) ~= string.sub(match, 1, 1) and string.sub(wild, 1, 1) ~= "*" then return false end
  6776.     if string.sub(wild, string.len(wild), string.len(wild)) ~= string.sub(match, string.len(match), string.len(match)) and string.sub(wild, string.len(wild), string.len(wild)) ~= "*" then return false end
  6777.    
  6778.     local substrings = string.split(wild, "*")
  6779.     local begin = 1
  6780.  
  6781.     for k,v in ipairs(substrings) do
  6782.  
  6783.         local sublength = string.len(v)
  6784.         local temp_begin = begin
  6785.         local temp_end = begin + sublength - 1
  6786.         local matchsub = string.sub(match, begin, temp_end)
  6787.         local bool
  6788.        
  6789.         repeat
  6790.             local wild = v
  6791.             local indexes = pack(string.findchar(wild, "?"))
  6792.             if #indexes > 0 then
  6793.                 for _,i in ipairs(indexes) do
  6794.                     wild = string.gsub(wild, "?", string.sub(matchsub, i, i), 1)
  6795.                 end
  6796.             end
  6797.             if matchsub == wild then
  6798.                 bool = true
  6799.                 break
  6800.             end
  6801.             matchsub = string.sub(match, temp_begin, temp_end)
  6802.             temp_begin = temp_begin + 1
  6803.             temp_end = temp_end + 1
  6804.            
  6805.         until temp_end >= string.len(match)
  6806.  
  6807.         if not bool then
  6808.             return false
  6809.         end
  6810.  
  6811.         begin = sublength + 1
  6812.     end
  6813.  
  6814.     return true
  6815. end
  6816.  
  6817. function string.findchar(str, char)
  6818.  
  6819.     local chars = string.split(str, "")
  6820.     local indexes = {}
  6821.     for k,v in ipairs(chars) do
  6822.         if v == char then
  6823.             table.insert(indexes, k)
  6824.         end
  6825.     end
  6826.  
  6827.     return unpack(indexes)
  6828. end
  6829.  
  6830. -- Written by Chalonic --
  6831. function ParseCommand(command)
  6832.  
  6833.     local cmd = nil
  6834.     local args = {}
  6835.    
  6836.     local arg = ""
  6837.     local in_quote = false
  6838.    
  6839.     for i = 1, #command do
  6840.         local c = command:sub(i, i)
  6841.        
  6842.         if c == "\"" then
  6843.             if in_quote then
  6844.                 in_quote = false
  6845.                
  6846.                 table.insert(args, arg)
  6847.                 arg = ""
  6848.             else
  6849.                 in_quote = true
  6850.             end
  6851.         elseif c == " " then
  6852.             if in_quote then
  6853.                 arg = arg .. c
  6854.             else
  6855.                 if #arg > 0 then
  6856.                     table.insert(args, arg)
  6857.                     arg = ""
  6858.                 end
  6859.             end
  6860.         else
  6861.             arg = arg .. c
  6862.         end
  6863.     end
  6864.    
  6865.     if #arg > 0 then
  6866.         table.insert(args, arg)
  6867.         arg = ""
  6868.     end
  6869.    
  6870.     if #args > 0 then
  6871.         cmd = table.remove(args, 1)
  6872.     end
  6873.    
  6874.     return cmd, args
  6875. end
  6876.  
  6877. function printlist(list, linelength, delimiter)
  6878.  
  6879.     local mprint = {}
  6880.     local x = 1
  6881.     local count = 0
  6882.     mprint[1] = ""
  6883.     while x <= #list do
  6884.         if (x - 1) % linelength == 0 then
  6885.             count = count + 1
  6886.             mprint[count] = ""
  6887.         end
  6888.         if x < #list then
  6889.             mprint[count] = mprint[count] .. list[x] .. delimiter
  6890.         else
  6891.             mprint[count] = mprint[count] .. list[x]
  6892.         end
  6893.         x = x + 1
  6894.     end
  6895.    
  6896.     return mprint
  6897. end
  6898.  
  6899. function capitalize(str, limit)
  6900.  
  6901.     local words = string.split(str, " ")
  6902.     limit = limit or #words
  6903.    
  6904.     if #words > 0 then
  6905.         for k,v in ipairs(words) do
  6906.             if k <= limit then
  6907.                 local first = string.sub(v, 1, 1)
  6908.                 words[k] = string.gsub(words[k], first, string.upper(first))
  6909.             else break end
  6910.         end
  6911.        
  6912.         return table.concat(words, " ")
  6913.     end
  6914.    
  6915.     return str
  6916. end
  6917.  
  6918. function getTuple(num)
  6919.  
  6920.     num = tonumber(num)
  6921.     if num == 1 then
  6922.         return "Single"
  6923.     elseif num == 2 then
  6924.         return "Double"
  6925.     elseif num == 3 then
  6926.         return "Triple"
  6927.     elseif num == 4 then
  6928.         return "Quadruple"
  6929.     elseif num == 5 then
  6930.         return "Quintuple"
  6931.     elseif num == 6 then
  6932.         return "Sextuple"
  6933.     elseif num == 7 then
  6934.         return "Septuple"
  6935.     elseif num == 8 then
  6936.         return "Octuple"
  6937.     elseif num == 9 then
  6938.         return "Nonuple"
  6939.     elseif num == 10 then
  6940.         return "Decuple"
  6941.     end
  6942. end
  6943.  
  6944. -- Time Functions
  6945.  
  6946. function secondsToTime(seconds)
  6947.  
  6948.     if seconds == -1 then
  6949.         return "Infinite"
  6950.     end
  6951.  
  6952.     if seconds == 0 then
  6953.         return "0 seconds"
  6954.     end
  6955.    
  6956.     local days = math.floor(seconds / (60 * 60 * 24))
  6957.     seconds = seconds % (60 * 60 * 24)
  6958.     local hours = math.floor(seconds / (60 * 60))
  6959.     seconds = seconds % (60 * 60)
  6960.     local minutes = math.floor(seconds / 60)
  6961.     seconds = seconds % 60
  6962.    
  6963.     local time = {}
  6964.    
  6965.     if days > 0 then
  6966.         if days > 1 then
  6967.             table.insert(time, days .. " days")
  6968.         else
  6969.             table.insert(time, days .. " day")
  6970.         end
  6971.     end
  6972.    
  6973.     if hours > 0 then
  6974.         if hours > 1 then
  6975.             table.insert(time, hours .. " hours")
  6976.         else
  6977.             table.insert(time, hours .. " hour")
  6978.         end
  6979.     end
  6980.    
  6981.     if minutes > 0 then
  6982.         if minutes > 1 then
  6983.             table.insert(time, minutes .. " minutes")
  6984.         else
  6985.             table.insert(time, minutes .. " minute")
  6986.         end
  6987.     end
  6988.    
  6989.     if seconds > 0 then
  6990.         if seconds > 1 then
  6991.             table.insert(time, seconds .. " seconds")
  6992.         else
  6993.             table.insert(time, seconds .. " second")
  6994.         end
  6995.     end
  6996.    
  6997.     if #time > 1 then
  6998.         table.insert(time, #time, "and")
  6999.         time[#time - 1] = table.concat(time, " ", #time - 1, #time)
  7000.         table.remove(time, #time)
  7001.     end
  7002.    
  7003.     local str
  7004.     if #time <= 2 then
  7005.         str = table.concat(time, " ")
  7006.     else
  7007.         str = table.concat(time, ", ")
  7008.     end
  7009.    
  7010.     return str
  7011. end
  7012.  
  7013. -- Math Functions
  7014.  
  7015. function editValue(current, edit)
  7016.  
  7017.     edit = string.gsub(edit, "inf", "math.inf")
  7018.     cur = tonumber(current)
  7019.     if not tonumber(edit) then
  7020.         local f = loadstring("return " .. edit)
  7021.         local value = f()
  7022.         if value == math.inf then
  7023.             value = 10^25
  7024.         elseif value == -math.inf then
  7025.             value = -10^25
  7026.         end
  7027.         return value
  7028.     else
  7029.         return tonumber(edit)
  7030.     end
  7031. end
  7032.  
  7033. function math.round(input, precision)
  7034.  
  7035.     return math.floor(input * (10 ^ precision) + 0.5) / (10 ^ precision)
  7036. end
  7037.  
  7038. -- Tag Functions
  7039. -- The following functions were written by Smiley
  7040. function getobjecttag(m_objId)
  7041.  
  7042.     local m_object = getobject(m_objId)
  7043.     local object_map_id = readdword(m_object, 0x0)
  7044.  
  7045.     local map_pointer = 0x460678
  7046.     local map_base = readdword(map_pointer, 0x0)
  7047.     local map_tag_count = todec(endian(map_base, 0xC, 0x3))
  7048.     local tag_table_base = map_base + 0x28
  7049.     local tag_table_size = 0x20
  7050.  
  7051.     for i = 0, (map_tag_count - 1) do
  7052.         local tag_id = todec(endian(tag_table_base, 0xC + (tag_table_size * i), 0x3))
  7053.  
  7054.         if tag_id == object_map_id then
  7055.             local tag_class = readstring(tag_table_base, (tag_table_size * i), 0x3, 1)
  7056.             local tag_name_address = endian(tag_table_base, 0x10 + (tag_table_size * i), 0x3)
  7057.             local tag_name = readtagname("0x" .. tag_name_address)
  7058.  
  7059.             return tag_class, tag_name
  7060.         end
  7061.     end
  7062. end
  7063.  
  7064. function gettagaddress(tagtype, tagname)
  7065.  
  7066.     -- map header
  7067.     local map_header_size = 0x800 -- Confirmed. (2048 bytes)
  7068.     local map_header_head = readstring(map_header_base, 0x0, 1) -- Confirmed. (head = daeh)
  7069.     local map_header_version = readbyte(map_header_base, 0x4) -- Confirmed. (Xbox = 5) (Trial = 6) (PC = 7) (CE = 0x261 = 609)
  7070.     local map_header_map_size = todec(endian(map_header_base, 0x8, 0x3)) -- Confirmed. (Bytes)
  7071.     local map_header_index_offset = endian(map_header_base, 0x10, 0x2) -- Confirmed. (Hex)
  7072.     local map_header_meta_data_size = endian(map_header_base, 0x14, 0x2) -- Confirmed. (Hex)
  7073.     local map_header_map_name = readstring(map_header_base, 0x20, 0x9) -- Confirmed.
  7074.     local map_header_build = readstring(map_header_base, 0x40, 0xC) -- Confirmed.
  7075.     local map_header_map_type = readbyte(map_header_base, 0x60) -- Confirmed. (SP = 0) (MP = 1) (UI = 2)
  7076.     -- Something from 0x64 to 0x67.
  7077.     local map_header_foot = readstring(map_header_base, 0x7FC, 0x3, 1) -- Confirmed. (foot = toof)
  7078.  
  7079.     --tag table setup
  7080.     local map_base = readdword(map_pointer, 0x0) -- Confirmed. (0x40440000)
  7081.     local map_magic = tohex(map_base - todec(map_header_index_offset)) -- Confirmed. (Hex)
  7082.     local tag_table_base_pointer = endian(map_base, 0x0, 0x3)
  7083.     local tag_table_first_tag_id = endian(map_base, 0x4, 0x3)
  7084.     local map_id = endian(map_base, 0x8, 0x3)
  7085.     local map_tag_count = todec(endian(map_base, 0xC, 0x3)) -- Confirmed.
  7086.     local map_verticie_count = todec(endian(map_base, 0x10, 0x3))
  7087.     local map_verticie_offset = endian(map_base, 0x14, 0x2)
  7088.     local map_indicie_count = todec(endian(map_base, 0x18, 0x3))
  7089.     local map_indicie_offset = endian(map_base, 0x1C, 0x2)
  7090.     local map_model_data_size = endian(map_base, 0x20, 0x2)
  7091.     local tag_table_tags = readstring(map_base, 0x24, 0x3, 1) -- Confirmed. "Tags"
  7092.     local tag_table_base = map_base + 0x28 -- Confirmed. (0x40440028)
  7093.     local tag_table_size = 0x20 -- Confirmed.
  7094.  
  7095.     -- tag table
  7096.     local scnr_tag_class = readstring(tag_table_base, 0x0, 0x3, 1) -- Confirmed.
  7097.     local scnr_tag_class2 = readstring(tag_table_base, 0x4, 0x7, 1) -- Confirmed.
  7098.     local scnr_tag_class3 = readstring(tag_table_base, 0x8, 0xB, 1) -- Confirmed.
  7099.     local scnr_tag_id = endian(tag_table_base, 0xC, 0x3) -- Confirmed.
  7100.     local scnr_tag_name_address = endian(tag_table_base, 0x10, 0x3) -- Confirmed.
  7101.     local scnr_tag_address = endian(tag_table_base, 0x14, 0x3) -- Confirmed.
  7102.     local scnr_tag_name = readtagname("0x" .. scnr_tag_name_address) -- Confirmed.
  7103.    
  7104.     local tag_address = 0
  7105.  
  7106.     for i=0,(map_tag_count - 1) do
  7107.    
  7108.         local tag_class = readstring(tag_table_base, (tag_table_size * i), 0x3, 1)
  7109.         local tag_id = todec(endian(tag_table_base, 0xC + (tag_table_size * i), 0x3))
  7110.         local tag_name_address = endian(tag_table_base, 0x10 + (tag_table_size * i), 0x3)
  7111.         local tag_name = readtagname("0x" .. tag_name_address)
  7112.  
  7113.         if tag_id == tagtype or (tag_class == tagtype and tag_name == tagname) then
  7114.             tag_address = todec(endian(tag_table_base, 0x14 + (tag_table_size * i), 0x3))
  7115.             break
  7116.         end
  7117.     end
  7118.  
  7119.     return tag_address
  7120. end
  7121.  
  7122. -- Reading Functions --
  7123.  
  7124. function readstring(address, offset, length, endian)
  7125.  
  7126.     local char_table = {}
  7127.     local string = ""
  7128.     for i=0,length do  
  7129.         if readbyte(address, (offset + (0x1 * i))) ~= 0 then       
  7130.             table.insert(char_table, string.char(readbyte(address, (offset + (0x1 * i)))))         
  7131.         end    
  7132.     end
  7133.     for k,v in pairs(char_table) do
  7134.         if endian == 1 then    
  7135.             string = v .. string           
  7136.         else       
  7137.             string = string .. v           
  7138.         end    
  7139.     end
  7140.  
  7141.     return string
  7142. end
  7143.  
  7144. function readtagname(address)
  7145.  
  7146.     local char_table = {}
  7147.     local i = 0
  7148.     local string = ""
  7149.     while readbyte(address, (0x1 * i)) ~= 0 do 
  7150.         table.insert(char_table, string.char(readbyte(address, (0x1 * i))))
  7151.         i = i + 1      
  7152.     end
  7153.     for k,v in pairs(char_table) do
  7154.         string = string .. v       
  7155.     end
  7156.  
  7157.     return string
  7158. end
  7159.  
  7160. -- Other --
  7161.  
  7162. function endian(address, offset, length)
  7163.  
  7164.     local data_table = {}
  7165.     local data = ""
  7166.     for i=0,length do
  7167.         local hex = string.format("%X", readbyte(address, offset + (0x1 * i)))
  7168.         if tonumber(hex, 16) < 16 then     
  7169.             hex = 0 .. hex         
  7170.         end
  7171.         table.insert(data_table, hex)
  7172.     end
  7173.     for k,v in pairs(data_table) do
  7174.         data = v .. data
  7175.     end
  7176.  
  7177.     return data
  7178. end
  7179.  
  7180. function tohex(number)
  7181.  
  7182.     return string.format("%X", number)
  7183. end
  7184.  
  7185. function todec(number)
  7186.  
  7187.     return tonumber(number, 16)
  7188. end
  7189.  
  7190. -- Table Functions --
  7191.  
  7192. -- Returns the key of the maximum numerical value of the specified table.
  7193. function table.max(t)
  7194.  
  7195.     local key, max = 0, 0
  7196.     for k,v in pairs(t) do
  7197.         if type(v) == "number" then
  7198.             if v > max then
  7199.                 max = v
  7200.                 key = k
  7201.             end
  7202.         end
  7203.     end
  7204.  
  7205.     return key
  7206. end
  7207.  
  7208. function table.len(t)
  7209.  
  7210.     local count = 0
  7211.     for k,v in pairs(t) do
  7212.         count = count + 1
  7213.     end
  7214.     return count
  7215. end
  7216.  
  7217. function table.random(array, n, allow_multiple)
  7218.  
  7219.     n = math.min(n, #array)
  7220.     local chosen = {}
  7221.     for i = 1, n do
  7222.         local rand
  7223.         if not allow_multiple then
  7224.             repeat
  7225.                 rand = getrandomnumber(1, #array + 1)
  7226.             until not table.find(chosen, rand)
  7227.             table.insert(chosen, array[rand])
  7228.         else
  7229.             table.insert(chosen, array[getrandomnumber(1, #array + 1)])
  7230.         end
  7231.     end
  7232.    
  7233.     return chosen
  7234. end
Advertisement
Add Comment
Please, Sign In to add comment