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 parallel.waitForAll(function() while true do local data, is_binary = ws.receive() 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() 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 true do local ev = { os.pullEvent() } if ev[1] == "char" and ev[2] == "q" then break elseif ev[1] == "obcb:hello" then term.setCursorPos(1, 1) print(string.format("Hello: obcb v%d.%d", ev[2], ev[3])) elseif ev[1] == "obcb:clients" then term.setCursorPos(1, 2) 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) ws.close()