Guest User

Untitled

a guest
May 22nd, 2018
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.57 KB | None | 0 0
  1. --------------------
  2. --     Config     --
  3. --------------------
  4. local host = "123.456.789.012"
  5. local username = "user"
  6. local password = "pass"
  7. local database = "bans"
  8. local port = 3306
  9. local table = "gbans"
  10.  
  11. local updatetime = 1 -- How often, in minutes, it updates the bans from mysql.
  12. -- (So if a person banned from one server joins another server using the same DB, it could take up to this long to get rid of him/her)
  13.  
  14. local persistent = true -- Use a persistent MySQL connection?
  15.  
  16. local baninterval = 44000 -- Ban time to report to console. We can't use 0 because we don't want it to be saved with writeid. 44k minutes == 1 month.
  17. -- If you plan on keeping your server on one map without restarting for more than a month at a time (hah) then you'll need to up this value.
  18.  
  19. --[[
  20. Table structure:
  21. CREATE TABLE gbans (
  22. id INT UNSIGNED PRIMARY KEY NOT NULL UNIQUE AUTO_INCREMENT,
  23. steamid CHAR( 12 ) NOT NULL,
  24. name CHAR( 31 ),
  25. time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  26. unban_time TIMESTAMP NOT NULL DEFAULT 0,
  27. comment CHAR( 128 ),
  28. serverip INT UNSIGNED NOT NULL,
  29. serverport SMALLINT UNSIGNED NOT NULL DEFAULT 27015,
  30. adminname CHAR( 31 ),
  31. adminsteamid CHAR( 12 )
  32. );
  33. ]]--
  34.  
  35. require( "mysql" )
  36.  
  37. module( "UBan", package.seeall )
  38.  
  39. local db
  40.  
  41. Bans = {} -- Keep track of all the last known bans
  42.  
  43. function DoQuery( query, type )
  44.     local result, isok, err = mysql.query( db, query, type or mysql.QUERY_NUMERIC )
  45.  
  46.     if not isok and err == "" then isok = true end -- False positive
  47.  
  48.     if not isok then
  49.         error( tostring( err ), 2 )
  50.         return nil
  51.     end
  52.  
  53.     if result then
  54.         -- print( query ) -- For debug
  55.         -- PrintTable( result )
  56.     end
  57.  
  58.     return result
  59. end
  60.  
  61. function Connect()
  62.     if db then return db end -- Still connected
  63.  
  64.     db, err = mysql.connect( host, username, password, database, port )
  65.     if db == 0 then
  66.         db = nil
  67.         error( tostring( err ), 1 )
  68.         return
  69.     end
  70.  
  71.     return db
  72. end
  73.  
  74. function Disconnect( force )
  75.     if not db then return end -- Already disconnected
  76.     if persistent and not force then return end -- Don't disconnect, persistent
  77.  
  78.     local succ, err = mysql.disconnect( db )
  79.     if not succ then
  80.         error( tostring( err ), 2 )
  81.     end
  82.    
  83.     db = nil
  84. end
  85. hook.Add( "ShutDown", "UBanClose", function() Disconnect( true ) end ) -- Force closed on shutdown.
  86.  
  87. function Escape( str )
  88.     if not db then
  89.         Msg( "Not connected to DB.\n" )
  90.         return
  91.     end
  92.    
  93.     if not str then return end
  94.  
  95.     local esc, err = mysql.escape( db, str )
  96.     if not esc then
  97.         error( tostring( err ), 2 )
  98.         return nil
  99.     end
  100.  
  101.     -- print( "esc=" .. esc ) -- For debug
  102.     return esc
  103. end
  104.  
  105. -- Because we use this a lot
  106. function Format( str )
  107.     if not str then return "NULL" end
  108.     return string.format( "%q", str )
  109. end
  110.  
  111. -- Ban user
  112. function BanUser( banner, ply, time, comment )
  113.     local time2
  114.     if not time or time == 0 then
  115.         time2 = baninterval
  116.     else
  117.         time2 = math.min( time / 60, baninterval )
  118.     end
  119.  
  120.     local str = string.format( "kickid %s Banned on global ban list\n", ply:SteamID() )
  121.     game.ConsoleCommand( str )
  122.  
  123.     local str = string.format( "banid %f %s kick\n", time2, ply:SteamID() ) -- Convert time to minutes
  124.     game.ConsoleCommand( str )
  125.  
  126.     return ManualBan( banner, ply:SteamID(), ply:Nick(), time, comment )
  127. end
  128.  
  129. function ManualBan( banner, steamid, name, time, comment )
  130.     if not steamid then
  131.         error( "Bad arguments passed to UBan.ManualBan", 2 )
  132.         return
  133.     end
  134.  
  135.     Connect() -- Make sure we're connected
  136.  
  137.     local curuser = DoQuery( "SELECT CURRENT_USER()" )
  138.     curuser = curuser[ 1 ][ 1 ] -- Get to the info we want
  139.  
  140.     local curip = curuser:gsub( ".-@", "" ) or "127.0.0.1"
  141.     local curport = GetConVarNumber( "hostport" )
  142.  
  143.     steamid = steamid:upper():gsub( "STEAM_", "" )
  144.  
  145.     local bannername
  146.     local bannersteam
  147.     if banner and banner:IsValid() and banner:IsPlayer() then
  148.         bannername = banner:Nick()
  149.         bannersteam = banner:SteamID():upper():gsub( "STEAM_", "" )
  150.     end
  151.    
  152.     local timestring = "0" -- ban duration part
  153.     if time and time > 0 then
  154.         timestring = "ADDTIME( NOW(), SEC_TO_TIME( " .. time .. " ) )"
  155.     end
  156.  
  157.     local result
  158.     result = DoQuery( "INSERT INTO " .. table .. " ( steamid, name, unban_time, comment, serverip, serverport, adminname, adminsteamid ) VALUES( \"" ..
  159.        Escape( steamid ) .. "\", " .. Format( Escape( name ) ) .. ", " .. timestring .. ", " .. Format( Escape( comment ) ) .. ", INET_ATON( \"" .. curip .. "\" ), " .. curport .. ", " .. Format( Escape( bannername ) ) .. ", " .. Format( Escape( bannersteam ) ) .. " )" )
  160.  
  161.     if time == 0 then
  162.         Bans[ steamid ] = baninterval
  163.     else
  164.         Bans[ steamid ] = time
  165.     end
  166.  
  167.     Disconnect() -- Make sure we're disconnected
  168.  
  169.     return result
  170. end
  171.  
  172. function ClearBan( steamid )
  173.     steamid = steamid:upper():gsub( "STEAM_", "" )
  174.  
  175.     Connect() -- Make sure we're connected
  176.  
  177.     local results = DoQuery( "UPDATE " .. table .. " SET unban_time=NOW(), comment=CONCAT( \"(ban lifted before expired) \", comment ) WHERE (NOW() < unban_time OR unban_time = 0) AND steamid=\"" .. Escape( steamid ) .. "\"", mysql.QUERY_FIELDS ) -- Select active bans
  178.     game.ConsoleCommand( "removeid STEAM_" .. steamid .. "\n" )
  179.    
  180.     Bans[ steamid ] = nil
  181.  
  182.     Disconnect() -- Make sure we're disconnected
  183. end
  184.  
  185. function GetBans()
  186.     Connect() -- Make sure we're connected
  187.  
  188.     local results = DoQuery( "SELECT id, steamid, TIME_TO_SEC( TIMEDIFF( unban_time, NOW() ) ) as timeleft, name, time, unban_time, comment, INET_NTOA( serverip ) as serverip, serverport, adminname, adminsteamid FROM " .. table .. " WHERE NOW() < unban_time OR unban_time = 0", mysql.QUERY_FIELDS ) -- Select active bans
  189.  
  190.     Disconnect() -- Make sure we're disconnected
  191.  
  192.     return results
  193. end
  194.  
  195. function DoBans()
  196.     Connect()
  197.  
  198.     local results = DoQuery( "SELECT steamid, TIME_TO_SEC( TIMEDIFF( unban_time, NOW() ) ) as timeleft FROM " .. table .. " WHERE NOW() < unban_time OR unban_time = 0", mysql.QUERY_FIELDS ) -- Select active bans
  199.  
  200.     local steamids = {}
  201.  
  202.     for _, t in ipairs( results ) do
  203.         local steamid = t.steamid
  204.  
  205.         local time = t.timeleft
  206.         if not time or time == 0 then
  207.             time = baninterval
  208.         else
  209.             time = math.min( time / 60, baninterval )
  210.         end
  211.  
  212.         steamids[ steamid ] = math.max( time, steamids[ steamid ] or 0 ) -- We're doing this so oddly so we can catch multiple results and use the largest one.
  213.     end
  214.  
  215.     -- We're using this following chunk of code to identify current steamids in the server
  216.     local cursteamids = {}
  217.     local players = player.GetAll()
  218.     for _, ply in ipairs( players ) do
  219.         cursteamids[ ply:SteamID() ] = ply
  220.     end
  221.  
  222.     for steamid, time in pairs( steamids ) do -- loop through all currently banned ids
  223.         if cursteamids[ "STEAM_" .. steamid ] then -- Currently connected
  224.             local str = string.format( "kickid STEAM_%s Banned on global ban list\n", steamid )
  225.             game.ConsoleCommand( str )
  226.             Bans[ steamid ] = nil -- Clear their ban info to make sure they get banned. (A 'reban' should only ever arise if console removeid's a steamid)
  227.         end
  228.  
  229.         if not Bans[ steamid ] or Bans[ steamid ] < time or Bans[ steamid ] > time + baninterval * 2 then -- If we don't already have them marked as banned or it's a new time
  230.             local str = string.format( "banid %f STEAM_%s kick\n", time, steamid )
  231.             game.ConsoleCommand( str )
  232.             -- print( str ) -- For debug
  233.         end
  234.         Bans[ steamid ] = time
  235.     end
  236.    
  237.     for steamid in pairs( Bans ) do -- loop through all recorded bans
  238.         if not steamids[ steamid ] then -- If they're not on the ban list we just pulled off the server, they're out of jail!
  239.             game.ConsoleCommand( "removeid STEAM_" .. steamid .. "\n" )
  240.             Bans[ steamid ] = nil
  241.         end
  242.     end
  243.    
  244.     Disconnect()
  245. end
  246.  
  247. DoBans() -- Initial
  248. timer.Create( "UBantimer", updatetime * 60, 0, DoBans ) -- Updates
Add Comment
Please, Sign In to add comment