feat: `/online` to list usernames of all online players
authorxangelo <me@xangelo.ca>
Fri, 1 Sep 2023 17:39:41 +0000 (13:39 -0400)
committerxangelo <me@xangelo.ca>
Fri, 1 Sep 2023 17:39:41 +0000 (13:39 -0400)
src/server/api.ts

index 77d54b28c942efb5ae375e78686ae144d9a7e84e..f167ff61bf0ba9cf5a3b1bb154485e11f29ad784 100644 (file)
@@ -89,12 +89,26 @@ async function bootstrapSocket(socket: Socket, player: Player) {
   cache.set(`socket:${player.id}`, socket.id);
   // ref to get the player object
   cache.set(`token:${player.id}`, player);
+  cache.set(`socket-lookup:${socket.id}`, {
+    id: player.id,
+    username: player.username
+  });
 
   socket.emit('authToken', player.id);
 
   socket.emit('chat', renderChatMessage(broadcastMessage('server', `${player.username} just logged in`)));
 }
 
+function uniqueConnectedUsers(): Set<string> {
+  const users = new Set<string>();
+
+  io.sockets.sockets.forEach((socket) => {
+    users.add(cache.get(`socket-lookup:${socket.id}`).username);
+  });
+
+  return users;
+}
+
 io.on('connection', async socket => {
   logger.log(`socket ${socket.id} connected, authToken: ${socket.handshake.headers['x-authtoken']}`);
 
@@ -118,11 +132,13 @@ io.on('connection', async socket => {
 
   socket.on('disconnect', () => {
     console.log(`Player ${player.username} left`);
-    io.emit('status', `${io.sockets.sockets.size} Online (v${version})`);
+    cache.delete(`socket-lookup:${socket.id}`);
+
+    io.emit('status', `${uniqueConnectedUsers().size} Online (v${version})`);
   });
 
 
-  io.emit('status', `${io.sockets.sockets.size} Online (v${version})`);
+  io.emit('status', `${uniqueConnectedUsers().size} Online (v${version})`);
   // this is a special event to let the client know it can start 
   // requesting data
   socket.emit('ready');
@@ -170,6 +186,13 @@ app.post('/chat', authEndpoint, async (req: AuthRequest, res: Response) => {
       }
     }
   }
+  else if(msg === '/online') {
+    const users = Array.from(uniqueConnectedUsers().values());
+    // send to specific user
+    const message = broadcastMessage('server', `Online Players: [${users.join(", ")}]`);
+    io.to(cache.get(`socket:${req.player.id}`)).emit('chat', renderChatMessage(message));
+    res.sendStatus(204);
+  }
   else {
     message = broadcastMessage(req.player.username, xss(msg, {
       whiteList: {}