fix: migrate chat to separate route file
authorxangelo <me@xangelo.ca>
Sat, 21 Oct 2023 03:11:23 +0000 (23:11 -0400)
committerxangelo <me@xangelo.ca>
Sat, 21 Oct 2023 03:11:23 +0000 (23:11 -0400)
src/server/api.ts
src/server/routes/chat.ts [new file with mode: 0644]

index c476f770041a2c927a4bfd8910077dd367a71657..033eb764a83def5e4709b8877a51d4baf2816085 100644 (file)
@@ -4,7 +4,6 @@ import { config as dotenv } from 'dotenv';
 import { join } from 'path';
 import express, {Request, Response} from 'express';
 import bodyParser from 'body-parser';
-import xss from 'xss';
 import { rateLimit } from 'express-rate-limit';
 
 import http from 'http';
@@ -13,7 +12,7 @@ import * as CONSTANT from '../shared/constants';
 import { logger } from './lib/logger';
 import { loadPlayer, createPlayer, updatePlayer, movePlayer } from './player';
 import { random, sample } from 'lodash';
-import {broadcastMessage, Message} from '../shared/message';
+import {broadcastMessage} from '../shared/message';
 import {maxHp, maxVigor, Player} from '../shared/player';
 import {createFight, getMonsterList, getMonsterLocation, getRandomMonster, loadMonster, loadMonsterFromFight, loadMonsterWithFaction} from './monster';
 import {addInventoryItem, getEquippedItems, getInventory, getInventoryItem} from './inventory';
@@ -25,7 +24,6 @@ import { clearTravelPlan, completeTravel, getAllPaths, getAllServices, getCityDe
 import { signup, login, authEndpoint } from './auth';
 import {db} from './lib/db';
 import { getPlayerSkills} from './skills';
-import { handleChatCommands } from './chat-commands';
 
 import { fightRound, blockPlayerInFight } from './fight';
 
@@ -33,6 +31,7 @@ import { router as healerRouter } from './locations/healer';
 import { router as professionRouter } from './locations/recruiter';
 import { router as repairRouter } from './locations/repair';
 import { router as dungeonRouter } from './locations/dungeon';
+import { chatRouter } from './routes/chat';
 
 import * as Alert from './views/alert';
 import { ExplorePane } from './views/components/explore-pane';
@@ -70,13 +69,23 @@ app.use(express.json());
 const io = new Server(server);
 
 const cache = new Map<string, any>();
-const chatHistory: Message[] = [];
 
 app.use((req, res, next) => {
   console.log(req.method, req.url);
   next();
 });
 
+// middle ware to ensure that the rl object 
+// (which contains the cache) is present
+app.use((req, res, next) => {
+  req.rl = {
+    cache,
+    io
+  };
+
+  next();
+});
+
 const fightRateLimiter = rateLimit({
   windowMs: parseInt(process.env.RATE_LIMIT_WINDOW || '30000'),
   max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS || '20'),
@@ -155,49 +164,7 @@ app.use(healerRouter);
 app.use(professionRouter);
 app.use(repairRouter);
 app.use(dungeonRouter);
-
-
-app.get('/chat/history', authEndpoint, async (req: Request, res: Response) => {
-  let html = chatHistory.map(renderChatMessage);
-
-  res.send(html.join("\n"));
-});
-
-app.post('/chat', authEndpoint, async (req: Request, res: Response) => {
-  const msg = req.body.message.trim();
-
-  if(!msg || !msg.length) {
-    res.sendStatus(204);
-    return;
-  }
-
-  if(msg.startsWith('/server') && req.player.permissions.includes('admin')) {
-    const sender = io.sockets.sockets.get(cache.get(`socket:${req.player.id}`));
-    try {
-      await handleChatCommands(msg, req.player, io, sender);
-    }
-    catch(e) {
-      sender.emit('chat', renderChatMessage(broadcastMessage('server', e.message)));
-    }
-  }
-  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 {
-    const message = broadcastMessage(req.player.username, xss(msg, {
-      whiteList: {}
-    }));
-    chatHistory.push(message);
-    chatHistory.slice(-10);
-    io.emit('chat', renderChatMessage(message));
-  }
-
-  res.sendStatus(204);
-});
+app.use(chatRouter);
 
 app.get('/player', authEndpoint, async (req: Request, res: Response) => {
   const equipment = await getEquippedItems(req.player.id);
diff --git a/src/server/routes/chat.ts b/src/server/routes/chat.ts
new file mode 100644 (file)
index 0000000..cc41b80
--- /dev/null
@@ -0,0 +1,58 @@
+import { Request, Response, Router } from 'express';
+import { broadcastMessage, Message } from '../../shared/message';
+import { authEndpoint } from '../auth';
+import { renderChatMessage } from '../views/chat';
+import { handleChatCommands } from '../chat-commands';
+import xss from 'xss';
+
+export const chatRouter = Router();
+
+const chatHistory: Message[] = [];
+
+chatRouter.get('/chat/history', authEndpoint, (req: Request, res: Response) => {
+  let html = chatHistory.map(renderChatMessage);
+
+  res.send(html.join("\n"));
+});
+
+chatRouter.post('/chat', authEndpoint, async (req: Request, res: Response) => {
+  const msg = req.body.message.trim();
+
+  if(!msg || !msg.length) {
+    res.sendStatus(204);
+    return;
+  }
+
+  if(msg.startsWith('/server') && req.player.permissions.includes('admin')) {
+    const sender = req.rl.io.sockets.sockets.get(req.rl.cache.get(`socket:${req.player.id}`));
+    try {
+      await handleChatCommands(msg, req.player, req.rl.io, sender);
+    }
+    catch(e) {
+      sender.emit('chat', renderChatMessage(broadcastMessage('server', e.message)));
+    }
+  }
+  else if(msg === '/online') {
+    const uniqueConnectedUsers = new Set<string>();
+
+    req.rl.io.sockets.sockets.forEach((socket) => {
+      uniqueConnectedUsers.add(req.rl.cache.get(`socket-lookup:${socket.id}`).username);
+    });
+
+    const users = Array.from(uniqueConnectedUsers.values());
+    // send to specific user
+    const message = broadcastMessage('server', `Online Players: [${users.join(", ")}]`);
+    req.rl.io.to(req.rl.cache.get(`socket:${req.player.id}`)).emit('chat', renderChatMessage(message));
+    res.sendStatus(204);
+  }
+  else {
+    const message = broadcastMessage(req.player.username, xss(msg, {
+      whiteList: {}
+    }));
+    chatHistory.push(message);
+    chatHistory.slice(-10);
+    req.rl.io.emit('chat', renderChatMessage(message));
+  }
+
+  res.sendStatus(204);
+});