By Guest

Unnamed Paste

Auto Detect 7.21 KiB 6 5 days ago
This site has been acquired by Toptal (Attention! API endpoint has changed) Save New Duplicate & Edit Just Text1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 local imgquant = require 'imgquant' local bson = require 'bson' local config = require 'mineboy_config' local monitor = peripheral.wrap(config.screenMonitor) monitor.setTextScale(0.5) local controlMonitor = peripheral.wrap(config.controlMonitor.monitorId) -- Pretty color logging local log = { rawLog = function(color, text, message) term.setTextColor(color) write('[' .. text .. '] ') term.setTextColor(colors.gray) write(message .. '\n') end } log.info = function(message) log.rawLog(colors.blue, "INFO", message) end log.error = function(message) log.rawLog(colors.red, "ERROR", message) end log.warn = function(message) log.rawLog(colors.yellow, "WARN", message) end log.query = function(message) log.rawLog(colors.green, "QUERY", message) term.setTextColor(colors.gray) write('> ') term.setTextColor(colors.white) return read() end -- Length of a table regardless of what the indexes are function tableLen(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end log.info('Getting games list from server') local gameList = bson.decode(http.get(config.httpUrl .. '/listGames').readAll()) log.info('Retrieved ' .. tableLen(gameList) .. ' games: ' .. textutils.serialize(gameList)) local ws, err = http.websocket(config.wsUrl .. '/attach') if err then log.error('Unable to open websocket: ' .. err) return else log.info('Connected to socket: ' .. config.wsUrl) end -- Controller button map local buttons = { { x = 2, y = 5, height = 2, width = 3, button = 'LEFT' }, { x = 10, y = 5, height = 2, width = 3, button = 'RIGHT' }, { x = 6, y = 2, height = 2, width = 3, button = 'UP' }, { x = 6, y = 8, height = 2, width = 3, button = 'DOWN' }, { x = 35, y = 4, height = 2, width = 3, button = 'A' }, { x = 30, y = 6, height = 2, width = 3, button = 'B' }, { x = 15, y = 10, height = 1, width = 5, button = 'SELECT' }, { x = 22, y = 10, height = 1, width = 5, button = 'START' } } function buttons:render() term.redirect(controlMonitor) term.setBackgroundColor(colors[config.controlMonitor.backgroundColor]) term.clear() for _, button in ipairs(self) do paintutils.drawFilledBox( button.x, button.y, button.x + button.width, button.y + button.height, colors[config.controlMonitor.foregroundColor]) end term.redirect(term.native()) end function buttons:updateButtons(x, y) for _, button in ipairs(self) do if button.x <= x and x <= button.x + button.width and button.y <= y and y <= button.y + button.height then ws.send(bson.encode({ type = 'PRESS_BUTTON', button = button.button })) end end end --- Render the received frame to the screen -- @param width of the image -- @param height of the image -- @param color palette used to render the image (length of 16) -- @param screen to render, array of 4-bit values (0-16) local function blitFrame(width, height, palette, screen) -- Extract image data local pos = 1 local img = {} for y = 1, height do img[y] = {} for x = 1, width, 2 do local c = screen:byte(pos) pos = pos + 1 img[y][x] = bit32.rshift(c, 4) + 1 img[y][x + 1] = bit32.band(c, 15) + 1 end end local ccImage = imgquant.toCCImage(img, palette) imgquant.drawBlitImage(1, 1, ccImage, palette, monitor) end --- Select a game and send a query to play the game local function selectGame() local index while true do index = tonumber(log.query('Select a game to play (0-' .. tableLen(gameList) - 1 .. ')')) if index then break else log.error('Input must be a number') end end ws.send(bson.encode({ type = 'SELECT_GAME', index = index })) local res = bson.decode(ws.receive()) log.info('Started game: ' .. res.name) end local function gameLoop() while true do -- Request draw from server ws.send(bson.encode({ type = 'REQUEST_DRAW' })) -- Wait for frame while true do local event = { os.pullEvent() } if event[1] == 'websocket_message' then local message = bson.decode(event[3]) if message.type == 'ERROR' then -- Message we recieved was an error of some sort, log it log.error(response.error) elseif message.type == 'SCREEN_DRAW' then blitFrame(message.width, message.height, message.palette, message.screen) -- Break out of the listener loop so we can request another frame break end elseif event[1] == 'monitor_touch' then buttons:updateButtons(event[3], event[4]) elseif event[1] == 'key' then local character = event[2] print(character) -- Exit game session if character == keys.x then ws.send(bson.encode({ type = 'EXIT_GAME' })) while true do local res = bson.decode(ws.receive()) if res.type == 'GAME_EXITED' then break end end log.info('Game session was terminated') end end end end end selectGame() buttons:render() gameLoop()