Add spudnet library
This commit is contained in:
parent
4d2a17e9a7
commit
287c7a0709
151
spudnet/lib/spudnet.lua
Normal file
151
spudnet/lib/spudnet.lua
Normal file
@ -0,0 +1,151 @@
|
||||
local mt = dofile "/lib/multitask.lua"
|
||||
local p = mt.newPool({crash_on_error = true})
|
||||
local spudnet = {}
|
||||
|
||||
spudnet.init = function(o)
|
||||
o = o or {}
|
||||
o.on_init = o.on_init or function() end
|
||||
if not o.channel then
|
||||
error("no channel specified")
|
||||
end
|
||||
if not o.mode then
|
||||
error("no mode specified")
|
||||
end
|
||||
o.subchannels = o.subchannels or {}
|
||||
local url = "wss://spudnet.osmarks.net/v4?enc=json&force_binary=true"
|
||||
local ws = nil
|
||||
local api = {}
|
||||
local since_last_ping = os.epoch"utc"
|
||||
local init
|
||||
for i,v in ipairs(o.subchannels) do
|
||||
o.subchannels[i]=o.mode..":"..o.channel.."/"..v
|
||||
end
|
||||
local get_spudmsg = function(filter)
|
||||
while true do
|
||||
local e, url_, data = coroutine.yield("websocket_message")
|
||||
data = textutils.unserializeJSON(data)
|
||||
if url_ == url then
|
||||
if not filter or filter == data.type then
|
||||
return data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
api.send_raw = function(data)
|
||||
return p.add(function(this)
|
||||
local x = pcall(ws.send,textutils.serializeJSON(data),true)
|
||||
if not x then
|
||||
p.clear()
|
||||
p.add(init,{name="spudnet_init"})
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
api.send_raw_sync = function(data)
|
||||
local id = math.random(1,0xFFFFFF)
|
||||
data.cid = id
|
||||
p.await(api.send_raw(data))
|
||||
while true do
|
||||
local m = get_spudmsg("ok")
|
||||
if m.cid == id then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
api.receive = function(filter)
|
||||
while true do
|
||||
local m = get_spudmsg("message").data
|
||||
if filter then
|
||||
if m.type == filter then
|
||||
return m
|
||||
end
|
||||
else
|
||||
return m
|
||||
end
|
||||
end
|
||||
end
|
||||
api.send = function(data,subchannel)
|
||||
api.send_raw({
|
||||
type="send",
|
||||
data=data,
|
||||
channel=o.mode..":"..o.channel.."/"..subchannel
|
||||
})
|
||||
end
|
||||
|
||||
api.send_sync = function(data,subchannel)
|
||||
api.send_raw_sync({
|
||||
type="send",
|
||||
data=data,
|
||||
channel=o.mode..":"..o.channel.."/"..subchannel
|
||||
})
|
||||
end
|
||||
|
||||
local error_handler = function()
|
||||
while true do
|
||||
local a = get_spudmsg("error")
|
||||
if a.error == "timeout" then
|
||||
p.clear()
|
||||
p.add(init,{name="spudnet_init"})
|
||||
else
|
||||
error("Error from SPUDNET ('"..(a["error"] or a["for"]).."'): "..a.detail)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local ping_handler = function()
|
||||
while true do
|
||||
local a = get_spudmsg("ping").seq
|
||||
since_last_ping = os.epoch"utc"
|
||||
api.send_raw({
|
||||
type="pong",
|
||||
seq = a,
|
||||
})
|
||||
os.queueEvent("spudnet_ping",seq)
|
||||
end
|
||||
end
|
||||
local terminate_handler = function()
|
||||
local x = os.pullEventRaw("terminate")
|
||||
if ws then ws.close() end
|
||||
p.clear()
|
||||
end
|
||||
local timeout_handler = function()
|
||||
while true do
|
||||
sleep(1)
|
||||
if os.epoch"utc" - since_last_ping >= 15000 then
|
||||
p.clear()
|
||||
p.add(init,{name="spudnet_init"})
|
||||
os.queueEvent("spudnet_timeout")
|
||||
end
|
||||
end
|
||||
end
|
||||
init = function()
|
||||
p.add(terminate_handler,{name="spudnet_termination_handler"})
|
||||
if ws then ws.close() end
|
||||
ws = nil
|
||||
while true do
|
||||
ws = http.websocket(url)
|
||||
if ws then
|
||||
break
|
||||
end
|
||||
sleep(0.3)
|
||||
end
|
||||
p.add(error_handler,{name="spudnet_error_handler"})
|
||||
p.add(ping_handler,{name="spudnet_ping_handler"})
|
||||
p.add(timeout_handler,{name="spudnet_timeout_handler"})
|
||||
api.send_raw_sync({
|
||||
type="identify",
|
||||
key=o.key,
|
||||
channels=o.subchannels,
|
||||
})
|
||||
p.add(o.on_init)
|
||||
os.queueEvent("spudnet_ready")
|
||||
end
|
||||
p.add(init,{name="spudnet_init"})
|
||||
return api,p.run
|
||||
end
|
||||
|
||||
spudnet.pool = p
|
||||
|
||||
return spudnet
|
12
spudnet/pkgmeta.ltn
Normal file
12
spudnet/pkgmeta.ltn
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
["version"] = "0.1.0",
|
||||
["dependencies"] = {
|
||||
"multitask",
|
||||
},
|
||||
["description"] = "Basic multitask-based spudnet interaction.",
|
||||
["files"] = {
|
||||
["lib"] = {
|
||||
"spudnet.lua"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user