cc-stuff/obcb-cc.lua

109 lines
3.6 KiB
Lua

local ws = assert(http.websocket("wss://bitmap-ws.alula.me/"))
function parse_u16(data)
local v = table.remove(data, 1)
v = bit.bor(v, bit.blshift(table.remove(data, 1), 8))
return v, data
end
function parse_u32(data)
local v = table.remove(data, 1)
v = bit.bor(v, bit.blshift(table.remove(data, 1), 8))
v = bit.bor(v, bit.blshift(table.remove(data, 1), 16))
v = bit.bor(v, bit.blshift(table.remove(data, 1), 24))
return v, data
end
local chunk_id = 421
local chunk_state = { 0x48, 0x65, 0x6c, 0x6c, 0x6f }
local function send_chunk_request(chunk)
ws.send(string.char(0x10, bit.band(chunk, 0xFF), bit.band(bit.brshift(chunk, 8), 0xFF)), true)
end
local function send_chunk_subscribe_request(chunk)
ws.send(string.char(0x14, bit.band(chunk, 0xFF), bit.band(bit.brshift(chunk, 8), 0xFF)), true)
end
local shutdown = false
parallel.waitForAll(function()
while not shutdown do
local data, is_binary = ws.receive()
if data == nil then return end
data = { string.byte(data, 1, #data) }
local opcode = table.remove(data, 1)
if opcode == 0x00 then -- hello
ver_major, data = parse_u16(data)
ver_minor, data = parse_u16(data)
os.queueEvent("obcb:hello", ver_major, ver_minor)
elseif opcode == 0x01 then
local clients = parse_u32(data)
-- TODO: show them somewhere
os.queueEvent("obcb:clients", clients)
elseif opcode == 0x11 then
chunk_index, data = parse_u16(data)
if chunk_index == chunk_id then
chunk_state = data
end
os.queueEvent("obcb:update")
elseif opcode == 0x12 then
offset, chunk = parse_u32(data)
local c_id = math.floor(offset / 32768)
local b_off = offset % 32768
for i = 1, 32 do
chunk_state[i + b_off] = chunk[i]
end
os.queueEvent("obcb:update")
else
print(table.unpack(data))
end
end
end,
function()
local mon = peripheral.wrap("monitor_0")
mon.setTextScale(0.5)
mon.clear()
local tw, th = term.getSize()
term.clear()
send_chunk_request(chunk_id)
send_chunk_subscribe_request(chunk_id)
term.setCursorPos(1, 3)
print("Showing chunk " .. chunk_id)
print(string.format("Screen: %dx%d", mon.getSize()))
while not shutdown do
local ev = { os.pullEvent() }
if ev[1] == "char" and ev[2] == "q" then
shutdown = true
ws.close()
break
elseif ev[1] == "obcb:hello" then
term.setCursorPos(1, 1)
term.clearLine()
print(string.format("Hello: obcb v%d.%d", ev[2], ev[3]))
elseif ev[1] == "obcb:clients" then
term.setCursorPos(1, 2)
term.clearLine()
print("Clients: " .. ev[2])
elseif ev[1] == "obcb:update" then
for y = 1, 81 do
mon.setCursorPos(1, y)
local tx = {}
local bg = {}
local fg = {}
for x = 1, 164 do
local i = (y - 1) * 164 + (x - 1)
tx[x] = chunk_state[i * 2 + 1]
fg[x] = string.format("%x", bit.band(chunk_state[i * 2 + 2], 0xF))
bg[x] = string.format("%x", bit.band(bit.brshift(chunk_state[i * 2 + 2], 4), 0xF))
end
mon.blit(string.char(table.unpack(tx)), table.concat(bg), table.concat(fg))
end
end
end
end)
shutdown = true
ws.close()