Advertisement
Guest User

Untitled

a guest
May 1st, 2019
2,978
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.45 KB | None | 0 0
  1. --[[
  2.     external datastore
  3.    
  4.     https://devforum.roblox.com/t/datastore-game-limits/238101/11
  5.    
  6.     w/ https://pastebin.com/M1pyBGgq
  7.    
  8. --]]
  9.  
  10. local jobid=game.JobId
  11. local url='http://127.0.0.1:3000'
  12. local function secret()
  13.     return'my code'
  14. end
  15.  
  16. local md={}
  17.  
  18. local function serialize(v)
  19.     local t=type(v)
  20.     return t=='number'and'n'..v or t=='string'and's'..v or v and'1'or'0'
  21. end
  22. local function deserialize(v)
  23.     if not v then return nil end
  24.     local c=v:sub(1,1)
  25.     return c=='n'and v:sub(2)+0 or c=='s'and v:sub(2)or v=='1'
  26. end
  27.  
  28. function md.flush()--wipes entire database
  29.     local body=_G.http:JSONDecode(_G.http:RequestAsync{
  30.         Url=url..'/flush',
  31.         Method='POST',
  32.         Headers={['Content-Type']='application/json',},
  33.         Body=_G.http:JSONEncode{
  34.             secret=secret(),
  35.         },
  36.     }.Body)
  37.     assert(body.err==nil,body.err)
  38.     return md
  39. end
  40.  
  41. function md.get(key)
  42.     local body=_G.http:JSONDecode(_G.http:RequestAsync{
  43.         Url=url..'/get',
  44.         Method='POST',
  45.         Headers={['Content-Type']='application/json',},
  46.         Body=_G.http:JSONEncode{
  47.             secret=secret(),
  48.             key=key,
  49.         },
  50.     }.Body)
  51.     assert(body.err==nil,body.err)
  52.     return deserialize(body.val)
  53. end
  54.  
  55. function md.set(key,val)
  56.     local body=_G.http:JSONDecode(_G.http:RequestAsync{
  57.         Url=url..'/set',
  58.         Method='POST',
  59.         Headers={['Content-Type']='application/json',},
  60.         Body=_G.http:JSONEncode{
  61.             secret=secret(),
  62.             key=key,
  63.             val=serialize(val),
  64.         },
  65.     }.Body)
  66.     assert(body.err==nil,body.err)
  67.     return md
  68. end
  69.  
  70. function md.del(key)
  71.     local body=_G.http:JSONDecode(_G.http:RequestAsync{
  72.         Url=url..'/del',
  73.         Method='POST',
  74.         Headers={['Content-Type']='application/json',},
  75.         Body=_G.http:JSONEncode{
  76.             secret=secret(),
  77.             key=key,
  78.         },
  79.     }.Body)
  80.     assert(body.err==nil,body.err)
  81.     return deserialize(body.val)
  82. end
  83.  
  84. function md.upd(key,transform)
  85.     local body=_G.http:JSONDecode(_G.http:RequestAsync{
  86.         Url=url..'/upd0',
  87.         Method='POST',
  88.         Headers={['Content-Type']='application/json',},
  89.         Body=_G.http:JSONEncode{
  90.             secret=secret(),
  91.             key=key,
  92.         },
  93.     }.Body)
  94.     assert(body.err==nil,body.err)
  95.     local id=body.id
  96.     local oldval=deserialize(body.oldval)
  97.     local val=transform(oldval)
  98.     if val==nil then
  99.         return oldval,oldval
  100.     end
  101.     local body=_G.http:JSONDecode(_G.http:RequestAsync{
  102.         Url=url..'/upd1',
  103.         Method='POST',
  104.         Headers={['Content-Type']='application/json',},
  105.         Body=_G.http:JSONEncode{
  106.             secret=secret(),
  107.             id=id,
  108.             key=key,
  109.             val=serialize(val),
  110.         },
  111.     }.Body)
  112.     assert(body.err==nil,body.err)
  113.     return val,oldval
  114. end
  115.  
  116. function md.inc(key,delta)
  117.     return md.upd(key,function(val)
  118.         return(val or 0)+(delta or 1)
  119.     end)
  120. end
  121.  
  122. local weakchanged=setmetatable({},{__mode='v',})--gc when no connections and no other references
  123. local strongchanged={}--store strong reference when signal has connection
  124. function md.changed(key)--it is techinically subscribed until it is gc-ed so we locally we can constantly disconnect and reconnect if we store ref
  125.     assert(not _G.isstudio,'Cannot get an upd changed signal in studio')
  126.     if not weakchanged[key]then
  127.         coroutine.wrap(function()
  128.             _G.http:RequestAsync{
  129.                 Url=url..'/sub',
  130.                 Method='POST',
  131.                 Headers={['Content-Type']='application/json',},
  132.                 Body=_G.http:JSONEncode{
  133.                     secret=secret(),
  134.                     key=key,
  135.                     jobid=jobid,
  136.                 },
  137.             }
  138.         end)()
  139.         weakchanged[key]=_G.signal()
  140.         weakchanged[key].maid(function()
  141.             weakchanged[key]=nil
  142.         end)
  143.         local count=0
  144.         weakchanged[key].changed:bind(function(status)
  145.             count=count+(status=='wait'or status=='bind'and 1 or -1)
  146.             local sig=weakchanged[key]
  147.             strongchanged[key]=count>0 and sig or nil
  148.         end)
  149.         _G.gc(weakchanged[key],function()
  150.             _G.http:RequestAsync{
  151.                 Url=url..'/unsub',
  152.                 Method='POST',
  153.                 Headers={['Content-Type']='application/json',},
  154.                 Body=_G.http:JSONEncode{
  155.                     secret=secret(),
  156.                     key=key,
  157.                     jobid=jobid,
  158.                 },
  159.             }
  160.         end)
  161.     end
  162.     return weakchanged[key]
  163. end
  164.  
  165. coroutine.wrap(function()
  166.     if _G.isstudio then return end
  167.     while true do
  168.         local ok,ret=pcall(_G.http.RequestAsync,_G.http,{
  169.             Url=url..'/poll',
  170.             Method='POST',
  171.             Headers={['Content-Type']='application/json',},
  172.             Body=_G.http:JSONEncode{
  173.                 secret=secret(),
  174.                 jobid=jobid,
  175.             },
  176.         })
  177.         if ok then
  178.             local body=_G.http:JSONDecode(ret.Body)
  179.             --assert(body.err==nil,body.err)
  180.             local key=body.key
  181.             if not body.timeout and weakchanged[key]then
  182.                 weakchanged[key](deserialize(body.val),deserialize(body.oldval))
  183.             end
  184.         else
  185.             --error(ret)
  186.         end
  187.     end
  188. end)()
  189.  
  190. return md
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement