Advertisement
rockbandcheeseman

PlayerIndexing

Feb 9th, 2013
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.80 KB | None | 0 0
  1. -- Player Indices
  2.  
  3. hashes = {}  -- Keeps track of players who have joined this round
  4.  
  5. function GetRequiredVersion()
  6.  
  7.     return 10058
  8. end
  9.  
  10. function OnScriptLoad(process)
  11.  
  12.  
  13. end
  14.  
  15. function OnScriptUnload()
  16.  
  17.     table.save(players, "players.data")
  18.     table.save(indices, "indices.data")
  19. end
  20.  
  21. function OnNewGame(map)
  22.  
  23.  
  24. end
  25.  
  26. function OnGameEnd(mode)
  27.  
  28.  
  29. end
  30.  
  31. function OnServerChat(player, chattype, message)
  32.  
  33.     return 1
  34. end
  35.  
  36. function OnServerCommand(admin, command)
  37.  
  38.     local cmd, args = cmdsplit(command)
  39.    
  40.     -- Players Commands --
  41.    
  42.     if cmd == "sv_players" then
  43.     -- Modified version of sv_players which prints players' indices as well as their IDs and names
  44.    
  45.         hprintf("ID   Index   Name")
  46.         for i = 0,15 do
  47.             local hash = gethash(i)
  48.             if hash then
  49.                 hprintf(resolveplayer(i) .. "    " .. players[hash].index .. "     " .. getname(i))
  50.             end
  51.         end
  52.        
  53.         return 0
  54.    
  55.     elseif cmd == "sv_players_recent" then
  56.     -- Prints indices and names of all players who have joined the server during this game (minus those who are still currently in it)
  57.        
  58.         hprintf("Index   Name")
  59.         for k,v in pairs(hashes) do
  60.             local found
  61.             for i = 0,15 do
  62.                 if gethash(i) == k then
  63.                     found = true
  64.                     break
  65.                 end
  66.             end
  67.            
  68.             if not found then
  69.                 hprintf(players[k].index .. "     " .. v)
  70.             end
  71.         end
  72.        
  73.         return 0
  74.    
  75.     elseif cmd == "sv_players_search" then
  76.     -- Prints a list of players' indices and names matching the name search specified
  77.    
  78.         local search = args[1]
  79.         local matches = {}
  80.         -- Loop through players table
  81.         for k,v in pairs(players) do
  82.             -- Find matches and organize by priority; more common aliases have higher priority
  83.             for name,v in pairs(v.alias) do
  84.                 local val = string.find(string.lower(name), string.lower(search))
  85.                 if val then
  86.                     table.insert(matches, {["priority"] = val + v, ["hash"] = k})
  87.                 end
  88.             end
  89.         end
  90.        
  91.         -- Sort matches table by priority value
  92.         table.sort(matches, function(a,b) return matches[a].priority > matches[b].priority end)
  93.        
  94.         if #matches > 0 then
  95.             hprintf("Players matching \"" .. search .. "\":")
  96.             hprintf("Index   Name")
  97.             -- Print up to 20 results
  98.             local len = math.min(#matches, 20)
  99.             for i = 1,len do
  100.                 hprintf(players[matches[i].hash].index .. "     " .. players[matches[i].hash].name)
  101.             end
  102.         end
  103.        
  104.         return 0
  105.    
  106.     -- Ban Commands
  107.  
  108.     elseif cmd == "sv_ban" then
  109.     -- Modified version of sv_ban allowing for Ban on Sight (banning a player via their Index while they aren't in the server puts them on the BOS list).  Also added a "name" parameter for those players who should be banned on sight who haven't yet joined the server with this script running (this parameter will be ignored in any other case).
  110.    
  111.         local id = args[1]
  112.         local duration = args[2] or "-1"
  113.         local name = args[3]
  114.        
  115.         if not id then
  116.             hprintf("Syntax: sv_ban <Player ID, Hash or Index> <opt: Duration> <opt: BOS Name (for players yet to join server)>")
  117.             return 0
  118.         end
  119.        
  120.         for i = 0,15 do
  121.             if getname(i) == id then
  122.                 return 1
  123.             end
  124.         end
  125.        
  126.         if string.len(id) < 3 then
  127.             return 1
  128.         end
  129.        
  130.         if indices[string.upper(id)] then
  131.             local hash = indices[string.upper(id)]
  132.             local player = hashtoplayer(hash)
  133.             if player then
  134.                 if duration == "-1" then
  135.                     svcmd("sv_ban " .. resolveplayer(player))
  136.                 else
  137.                     svcmd("sv_ban " .. resolveplayer(player) .. " " .. duration)
  138.                 end
  139.             else
  140.                 players[hash].bos = duration
  141.                 hprintf((hashes[hash] or players[hash].name) .. " will be banned on sight.")
  142.             end
  143.            
  144.             return 0
  145.         end
  146.        
  147.         if players[id] then
  148.             players[id].bos = duration
  149.             hprintf((hashes[id] or players[id].name) .. " will be banned on sight.")
  150.         else
  151.             name = name or "???"
  152.             players[id] = {}
  153.             players[id].bos = duration
  154.             players[id].name = name
  155.         end
  156.        
  157.     elseif cmd == "sv_unban" then
  158.     -- Modified version of sv_unban which allows the ability to unban from a player's Ban ID, Hash, or Index and takes the player off of the Ban on Sight list (even if they haven't been banned yet).
  159.        
  160.         local id = args[1]
  161.        
  162.         if not id then
  163.             hprintf("Syntax: sv_unban <Ban ID, Hash or Index>")
  164.             return 0
  165.         end
  166.        
  167.         local hash
  168.        
  169.         local dir = getprofilepath()
  170.         local banned = io.string(dir .. "\\banned.txt")
  171.         local lines = string.split(banned, "\n")
  172.        
  173.         for k,v in ipairs(lines) do
  174.             local split = string.split(v, ",")
  175.             local ban_id = split[1]
  176.             local ban_hash = split[3]
  177.             if tonumber(id) == tonumber(ban_id) then
  178.                 players[ban_hash].bos = nil
  179.                 return 1
  180.             end
  181.         end
  182.        
  183.         if indices[string.upper(id)] then
  184.             hash = indices[string.upper(id)]
  185.         elseif players[id] then
  186.             hash = id
  187.         end
  188.        
  189.         if hash then
  190.             players[hash].bos = nil
  191.             hprintf((hashes[id] or players[hash].name) .. " has been taken off of the Ban on Sight list.")
  192.            
  193.             for k,v in ipairs(lines) do
  194.                 local split = string.split(v, ",")
  195.                 local ban_id = split[1]
  196.                 local ban_hash = split[3]
  197.                 if hash == ban_hash then
  198.                     svcmd("sv_unban " .. ban_id)
  199.                     return 0
  200.                 end
  201.             end
  202.         else
  203.             hprintf("Invalid Player.")
  204.         end
  205.        
  206.     elseif cmd == "sv_bos_list" then
  207.     -- Lists all players on the Ban on Sight list
  208.        
  209.         hprintf("Players to be banned on sight (-1 duration specifies an indefinite ban):")
  210.        
  211.         for k,v in pairs(players) do
  212.             if players[k].bos then
  213.                 hprintf(players[k].index .. "  " .. (hashes[k] or players[k].name) .. "  " .. players[k].bos)
  214.             end
  215.         end
  216.        
  217.         return 0
  218.        
  219.     -- Alias
  220.    
  221.     elseif cmd == "sv_alias" then
  222.     -- Modified version of sv_alias which allows the ability to view a player's aliases by their Player ID, Hash or Index.  This does not include aliases previously saved by Phasor; the new version of Phasor will hopefully have a way to access the alias database via scripts.  Once that happens, I'll be able to add the aliases Phasor has stored into this command as well.
  223.        
  224.         local id = args[1]
  225.        
  226.         if not id then
  227.             hprintf("Syntax: sv_alias <Player ID, Hash or Index>")
  228.             return 0
  229.         end
  230.        
  231.         local hash
  232.        
  233.         if string.len(id) < 3 then
  234.             local player = rresolveplayer(tonumber(id))
  235.             hash = gethash(player)
  236.         elseif indices[string.upper(id)] then
  237.             hash = indices[string.upper(id)]
  238.         elseif players[id] then
  239.             hash = id
  240.         end
  241.        
  242.         if hash then
  243.             local aliases = {}
  244.             for k,v in pairs(players[hash].alias) do
  245.                 table.insert(aliases, k)
  246.             end
  247.            
  248.             table.sort(aliases, function(a,b) return players[hash].alias[a] > players[hash].alias[b] end)
  249.            
  250.             for k,v in ipairs(aliases) do
  251.                 aliases[k] = "[" .. players[hash].alias[v] .. "]: " .. aliases[k]
  252.             end
  253.            
  254.             local str = formatlist(aliases, "   ", 4)
  255.            
  256.             hprintf("Aliases for player " .. players[hash].index .. " sorted by most common alias:")
  257.             hprintf(str)
  258.             return 0
  259.         else
  260.             hprintf("Invalid Player.")
  261.             return 0
  262.         end
  263.  
  264.     -- Admin Commands
  265.    
  266.     elseif cmd == "sv_admin_add" then
  267.     -- Modified version of sv_admin_add which allows the ability to add admins with their Player ID, Hash or Index.  sv_admin_del does not need Index support because you can pull up the list of admins with sv_admin_list.
  268.        
  269.         local id = args[1]
  270.         local name = args[2]
  271.         local level = args[3]
  272.        
  273.         if not id then
  274.             hprintf("Syntax: sv_admin_add <Player ID, Hash or Index> <Authentication Name> <Level>")
  275.             return 0
  276.         end
  277.        
  278.         local hash
  279.        
  280.         if string.len(id) < 3 then
  281.             local player = rresolveplayer(tonumber(id))
  282.             hash = gethash(player)
  283.         elseif indices[string.upper(id)] then
  284.             hash = indices[string.upper(id)]
  285.         elseif players[id] then
  286.             return 1
  287.         else
  288.             players[id] = {}
  289.             players[id].name = name or "???"
  290.             hash = id
  291.         end
  292.        
  293.         if hash then
  294.             if name and level then
  295.                 svcmd("sv_admin_add " .. hash .. " " .. name .. " " .. level)
  296.             elseif name and not level then
  297.                 svcmd("sv_admin_add " .. hash .. " " .. name)
  298.             elseif not name and not level then
  299.                 svcmd("sv_admin_add " .. hash)
  300.             end
  301.         end
  302.        
  303.         return 0
  304.        
  305.     elseif cmd == "sv_commands" then
  306.        
  307.         registertimer(1, "DelayPrint")
  308.     end
  309.    
  310.     return 1
  311. end
  312.  
  313. function DelayPrint(id, count)
  314.  
  315.     hprintf("sv_players_recent       sv_players_search       sv_bos_list")
  316.     return 0
  317. end
  318.  
  319. function OnTeamDecision(team)
  320.  
  321.     return team
  322. end
  323.  
  324. function OnPlayerJoin(player, team)
  325.  
  326.     local hash = gethash(player)
  327.     updatePlayer(hash)
  328.     hashes[hash] = getname(player)
  329. end
  330.  
  331. function OnPlayerLeave(player, team)
  332.  
  333.  
  334. end
  335.  
  336. function OnPlayerKill(killer, victim, mode)
  337.  
  338.  
  339. end
  340.  
  341. function OnKillMultiplier(player, multiplier)
  342.  
  343.  
  344. end
  345.  
  346. function OnPlayerSpawn(player, m_objId)
  347.  
  348.  
  349. end
  350.  
  351. function OnPlayerSpawnEnd(player, m_objId)
  352.  
  353.    
  354. end
  355.  
  356. function OnTeamChange(relevant, player, cur_team, dest_team)
  357.  
  358.     return 1
  359. end
  360.  
  361. function OnObjectCreation(m_objId, player, tagName)
  362.  
  363.  
  364. end
  365.  
  366. function OnObjectInteraction(player, m_objId, tagType, tagName)
  367.    
  368.     return 1
  369. end
  370.  
  371. function OnWeaponAssignment(player, m_objId, slot, tagName)
  372.    
  373.     return 0
  374. end
  375.  
  376. function OnWeaponReload(player, m_weapId)
  377.  
  378.     return 1
  379. end
  380.  
  381. function OnDamageLookup(receiver, causer, tagData, tagName)
  382.  
  383.  
  384. end
  385.  
  386. function OnVehicleEntry(relevant, player, m_vehicleId, tagName, seat)
  387.  
  388.     return 1
  389. end
  390.  
  391. function OnVehicleEject(player, forced)
  392.  
  393.     return 1
  394. end
  395.  
  396. function OnClientUpdate(player, m_objId)
  397.  
  398.  
  399. end
  400.  
  401. math.inf = 1 / 0
  402.  
  403. function table.save(t, filename)
  404.  
  405.     local dir = getprofilepath()
  406.     local file = io.open(dir .. "\\data\\" .. filename, "w")
  407.     local spaces = 0
  408.  
  409.     local function tab()
  410.  
  411.         local str = ""
  412.         for i = 1,spaces do
  413.             str = str .. " "
  414.         end
  415.  
  416.         return str
  417.     end
  418.  
  419.     local function format(t)
  420.  
  421.         spaces = spaces + 4
  422.         local str = "{ "
  423.  
  424.         for k,v in pairs(t) do
  425.             -- Key datatypes
  426.             if type(k) == "string" then
  427.                 k = string.format("%q", k)
  428.             end
  429.  
  430.             -- Value datatypes
  431.             if type(v) == "string" then
  432.                 v = string.format("%q", v)
  433.             elseif v == math.inf then
  434.                 v = "1 / 0"
  435.             end
  436.  
  437.             if type(v) == "table" then
  438.                 if table.len(v) > 0 then
  439.                     str = str .. "\n" .. tab() .. "[" .. k .. "] = " .. format(v) .. ","
  440.                 else
  441.                     str = str .. "\n" .. tab() .. "[" .. k .. "] = {},"
  442.                 end
  443.             else
  444.                 str = str .. "\n" .. tab() .. "[" .. k .. "] = " .. tostring(v) .. ","
  445.             end
  446.         end
  447.  
  448.         spaces = spaces - 4
  449.  
  450.         return string.sub(str, 1, string.len(str) - 1) .. "\n" .. tab() .. "}"
  451.     end
  452.  
  453.     file:write("return " .. format(t))
  454.     file:close()
  455. end
  456.  
  457. function table.load(filename)
  458.  
  459.     local dir = getprofilepath()
  460.     local file = loadfile(dir .. "\\data\\" .. filename)
  461.     if file then
  462.         return file()
  463.     end
  464.    
  465.     return {}
  466. end
  467.  
  468. function table.len(t)
  469.  
  470.     local count = 0
  471.     for k,v in pairs(t) do
  472.         count = count + 1
  473.     end
  474.    
  475.     return count
  476. end
  477.  
  478. function table.max(t)
  479.  
  480.     local key
  481.     local max = -math.inf
  482.     for k,v in pairs(t) do
  483.         v = tonumber(v)
  484.         if v then
  485.             if v > max then
  486.                 key = k
  487.                 max = v
  488.             end
  489.         end
  490.     end
  491.    
  492.     return key, max
  493. end
  494.  
  495. players = table.load("players.data")
  496. indices = table.load("indices.data")
  497.  
  498. function hashtoplayer(hash)
  499.  
  500.     for i = 0,15 do
  501.         if gethash(i) then return i end
  502.     end
  503. end
  504.  
  505. function updatePlayer(hash, name)
  506.  
  507.     local player = hashtoplayer(hash)
  508.     local name = name or getname(player)
  509.    
  510.     players[hash] = players[hash] or {}
  511.     -- Name
  512.     players[hash].alias = players[hash].alias or {}
  513.     players[hash].alias[name] = (players[hash].alias[name] or 0) + 1
  514.     players[hash].name = players[hash].name or table.max(players[hash].alias)
  515.     -- Index
  516.     players[hash].index = players[hash].index or newIndex(hash)
  517.    
  518.     -- Check if the player should be banned on sight
  519.     if players[hash].bos then
  520.         if players[hash].bos == "-1" then
  521.             svcmd("sv_ban " .. resolveplayer(player))
  522.         else
  523.             svcmd("sv_ban " .. resolveplayer(player) .. " " .. players[hash].bos)
  524.         end
  525.        
  526.         players[hash].bos = nil
  527.     end
  528. end
  529.  
  530. function newIndex(hash)
  531.  
  532.     indices.unique = (indices.unique or 0) + 1
  533.     local index
  534.     repeat
  535.         index = convertbase((indices.next or 0), 36)
  536.         while string.len(index) < 3 do
  537.             index = "0" .. index
  538.         end
  539.         indices.next = (indices.next or 0) + 1
  540.     until validIndex(index)
  541.    
  542.     indices[index] = hash
  543.     return index
  544. end
  545.  
  546. function validIndex(entry)
  547.  
  548.     local invalid = {"red", "blue", "all", "me"}
  549.     for _,v in ipairs(invalid) do
  550.         if string.lower(entry) == v then
  551.             return false
  552.         end
  553.     end
  554.    
  555.     return true
  556. end
  557.  
  558. function convertbase(input, base)
  559.  
  560.     if not base or base == 10 then return tostring(input) end
  561.  
  562.     local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  563.     local answer = {}
  564.  
  565.     repeat
  566.         local digit = (input % base) + 1
  567.         input = math.floor(input / base)
  568.         table.insert(answer, 1, string.sub(digits, digit, digit))
  569.     until input == 0
  570.  
  571.     return table.concat(answer, "")
  572. end
  573.  
  574. function string.split(str, ...)
  575.  
  576.     for k,v in ipairs(arg) do
  577.         if v == "" then
  578.             local subs = {}
  579.             for i = 1,string.len(str) do
  580.                 table.insert(subs, string.sub(str, i, i))
  581.             end
  582.  
  583.             return subs
  584.         end
  585.     end
  586.  
  587.     local subs = {}
  588.     local sub = ""
  589.     for i = 1,string.len(str) do
  590.         local bool
  591.         local char = string.sub(str, i, i)
  592.         for k,v in ipairs(arg) do
  593.             local delim = string.sub(str, i - (string.len(v) - 1), i)
  594.             if v == delim then
  595.                 bool = true
  596.                 sub = string.sub(sub, 1, string.len(sub) - (string.len(v) - 1))
  597.                 if sub ~= "" then
  598.                     table.insert(subs, sub)
  599.                 end
  600.                 sub = ""
  601.                 break
  602.             end
  603.         end
  604.  
  605.         if not bool then
  606.             sub = sub .. char
  607.         end
  608.        
  609.         if i == string.len(str) then
  610.             table.insert(subs, sub)
  611.         end
  612.     end
  613.  
  614.     return subs
  615. end
  616.  
  617. function cmdsplit(str)
  618.  
  619.     local subs = {}
  620.     local sub = ""
  621.     local ignore_quote, inquote, endquote
  622.     for i = 1,string.len(str) do
  623.         local bool
  624.         local char = string.sub(str, i, i)
  625.         if char == " " then
  626.             if (inquote and endquote) or (not inquote and not endquote) then
  627.                 bool = true
  628.             end
  629.         elseif char == "\\" then
  630.             ignore_quote = true
  631.         elseif char == "\"" then
  632.             if not ignore_quote then
  633.                 if not inquote then
  634.                     inquote = true
  635.                 else
  636.                     endquote = true
  637.                 end
  638.             end
  639.         end
  640.        
  641.         if char ~= "\\" then
  642.             ignore_quote = false
  643.         end
  644.        
  645.         if bool then
  646.             if inquote and endquote then
  647.                 sub = string.sub(sub, 2, string.len(sub) - 1)
  648.             end
  649.            
  650.             if sub ~= "" then
  651.                 table.insert(subs, sub)
  652.             end
  653.             sub = ""
  654.             inquote = false
  655.             endquote = false
  656.         else
  657.             sub = sub .. char
  658.         end
  659.        
  660.         if i == string.len(str) then
  661.             if string.sub(sub, 1, 1) == "\"" and string.sub(sub, string.len(sub), string.len(sub)) == "\"" then
  662.                 sub = string.sub(sub, 2, string.len(sub) - 1)
  663.             end
  664.             table.insert(subs, sub)
  665.         end
  666.     end
  667.    
  668.     local cmd = subs[1]
  669.     local args = subs
  670.     table.remove(args, 1)
  671.    
  672.     return cmd, args
  673. end
  674.  
  675. function formatlist(t, delim, length)
  676.  
  677.     local str = ""
  678.     for k,v in ipairs(t) do
  679.         if k % length == 0 then
  680.             str = str .. v .. "\n"
  681.         else
  682.             str = str .. v .. delim
  683.         end
  684.     end
  685.    
  686.     return str
  687. end
  688.  
  689. function io.string(filename)
  690.  
  691.     local str
  692.     local file = io.open(filename, "a+")
  693.     if file then
  694.         str = file:read("*all")
  695.     end
  696.    
  697.     file:close()
  698.     return str
  699. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement