Python1320

Omg epic shitty data transfer thing

Jul 21st, 2011
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.31 KB | None | 0 0
  1.  
  2. local Tag="hdata"
  3.  
  4.  
  5. -- HELPERS -------------------------------------------------------------
  6.  
  7. local tostring=tostring
  8. local setmetatable=setmetatable
  9. local hook=hook
  10. local table=table
  11. local pairs=pairs
  12. local type=type
  13. local string=string
  14. local HTTPGet=HTTPGet
  15.  
  16.  
  17. local class do -- http://lua-users.org/wiki/SimpleLuaClasses
  18.     -- class.lua
  19.     -- Compatible with Lua 5.1 (not 5.0).
  20.     class = function(base, init)
  21.        local c = {}    -- a new class instance
  22.        if not init and type(base) == 'function' then
  23.           init = base
  24.           base = nil
  25.        elseif type(base) == 'table' then
  26.         -- our new class is a shallow copy of the base class!
  27.           for i,v in pairs(base) do
  28.              c[i] = v
  29.           end
  30.           c._base = base
  31.        end
  32.        -- the class will be the metatable for all its objects,
  33.        -- and they will look up their methods in it.
  34.        c.__index = c
  35.  
  36.        -- expose a constructor which can be called by <classname>(<args>)
  37.        local mt = {}
  38.        mt.__call = function(class_tbl, ...)
  39.        local obj = {}
  40.        setmetatable(obj,c)
  41.        if init then
  42.           init(obj,...)
  43.        else
  44.           -- make sure that any stuff from the base class is initialized!
  45.           if base and base.init then
  46.           base.init(obj, ...)
  47.           end
  48.        end
  49.        return obj
  50.        end
  51.        c.init = init
  52.        c.is_a = function(self, klass)
  53.           local m = getmetatable(self)
  54.           while m do
  55.              if m == klass then return true end
  56.              m = m._base
  57.           end
  58.           return false
  59.        end
  60.        setmetatable(c, mt)
  61.        return c
  62.     end
  63. end -- http://lua-users.org/wiki/SimpleLuaClasses
  64.  
  65. --[[TEST
  66. local _class = class(function(a,name)
  67.    a.name = name
  68. end)
  69. --_class.__newindex=function(a,b,c) print("asserttest","newindex",type(a),type(b),type(c)) rawset(a,b,c) end
  70. _class.__tostring=function(s)return s.name end
  71. local name="test"
  72. local _=_class(name)
  73. assert(tostring(_)==name)
  74. _.testkey="testvalue"
  75. _=nil
  76. _class=nil
  77. --]]--ETEST
  78.  
  79.  
  80. local insert=table.insert
  81. local remove=table.remove
  82. local Empty=table.Empty
  83.  
  84.  
  85.  
  86.  
  87. local function unescape (str)
  88.     str = string.gsub (str, "+", " ")
  89.     str = string.gsub (str, "%%(%x%x)", function(h) return string.char(tonumber(h,16)) end)
  90.     str = string.gsub (str, "\r\n", "\n")
  91.     return str
  92. end
  93.  
  94. local function escape (str)
  95.     str = string.gsub (str, "\n", "\r\n")
  96.     str = string.gsub (str, "([^0-9a-zA-Z ])", -- locale independent
  97.         function (c) return string.format ("%%%02X", string.byte(c)) end)
  98.     str = string.gsub (str, " ", "+")
  99.     return str
  100. end
  101.  
  102.  
  103.  
  104. -------------------------------------------------------------
  105. -------------------------------------------------------------
  106. -------------------------------------------------------------
  107.  
  108.  
  109.  
  110. local FIFO do -- STACK IMPLEMENTATION
  111.     FIFO=class()
  112.     function FIFO:__tostring() return "< Stack "..tostring(self:len()).." >" end
  113.  
  114.     -- Pop
  115.     function FIFO:pop()
  116.         return remove( self , self.lilo and #self or 1 )
  117.     end
  118.  
  119.     -- push
  120.     function FIFO.push(a,b)
  121.         insert( a , b )
  122.         return a
  123.     end
  124.  
  125.     function FIFO:len()
  126.         return #self
  127.     end
  128.  
  129.     function FIFO:length()
  130.         return #self
  131.     end
  132.  
  133.     function FIFO:clear()
  134.         return Empty( self )
  135.     end
  136.    
  137. end -- STACK IMPLEMENTATION
  138.  
  139. --[[TEST
  140. local _=FIFO()
  141. assert(_:push("a")==_)
  142. assert(_:push("b")==_)
  143. assert(_:pop()=="a")
  144. print("asserttest",_)
  145. assert(_:pop()=="b")
  146. assert(!_:pop())
  147.  
  148. _=nil
  149. --]]--ETEST
  150.  
  151. local thinks do -- THINK IMPLEMENTATION
  152.     local Now=SysTime
  153.    
  154.     thinks=class(function(self,add_shutdown_hook)
  155.         if add_shutdown_hook==true then
  156.             hook.Add('Shutdown',self,function()
  157.                 if not self or not self.ThinkForever then return end
  158.                 print(self,"Finishing thinking")
  159.                 self:ThinkForever(10)
  160.             end)
  161.         end
  162.     end)
  163.     meta.name="Think Queue"
  164.  
  165.     function thinks:__tostring() return "< ".."Thinks".." - "..table.Count(self).." thinks >" end
  166.    
  167.     function thinks:Add(obj,thinkfunc)
  168.         self[obj]=thinkfunc or true
  169.         if not hook:GetTable().Think[Tag] then
  170.             --dprint("Adding think")
  171.             hook.Add('Think',Tag,function() self:Think() end)
  172.         end
  173.     end
  174.     function thinks:Remove(obj)
  175.         if self[obj] then
  176.             self[obj]=nil
  177.             return true
  178.         end
  179.         return false
  180.     end
  181.    
  182.     function thinks:Exec( thinkfunc,obj )  
  183.         local bOk, strReturn = pcall( thinkfunc,obj )
  184.         if !bOk then
  185.             ErrorNoHalt( "Think failure:"+strReturn )
  186.         end
  187.     end
  188.    
  189.     function thinks:Think()
  190.         local done=true
  191.         for obj,thinkfunc in pairs(self) do
  192.             done=false
  193.             self:Exec( thinkfunc,obj ) 
  194.         end
  195.         if done then
  196.             --dprint("Removing thinking")
  197.             hook.Remove('Think',Tag)
  198.         end
  199.     end
  200.    
  201.     function thinks:ThinkForever(timeout)
  202.        
  203.         -- optimization
  204.         if table.Count(self) == 0 then return end
  205.        
  206.         local started=Now()
  207.         local done=false
  208.         if !timeout then error"no timeout specified" end
  209.         while not done do
  210.             done=true
  211.             for obj,thinkfunc in pairs(self) do
  212.                 done=false
  213.                 self:Exec( thinkfunc,obj )
  214.             end
  215.            
  216.             if (Now()-started) < timeout then
  217.                 ErrorNoHalt(tostring(self).." exceeded timeout ("..timeout.." seconds), killed!\n")
  218.                 break
  219.             end
  220.            
  221.         end
  222.        
  223.         if done then
  224.             print(self,"Emptied queue")
  225.         end
  226.        
  227.     end
  228.    
  229. end -- THINK IMPLEMENTATION
  230.  
  231. --[[TEST
  232. local _=thinks()
  233. local boo=false
  234. _:Add("!",function() boo=true _:Remove("!") end)
  235. _:Add("_",function() end)
  236. _:Think()_:Think()_:Think()_:Think()_:Think()
  237. assert(boo==true)
  238. print("asserttest",_)
  239. assert(_:Remove("_")==true)
  240. print("asserttest",_)
  241. _:Think()
  242. --]]--ETEST
  243.  
  244. local thinks=thinks()
  245.  
  246.  
  247. local HTTPQueryObject do -- HTTP QUERY OBJECT HELPERS
  248.     HTTPQueryObject=class()
  249.    
  250.  
  251.     function HTTPQueryObject:__tostring()  
  252.         return "< ".."HTTPQueryObject".." - Timeout "..tostring(self:GetTimeout() or 0).." - Started "..tostring(self:GetStarted()).." >"
  253.     end
  254.  
  255.     AccessorFunc(HTTPQueryObject,"__headers","Header",FORCE_STRING)
  256.     AccessorFunc(HTTPQueryObject,"__callback","Callback")
  257.     AccessorFunc(HTTPQueryObject,"__timeout","Timeout",FORCE_NUMBER)
  258.     AccessorFunc(HTTPQueryObject,"__started","Started",FORCE_BOOL)
  259.        
  260.  
  261. end -- HTTP QUERY OBJECT HELPERS
  262.  
  263.  
  264.  
  265. --[[TEST
  266. local _=HTTPQueryObject()
  267. _:SetStarted(true)
  268. assert(_:GetStarted()==true)
  269. print("asserttest",_)
  270. assert(tostring(_)!="")
  271. _=nil
  272. --]]--ETEST
  273.  
  274.  
  275.  
  276.  
  277. local queryqueue do -- QUERY QUEUE IMPLEMENTATION
  278.    
  279.     queryqueue  = class(function( tbl, host )
  280.         local http = tbl:GetHTTPGet()
  281.         assert(http:Finished()==false)
  282.         tbl:__sethost(host or "http://gmod.iriz.org:20090")
  283.         tbl.stack=FIFO()
  284.         return tbl
  285.     end)
  286.    
  287.     function queryqueue:__tostring()   
  288.         return "< ".."Query Object".." >"
  289.     end
  290.            
  291.  
  292.     function queryqueue:GetProcess()
  293.         return self.__proc
  294.     end
  295.     function queryqueue:SetProcess(proc)
  296.         self.__proc = proc
  297.     end
  298.    
  299.     function queryqueue:GetHTTPGet(new)
  300.         if new or not self.__HTTPGet then
  301.             self.__HTTPGet=HTTPGet()
  302.         end
  303.         return self.__HTTPGet
  304.     end
  305.    
  306.     -- not finished if not even started!!
  307.     function queryqueue:HTTPIsFinished()
  308.         return self:GetHTTPGet():Finished()
  309.     end
  310.    
  311.  
  312.    
  313.     function queryqueue:GetCurrentData( raw )
  314.             local buf = self:GetHTTPGet():GetBuffer()
  315.             local len = self:GetHTTPGet():DownloadSize()
  316.            
  317.             -- http.Get does this for some reason...
  318.             local data = raw and buf or buf:gsub( "\r\n","\n")
  319.            
  320.             return data,len
  321.     end
  322.    
  323.     function queryqueue:Download(host,header)  
  324.         if header and header:len() > 0 then -- hack
  325.             header="Accept: */*\n"..header
  326.         else
  327.             header = ""
  328.         end
  329.        
  330.         self:GetHTTPGet():Download(host,header)
  331.        
  332.     end
  333.    
  334.     function queryqueue:Process(proc)
  335.        
  336.         local started = proc:GetStarted()
  337.         if not started then
  338.             proc:SetStarted(true)
  339.             self:GetHTTPGet(true) -- We need to reset it :\
  340.             --dprint("Started processing new",proc,"to",self:gethost())
  341.            
  342.             --proc:GetTimeout()
  343.            
  344.             self:Download( self:gethost(), proc:GetHeader())
  345.         end
  346.        
  347.        
  348.         if proc:GetStarted() and self:HTTPIsFinished() then
  349.             local proc = self:GetProcess()
  350.             self:SetProcess( nil )
  351.            
  352.             local callback = proc:GetCallback()
  353.             if not callback then
  354.                 --dprint("processed",proc,"without callbacks?")
  355.                 return
  356.             end
  357.            
  358.             local buf,len=self:GetCurrentData()
  359.            
  360.             local ok, ret = pcall( callback, buf, len )
  361.             if not ok then
  362.                 ErrorNoHalt( meta.name.." callback error: "+ret+"\n" )
  363.             end
  364.  
  365.         end
  366.        
  367.     end
  368.  
  369.     function queryqueue:Think()
  370.         local proc=self:GetProcess()
  371.         if proc then
  372.             self:Process(proc)
  373.             return
  374.         end
  375.         if self:GetProcess() then return end
  376.         local newdata=self.stack:pop()
  377.         if newdata then
  378.             --print("grabbing new process",newdata)
  379.             self:SetProcess( newdata )
  380.             return
  381.         end
  382.         --dprint("stopped thinking",self)
  383.         thinks:Remove(self)
  384.     end
  385.  
  386.     function queryqueue:Wake()
  387.         if self.stack:len() > 0 then
  388.             --dprint("waking up")
  389.             thinks:Add(self,self.Think)
  390.         end
  391.     end
  392.  
  393.     function queryqueue:query(header,callback,timeout)
  394.        
  395.         local proc = HTTPQueryObject()
  396.        
  397.         if header then
  398.             proc:SetHeader(header)
  399.         end
  400.         if callback then
  401.             proc:SetCallback(callback)
  402.         end
  403.         if timeout then
  404.             proc:SetTimeout(timeout)
  405.         end
  406.            
  407.         self.stack:push(proc)
  408.         self:Wake()
  409.     end
  410.     function queryqueue:gethost()
  411.         return self.def_host
  412.     end
  413.     function queryqueue:__sethost(host)
  414.         self.def_host = host
  415.     end
  416.    
  417.     function queryqueue:GetQueueLength()
  418.         return self.stack:len()
  419.     end
  420.  
  421. end -- QUERY QUEUE IMPLEMENTATION
  422.  
  423.  
  424.  
  425. --[[TEST
  426. local host="http://iriz.org"
  427. _G._=queryqueue(host)
  428. local _=_G._
  429. assert(_:HTTPIsFinished()==false)
  430. _:query(nil,function(a,b)print("callback:",a:len()) assert(a:len()>0) end,0)
  431. _:query(nil,function(a,b)print("callback:",a:len()) assert(a:len()>0) end,0)
  432. assert(_:GetQueueLength()==2)
  433. print("host:",_:gethost())
  434. assert(_:gethost()==host)
  435. --]]--ETEST
  436.  
  437. local hyperdata do -- HYPERDATA IMPLEMENTATION
  438.  
  439.     hyperdata=class(function(tbl,host)
  440.         tbl.httpqueue=queryqueue(host or "http://gmod.iriz.org:20090") or "HURR??"
  441.         --dprint("New",self)
  442.         return tbl
  443.     end)
  444.    
  445.     function hyperdata:__tostring()
  446.         return "< ".."Hyperdata".." - "..tostring(self:gethost()).." >"
  447.     end
  448.  
  449.     function hyperdata:gethost()
  450.         return self:GetQueryQueue():gethost()
  451.     end
  452.  
  453.     function hyperdata:test(callback)
  454.         http.Get(self:gethost(),"",function(_,b)
  455.             callback(b>0)
  456.         end)
  457.     end
  458.  
  459.     function hyperdata:GetQueryQueue()
  460.         return self.httpqueue
  461.     end
  462.    
  463.     function hyperdata:request_kv(keyvalues,callback)
  464.         if !keyvalues then error"need juice" end
  465.         local payload=""
  466.         local first=true
  467.         for k,v in pairs(keyvalues) do
  468.             --dprint"ADDING SHIT"
  469.             local str=(first and "" or "\n")..escape(tostring(k))..": "..escape(tostring(v))
  470.             first=false
  471.             payload=payload..str
  472.         end
  473.         self:GetQueryQueue():query(payload,callback,0)
  474.     end
  475.    
  476.    
  477. end -- HYPERDATA IMPLEMENTATION
  478.  
  479.  
  480.  
  481. /*
  482.  
  483. local _=hyperdata("http://iriz.org:20090")
  484. --_:test(function(works)
  485. --  assert(works)
  486.     _:request_kv(
  487.         { type="test",
  488.             Data=data,
  489.         },function(str,len)
  490.         local binary=str:find("\0",1,true)
  491.         print("Backend response ("..len.."): '"..tostring(binary and "binary data" or str).."'")
  492.         if binary then
  493.             file.Write("bintest_recv.txt",str)
  494.             if data!=str then
  495.                 for i=1,#data do
  496.                     if data[i]!=str[i] then
  497.                         print("DATA DIFF AT POS "..i,string.byte(data[i]),string.byte(str[i]))
  498.                         print("diffbytes:","'"..data[i].."'","'"..str[i].."'")
  499.                         break
  500.                     end
  501.                 end
  502.             else
  503.                 print"data is the same :o"
  504.             end
  505.            
  506.         end
  507.     end)
  508. --end)*/
  509.  
  510. _G.coins=hyperdata("http://iriz.org:20090")
  511. local coins=_G.coins
  512. function coins:GetCoins(steamid64,callback)
  513.     local steamid64=steamid64
  514.    
  515.     coins:request_kv(
  516.         { type="getcoins",
  517.             sid64=steamid64,
  518.         },function(str,len)
  519.             if len==0 then
  520.                 callback(false,"no reply")
  521.             end
  522.             if str:sub(1,6)!="COINS=" then
  523.                 if str:find("NOTFOUND",1,true) then
  524.                     callback(-1,steamid64)
  525.                 end
  526.                 callback(false,str)
  527.                 return
  528.             end
  529.             local coins=tonumber(str:match("COINS%=(%d+)"))
  530.             if !coins then
  531.                 callback(false,"bad coin reply:"..str)
  532.             end
  533.             callback(coins,steamid64)
  534.         end)
  535. end
  536.  
  537. function coins:SetCoins(steamid64,newcoins,callback)
  538.     local steamid64=steamid64
  539.     local newcoins=tonumber(newcoins)
  540.     coins:request_kv(
  541.         { type="setcoins",
  542.             sid64=steamid64,
  543.             coins=tostring(newcoins)
  544.         },function(str,len)
  545.             if len==0 then
  546.                 callback(false,"no reply")
  547.             end
  548.             if str:sub(1,8)!="SETCOINS" then
  549.                 callback(false,str)
  550.             else
  551.                 callback(true,steamid64,newcoins)
  552.             end
  553.         end)
  554. end
  555.  
  556. Say("setting coins to 5555555")
  557. coins:SetCoins("0",5555555,function(coins,a)Say(type(coins),coins,a)end)
  558. coins:GetCoins("0",function(coins)Say(type(coins),coins)end)
Advertisement
Add Comment
Please, Sign In to add comment