Advertisement
csmit195

admin_ip2c.lua -- edit

Mar 29th, 2013
603
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.16 KB | None | 0 0
  1. --[[**********************************
  2. *
  3. *   Multi Theft Auto - Admin Panel
  4. *
  5. *   admin_ip2c.lua
  6. *
  7. *   Original File by lil_Toady
  8. *
  9. **************************************]]
  10.  
  11. -- Code addition by csmit195:
  12. addCommandHandler('updateadmin',
  13. function(player)
  14.     if isGuestAccount(getPlayerAccount(player)) then return end
  15.     local accName = getAccountName(getPlayerAccount(player))
  16.     if isObjectInACLGroup('user.'..accName, aclGetGroup('Admin')) then
  17.         makeAndTestCompactCsv = true
  18.         outputChatBox('Admin countries downloading!', player, 200, 200, 200)
  19.         fetchRemote("http://mirrorformta.comuf.com/adminupdate.php", returnDownload, "", false, player)
  20.     end
  21. end )
  22. function returnDownload(responseData, errno, player)
  23.     outputChatBox('Download complete!', player)
  24.     file = fileCreate('conf/IpToCountry.csv')
  25.     fileWrite(file, responseData)
  26.     fileClose(file)
  27.     makecsv()
  28. end
  29.  
  30.  
  31. local aCountries = {}
  32. local makeCor
  33.  
  34. function getPlayerCountry ( player )
  35.     return getIpCountry ( getPlayerIP ( player ) )
  36. end
  37. function getIpCountry ( ip )
  38.     if not loadIPGroupsIsReady() then return false end
  39.     local ip_group = tonumber ( gettok ( ip, 1, 46 ) )
  40.     local ip_code = ( gettok ( ip, 2, 46 ) * 65536 ) + ( gettok ( ip, 3, 46 ) * 256 ) + ( gettok ( ip, 4, 46 ) )
  41.     if ( not aCountries[ip_group] ) then
  42.         return false
  43.     end
  44.     for id, group in ipairs ( aCountries[ip_group] ) do
  45.         local buffer = ByteBuffer:new( group )
  46.         local rstart = buffer:readInt24()
  47.         if ip_code >= rstart then
  48.             local rend = buffer:readInt24()
  49.             if ip_code <= rend then
  50.                 local rcountry = buffer:readBytes( 2 )
  51.                 return rcountry ~= "ZZ" and rcountry
  52.             end
  53.         end
  54.     end
  55.     return false
  56. end
  57.  
  58. -- Returns false if aCountries is not ready
  59. function loadIPGroupsIsReady ()
  60.     if ( get ( "*useip2c" ) == "false" ) then return false end
  61.     if ( #aCountries == 0 and not makeCor) then
  62.         makeCor = coroutine.create(loadIPGroupsWorker)
  63.         coroutine.resume(makeCor)
  64.     end
  65.     return makeCor == nil
  66. end
  67. setTimer( loadIPGroupsIsReady, 1000, 1 )
  68.  
  69. -- Load all IP groups from "conf/IpToCountryCompact.csv"
  70. function loadIPGroupsWorker ()
  71.     unrelPosReset()
  72.  
  73.     local readFilename = "conf/IpToCountryCompact.csv";
  74.     local hReadFile = fileOpen( readFilename, true )
  75.     if not hReadFile then
  76.         outputHere ( "Cannot read " .. readFilename )
  77.         return
  78.     end
  79.  
  80.     local buffer = ""
  81.     local tick = getTickCount()
  82.     while true do
  83.         local endpos = string.find(buffer, "\n")
  84.  
  85.         if makeCor and ( getTickCount() > tick + 50 ) then
  86.             -- Execution exceeded 50ms so pause and resume in 50ms
  87.             setTimer(function()
  88.                 local status = coroutine.status(makeCor)
  89.                 if (status == "suspended") then
  90.                     coroutine.resume(makeCor)
  91.                 elseif (status == "dead") then
  92.                     makeCor = nil
  93.                 end
  94.             end, 50, 1)
  95.             coroutine.yield()
  96.             tick = getTickCount()
  97.         end
  98.        
  99.         -- If can't find CR, try to load more from the file
  100.         if not endpos then
  101.             if fileIsEOF( hReadFile ) then
  102.                 break
  103.             end
  104.             buffer = buffer .. fileRead( hReadFile, 500 )
  105.         end
  106.  
  107.         if endpos then
  108.             -- Process line
  109.             local line = string.sub(buffer, 1, endpos - 1)
  110.             buffer = string.sub(buffer, endpos + 1)
  111.  
  112.             local parts = split( line, string.byte(',') )
  113.             if #parts > 2 then
  114.                 local rstart = tonumber(parts[1])
  115.                 local rend = tonumber(parts[2])
  116.                 local rcountry = parts[3]
  117.  
  118.                 -- Relative to absolute numbers
  119.                 rstart = unrelRange ( rstart )
  120.                 rend = unrelRange ( rend )
  121.  
  122.                 -- Top byte is group
  123.                 local group = math.floor( rstart / 0x1000000 )
  124.  
  125.                 -- Remove top byte from ranges
  126.                 rstart = rstart - group * 0x1000000
  127.                 rend = rend - group * 0x1000000
  128.  
  129.                 if not aCountries[group] then
  130.                     aCountries[group] = {}
  131.                 end
  132.                 local count = #aCountries[group] + 1
  133.  
  134.                 -- Add country/IP range to aCountries
  135.                 local buffer = ByteBuffer:new()
  136.                 buffer:writeInt24( rstart )
  137.                 buffer:writeInt24( rend )
  138.                 buffer:writeBytes( rcountry, 2 )
  139.                 aCountries[group][count] = buffer.data
  140.             end
  141.         end
  142.     end
  143.     fileClose(hReadFile)
  144.     makeCor = nil
  145.     collectgarbage("collect")
  146.  
  147.     -- Update currently connected players
  148.     for user,info in pairs( aPlayers ) do
  149.         info["country"] = getPlayerCountry ( user )
  150.  
  151.         -- Send info to all admins
  152.         for id, admin in ipairs(getElementsByType("player")) do
  153.             if ( hasObjectPermissionTo ( admin, "general.adminpanel" ) ) then
  154.                 triggerClientEvent ( admin, "aClientPlayerJoin", user, false, false, false, false, false, aPlayers[user]["country"] )
  155.             end
  156.         end
  157.     end
  158.  
  159.     return true
  160. end
  161.  
  162. -- For squeezing data together
  163. ByteBuffer = {
  164.     new = function(self, indata)
  165.         local newItem = { data = indata or "", readPos = 1 }
  166.         return setmetatable(newItem, { __index = ByteBuffer })
  167.     end,
  168.  
  169.     Copy = function(self)
  170.         return ByteBuffer:new(self.data)
  171.     end,
  172.  
  173.     -- Write
  174.     writeInt24 = function(self,value)
  175.         local b0 = math.floor(value / 1) % 256
  176.         local b1 = math.floor(value / 256) % 256
  177.         local b2 = math.floor(value / 65536) % 256
  178.         self.data = self.data .. string.char(b0,b1,b2)
  179.     end,
  180.  
  181.     writeBytes = function(self, chars, count)
  182.         self.data = self.data .. string.sub(chars,1,count)
  183.     end,
  184.  
  185.     -- Read
  186.     readInt24 = function(self,value)
  187.         local b0,b1,b2 = string.byte(self.data, self.readPos, self.readPos+2)
  188.         self.readPos = self.readPos + 3
  189.         return b0 + b1 * 256 + b2 * 65536
  190.     end,
  191.  
  192.     readBytes = function(self, count)
  193.         self.readPos = self.readPos + count
  194.         return string.sub(self.data, self.readPos - count, self.readPos - 1)
  195.     end,
  196. }
  197.  
  198.  
  199.  
  200. -- Make a stream of absolute numbers relative to each other
  201. local relPos = 0
  202. function relPosReset()
  203.     relPos = 0
  204. end
  205. function relRange( v )
  206.     local rel = v - relPos
  207.     relPos = v
  208.     return rel
  209. end
  210.  
  211. -- Make a stream of relative numbers absolute
  212. local unrelPos = 0
  213. function unrelPosReset()
  214.     unrelPos = 0
  215. end
  216. function unrelRange( v )
  217.     local unrel = v + unrelPos
  218.     unrelPos = unrel
  219.     return unrel
  220. end
  221.  
  222.  
  223. -- IP2C logging
  224. function outputHere( msg )
  225.     --outputServerLog ( msg )
  226.     outputChatBox ( msg )
  227. end
  228.  
  229.  
  230. ----------------------------------------------------------------------------------------
  231. --
  232. -- Set to true to enable commands "makecsv" and "iptest"
  233. --
  234. ----------------------------------------------------------------------------------------
  235. local makeAndTestCompactCsv = false
  236.  
  237.  
  238. local makeCor
  239.  
  240. -- Takes a 'IPV4 CSV' file sourced from http://software77.net/geo-ip/
  241. -- and makes a smaller one for use by Admin
  242.  
  243. function makecsv()
  244.     local status = makeCor and coroutine.status(makeCor)
  245.     if (status == "suspended") then
  246.         outputHere( "Please wait" )
  247.         return
  248.     end
  249.     makeCor = coroutine.create ( makeCompactCsvWorker )
  250.     coroutine.resume ( makeCor )
  251. end
  252.  
  253.  
  254. function makeCompactCsvWorker ()
  255.     outputHere ( "makeCompactCsv started" )
  256.     relPosReset()
  257.  
  258.     local readFilename = "conf/IpToCountry.csv";
  259.     local hReadFile = fileOpen( readFilename, true )
  260.     if not hReadFile then
  261.         outputHere ( "Cannot read " .. readFilename )
  262.         return
  263.     end
  264.  
  265.     local writeFilename = "conf/IpToCountryCompact.csv";
  266.     local hWriteFile = fileCreate( writeFilename, true )
  267.     if not hWriteFile then
  268.         fileClose(hReadFile)
  269.         outputHere ( "Cannot create " .. writeFilename )
  270.         return
  271.     end
  272.  
  273.     local tick = getTickCount()
  274.  
  275.     local cur = {}
  276.     local buffer = ""
  277.     while true do
  278.  
  279.         if ( makeCor and getTickCount() > tick + 50 ) then
  280.             -- Execution exceeded 50ms so pause and resume in 50ms
  281.             setTimer(function()
  282.                 local status = coroutine.status(makeCor)
  283.                 if (status == "suspended") then
  284.                     coroutine.resume(makeCor)
  285.                 elseif (status == "dead") then
  286.                     makeCor = nil
  287.                 end
  288.             end, 50, 1)
  289.             coroutine.yield()
  290.             tick = getTickCount()
  291.         end
  292.  
  293.         local endpos = string.find(buffer, "\n")
  294.  
  295.         -- If can't find CR, try to load more from the file
  296.         if not endpos then
  297.             if fileIsEOF( hReadFile ) then
  298.                 break
  299.             end
  300.             buffer = buffer .. fileRead( hReadFile, 500 )
  301.         end
  302.  
  303.         if endpos then
  304.             -- Process line
  305.             local line = string.sub(buffer, 1, endpos - 1)
  306.             buffer = string.sub(buffer, endpos + 1)
  307.  
  308.             -- If not a comment line
  309.             if string.sub(line,1,1) ~= '#' then
  310.                 -- Parse out required fields
  311.                 local _,_,rstart,rend,rcountry = string.find(line, '"(%w+)","(%w+)","%w+","%w+","(%w+)"' )
  312.                 if rcountry then
  313.  
  314.                     rstart = tonumber(rstart)
  315.                     rend = tonumber(rend)
  316.  
  317.                     --
  318.                     -- Save memory by joining ranges here
  319.                     --
  320.                     local group = math.floor( rstart / 0x1000000 )
  321.                     if group == cur.group and rstart == cur.rend + 1 and rcountry == cur.rcountry then
  322.                         -- We can extend previous range
  323.                         cur.rend = rend
  324.                     else
  325.                         -- Otherwise flush previous range
  326.                         writeCountryRange(hWriteFile, cur.rstart, cur.rend, cur.rcountry)
  327.                         -- and start a new one
  328.                         cur.group = group
  329.                         cur.rstart = rstart
  330.                         cur.rend = rend
  331.                         cur.rcountry = rcountry
  332.                     end
  333.                 end
  334.             end
  335.         end
  336.     end
  337.     -- Flush last range
  338.     writeCountryRange(hWriteFile, cur.rstart, cur.rend, cur.rcountry)
  339.     fileClose(hWriteFile)
  340.     fileClose(hReadFile)
  341.     outputHere ( "makeCompactCsv done" )
  342. end
  343.  
  344. function writeCountryRange(hWriteFile, rstart, rend, rcountry)
  345.     if not rstart then return end
  346.     -- Absolute to relative numbers
  347.     rstart = relRange( rstart )
  348.     rend = relRange( rend )
  349.     -- Output line
  350.     fileWrite( hWriteFile, rstart .. "," .. rend .. "," .. rcountry .. "\n" )
  351. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement