diff --git a/API.md b/API.md index 5af7d1d4..74ad0bee 100644 --- a/API.md +++ b/API.md @@ -12,7 +12,11 @@ Authorization: "Bearer APISOCKETKEY" ``` All requests are made as JSON encoded array. + ### Subscribe to chat messages + +send + ```["sub", "chat"]``` All chat messages, except the once you send with `chat` or `mcchat`, will be sent to you in the form: @@ -21,13 +25,23 @@ All chat messages, except the once you send with `chat` or `mcchat`, will be sen channelId is an integer, channel 0 is `en` channel 1 is `int` and maybe more to come. id is the user id country is the [two-letter country code](https://www.nationsonline.org/oneworld/country_code_list.htm) in lowercase -### Online user counter -Online counter will be sent to you as typical binary package (see `src/socket/packets/OnlineCounter.js`) +### Subscribe to online user counter + +send + +```["sub", "online"]``` + +Online counter will be sent to you all 10s as typical binary package (see `src/socket/packets/OnlineCounter.js`) + ### Subscribe to pixel packages + +send + ```["sub", "pxl"]``` All pixels (including your own) will be sent to you as typical binary packages + ### Set Pixel ```[ "setpxl", minecraftid, ip, x, y, clr ]``` @@ -49,6 +63,7 @@ waitSeconds is the current cooldown. coolDownSeconds is the added cooldown (negative if pixel couldn't be set because max cooldown got reached) ### Send Chat Message + ```["chat", name, message, country, channelId]``` channelId is an integer, channel 0 is `en` channel 1 is `int` and maybe more to come. diff --git a/src/socket/APISocketServer.js b/src/socket/APISocketServer.js index 7539c18d..480a63ce 100644 --- a/src/socket/APISocketServer.js +++ b/src/socket/APISocketServer.js @@ -61,6 +61,7 @@ class APISocketServer { ws.isAlive = true; ws.subChat = false; ws.subPxl = false; + ws.subOnline = false; ws.on('pong', heartbeat); ws.on('message', (data, isBinary) => { @@ -72,11 +73,13 @@ class APISocketServer { }); this.broadcast = this.broadcast.bind(this); + this.broadcastOnlineCounter = this.broadcastOnlineCounter.bind(this); this.broadcastPixelBuffer = this.broadcastPixelBuffer.bind(this); this.ping = this.ping.bind(this); this.broadcastChatMessage = this.broadcastChatMessage.bind(this); socketEvents.on('broadcast', this.broadcast); + socketEvents.on('onlineCounter', this.broadcastOnlineCounter); socketEvents.on('pixelUpdate', this.broadcastPixelBuffer); socketEvents.on('chatMessage', this.broadcastChatMessage); @@ -104,11 +107,13 @@ class APISocketServer { }); } - broadcast(data) { + broadcast(data, filter = null) { if (typeof data === 'string') { this.wss.clients.forEach((ws) => { if (ws.readyState === WebSocket.OPEN) { - ws.send(data); + if (!filter || filter(ws)) { + ws.send(data); + } } }); } else { @@ -121,40 +126,31 @@ class APISocketServer { }); this.wss.clients.forEach((ws) => { if (ws.readyState === WebSocket.OPEN) { - frame.forEach((buffer) => { - try { - // eslint-disable-next-line no-underscore-dangle - ws._socket.write(buffer); - } catch (error) { - logger.error(`WebSocket broadcast error: ${error.message}`); - } - }); + if (!filter || filter(ws)) { + frame.forEach((buffer) => { + try { + // eslint-disable-next-line no-underscore-dangle + ws._socket.write(buffer); + } catch (error) { + logger.error(`WebSocket broadcast error: ${error.message}`); + } + }); + } } }); } } + broadcastOnlineCounter(data) { + this.broadcast(data, (client) => client.subOnline); + } + broadcastPixelBuffer(canvasId, chunkid, buffer) { - if (canvasId !== 0 && canvasId !== '0') return; - const frame = WebSocket.Sender.frame(buffer, { - readOnly: true, - mask: false, - rsv1: false, - opcode: 2, - fin: true, - }); - this.wss.clients.forEach((client) => { - if (client.subPxl && client.readyState === WebSocket.OPEN) { - frame.forEach((data) => { - try { - // eslint-disable-next-line no-underscore-dangle - client._socket.write(data); - } catch (error) { - logger.error('(!) Catched error on write apisocket:', error); - } - }); - } - }); + // just canvas 0 for now + if (canvasId !== 0 && canvasId !== '0') { + return; + } + this.broadcast(buffer, (client) => client.subPxl); } async onTextMessage(message, ws) { @@ -169,9 +165,12 @@ class APISocketServer { const even = packet[0]; if (even === 'chat') { ws.subChat = true; - } - if (even === 'pxl') { + } else if (even === 'pxl') { ws.subPxl = true; + } else if (even === 'online') { + ws.subOnline = true; + } else { + logger.info(`APISocket wanted to sub to unexisting ${command}`); } logger.info(`APISocket client subscribed to ${command}`); return; diff --git a/src/socket/SocketEvents.js b/src/socket/SocketEvents.js index e6fde4af..bde86cd9 100644 --- a/src/socket/SocketEvents.js +++ b/src/socket/SocketEvents.js @@ -154,7 +154,7 @@ class SocketEvents extends EventEmitter { broadcastOnlineCounter(online) { this.onlineCounter = online; const buffer = OnlineCounter.dehydrate(online); - this.emit('broadcast', buffer); + this.emit('onlineCounter', buffer); } } diff --git a/src/socket/SocketServer.js b/src/socket/SocketServer.js index 801509af..c85e3096 100644 --- a/src/socket/SocketServer.js +++ b/src/socket/SocketServer.js @@ -120,6 +120,7 @@ class SocketServer { this.onlineCounterBroadcast = this.onlineCounterBroadcast.bind(this); socketEvents.on('broadcast', this.broadcast); + socketEvents.on('onlineCounter', this.broadcast); socketEvents.on('pixelUpdate', this.broadcastPixelBuffer); socketEvents.on('reloadUser', this.reloadUser);