Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- external datastore
- https://devforum.roblox.com/t/datastore-game-limits/238101/11
- w/ https://pastebin.com/M1pyBGgq
- --]]
- local jobid=game.JobId
- local url='http://127.0.0.1:3000'
- local function secret()
- return'my code'
- end
- local md={}
- local function serialize(v)
- local t=type(v)
- return t=='number'and'n'..v or t=='string'and's'..v or v and'1'or'0'
- end
- local function deserialize(v)
- if not v then return nil end
- local c=v:sub(1,1)
- return c=='n'and v:sub(2)+0 or c=='s'and v:sub(2)or v=='1'
- end
- function md.flush()--wipes entire database
- local body=_G.http:JSONDecode(_G.http:RequestAsync{
- Url=url..'/flush',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- },
- }.Body)
- assert(body.err==nil,body.err)
- return md
- end
- function md.get(key)
- local body=_G.http:JSONDecode(_G.http:RequestAsync{
- Url=url..'/get',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- key=key,
- },
- }.Body)
- assert(body.err==nil,body.err)
- return deserialize(body.val)
- end
- function md.set(key,val)
- local body=_G.http:JSONDecode(_G.http:RequestAsync{
- Url=url..'/set',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- key=key,
- val=serialize(val),
- },
- }.Body)
- assert(body.err==nil,body.err)
- return md
- end
- function md.del(key)
- local body=_G.http:JSONDecode(_G.http:RequestAsync{
- Url=url..'/del',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- key=key,
- },
- }.Body)
- assert(body.err==nil,body.err)
- return deserialize(body.val)
- end
- function md.upd(key,transform)
- local body=_G.http:JSONDecode(_G.http:RequestAsync{
- Url=url..'/upd0',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- key=key,
- },
- }.Body)
- assert(body.err==nil,body.err)
- local id=body.id
- local oldval=deserialize(body.oldval)
- local val=transform(oldval)
- if val==nil then
- return oldval,oldval
- end
- local body=_G.http:JSONDecode(_G.http:RequestAsync{
- Url=url..'/upd1',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- id=id,
- key=key,
- val=serialize(val),
- },
- }.Body)
- assert(body.err==nil,body.err)
- return val,oldval
- end
- function md.inc(key,delta)
- return md.upd(key,function(val)
- return(val or 0)+(delta or 1)
- end)
- end
- local weakchanged=setmetatable({},{__mode='v',})--gc when no connections and no other references
- local strongchanged={}--store strong reference when signal has connection
- 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
- assert(not _G.isstudio,'Cannot get an upd changed signal in studio')
- if not weakchanged[key]then
- coroutine.wrap(function()
- _G.http:RequestAsync{
- Url=url..'/sub',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- key=key,
- jobid=jobid,
- },
- }
- end)()
- weakchanged[key]=_G.signal()
- weakchanged[key].maid(function()
- weakchanged[key]=nil
- end)
- local count=0
- weakchanged[key].changed:bind(function(status)
- count=count+(status=='wait'or status=='bind'and 1 or -1)
- local sig=weakchanged[key]
- strongchanged[key]=count>0 and sig or nil
- end)
- _G.gc(weakchanged[key],function()
- _G.http:RequestAsync{
- Url=url..'/unsub',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- key=key,
- jobid=jobid,
- },
- }
- end)
- end
- return weakchanged[key]
- end
- coroutine.wrap(function()
- if _G.isstudio then return end
- while true do
- local ok,ret=pcall(_G.http.RequestAsync,_G.http,{
- Url=url..'/poll',
- Method='POST',
- Headers={['Content-Type']='application/json',},
- Body=_G.http:JSONEncode{
- secret=secret(),
- jobid=jobid,
- },
- })
- if ok then
- local body=_G.http:JSONDecode(ret.Body)
- --assert(body.err==nil,body.err)
- local key=body.key
- if not body.timeout and weakchanged[key]then
- weakchanged[key](deserialize(body.val),deserialize(body.oldval))
- end
- else
- --error(ret)
- end
- end
- end)()
- return md
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement