diff --git a/docker-production.js b/docker-production.js deleted file mode 100644 index e586998..0000000 --- a/docker-production.js +++ /dev/null @@ -1,20 +0,0 @@ -// Simple production entry point for Docker -// Runs the SvelteKit server only, WebSocket server is run separately -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import { execFileSync } from 'child_process'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); - -// Run the SvelteKit production server -try { - console.log('Starting SvelteKit production server'); - // Execute the built SvelteKit server directly - execFileSync('node', ['build/index.js'], { - stdio: 'inherit', - cwd: __dirname - }); -} catch (error) { - console.error('Error running SvelteKit server:', error); - process.exit(1); -} diff --git a/docker/app.Dockerfile b/docker/app.Dockerfile deleted file mode 100644 index c529a7a..0000000 --- a/docker/app.Dockerfile +++ /dev/null @@ -1,47 +0,0 @@ -# Multi-stage build Dockerfile for Svelte MUD web application - -# Build stage -FROM node:20-alpine AS build - -# Set working directory -WORKDIR /app - -# Copy package files -COPY package*.json ./ - -# Install dependencies -RUN npm install - -# Copy source files -COPY . . - -# Build the application -RUN npm run build - -# Production stage -FROM node:20-alpine AS production - -# Set working directory -WORKDIR /app - -# Create a non-root user and group with the node user ID -RUN addgroup -g 1001 -S nodejs && \ - adduser -S -u 1001 -G nodejs nodejs - -# Install only production dependencies -COPY package*.json ./ -RUN npm install --omit=dev - -# Copy built application from the build stage -COPY --from=build /app/build ./build -COPY --from=build /app/docker-production.js ./ - -# Switch to non-root user -USER nodejs - -# Set environment variables -ENV NODE_ENV=production -ENV PORT=3000 - -# Start the SvelteKit production server -CMD ["node", "docker-production.js"] diff --git a/docker/ws.Dockerfile b/docker/ws.Dockerfile deleted file mode 100644 index 9e8a026..0000000 --- a/docker/ws.Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -# Dockerfile for WebSocket server only - -FROM node:20-alpine - -# Set working directory -WORKDIR /app - -# Copy package files -COPY package*.json ./ - -# Install only production dependencies -RUN npm install --omit=dev - -# Copy only the websocket server code -COPY src/websocket-server.js ./src/ - -# Create a non-root user and group with the node user ID -RUN addgroup -g 1001 -S nodejs && \ - adduser -S -u 1001 -G nodejs nodejs - -# Switch to non-root user -USER nodejs - -# Set environment variables -ENV NODE_ENV=production -ENV WS_PORT=3001 - -# Start the WebSocket server -CMD ["node", "src/websocket-server.js"] diff --git a/integrated-server.js b/integrated-server.js deleted file mode 100644 index e07269d..0000000 --- a/integrated-server.js +++ /dev/null @@ -1,209 +0,0 @@ -import { createServer } from 'http'; -import { WebSocketServer } from 'ws'; -import * as net from 'net'; -import * as tls from 'tls'; -import { parse } from 'url'; -import { handler } from './build/handler.js'; - -// Create an HTTP server -const server = createServer(handler); - -// Create WebSocket server -const wss = new WebSocketServer({ noServer: true }); - -// Active connections and their proxies -const connections = new Map(); - -// Handle WebSocket connections -wss.on('connection', (ws, req, mudHost, mudPort, useSSL) => { - console.log(`WebSocket connection established for ${mudHost}:${mudPort} (SSL: ${useSSL})`); - - // Create a unique ID for this connection - const connectionId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - - // Special handling for test connections - if (mudHost === 'example.com' && mudPort === '23') { - console.log('Test connection detected - using echo server mode'); - - // Send welcome message - ws.send('Hello from WebSocket test server! This is an echo server.'); - - // Echo back messages - ws.on('message', (message) => { - console.log('Test server received:', message.toString()); - ws.send(`Echo: ${message.toString()}`); - }); - - // Handle close - ws.on('close', () => { - console.log('Test connection closed'); - connections.delete(connectionId); - }); - - // Store the connection (without a socket) - connections.set(connectionId, { ws, testMode: true }); - return; - } - - let socket; - try { - // Create a TCP socket connection to the MUD server - // Use tls for SSL connections, net for regular connections - socket = useSSL - ? tls.connect({ host: mudHost, port: parseInt(mudPort), rejectUnauthorized: false }) - : net.createConnection({ host: mudHost, port: parseInt(mudPort) }); - - // Add error handler - socket.on('error', (error) => { - console.error(`Socket error for ${mudHost}:${mudPort}:`, error.message); - // Send error to client - if (ws.readyState === 1) { - ws.send(Buffer.from(`ERROR: Connection to MUD server failed: ${error.message}\r\n`)); - setTimeout(() => { - if (ws.readyState === 1) ws.close(); - }, 1000); - } - // Remove from connections map - connections.delete(connectionId); - }); - - // Store the connection - connections.set(connectionId, { ws, socket }); - } catch (error) { - console.error(`Error creating socket connection: ${error.message}`); - if (ws.readyState === 1) { - ws.send(Buffer.from(`ERROR: Failed to connect to MUD server: ${error.message}\r\n`)); - ws.close(); - } - return; - } - - // Handle data from the MUD server - only in regular mode, not test mode - if (socket) { - socket.on('data', (data) => { - // Check for GMCP data (IAC SB GMCP) - very basic check for debugging - // IAC = 255, SB = 250, GMCP = 201 - let isGmcp = false; - for (let i = 0; i < data.length - 2; i++) { - if (data[i] === 255 && data[i+1] === 250 && data[i+2] === 201) { - isGmcp = true; - console.log('WebSocket server: Detected GMCP data in server response'); - break; - } - } - - // Forward data to the WebSocket client if it's still open - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(data); - console.log(`WebSocket server: Sent ${data.length} bytes to client${isGmcp ? ' (contains GMCP data)' : ''}`); - } - }); - } - - // Handle socket close - if (socket) { - socket.on('close', () => { - console.log(`MUD connection closed for ${mudHost}:${mudPort}`); - // Close WebSocket if it's still open - if (ws.readyState === 1) { - ws.close(); - } - // Remove from connections map - connections.delete(connectionId); - }); - } - - // Handle WebSocket messages (data from client to server) - ws.on('message', (message) => { - try { - // Skip if this is a test connection (already handled in the test mode section) - const conn = connections.get(connectionId); - if (conn.testMode) return; - - // Check for GMCP data (IAC SB GMCP) in client messages - let isGmcp = false; - if (message instanceof Buffer || message instanceof Uint8Array) { - for (let i = 0; i < message.length - 2; i++) { - if (message[i] === 255 && message[i+1] === 250 && message[i+2] === 201) { - isGmcp = true; - console.log('WebSocket server: Detected GMCP data in client message'); - break; - } - } - } - - // Forward data to the MUD server - // The message might be Buffer, ArrayBuffer, or string - if (conn.socket && conn.socket.writable) { - conn.socket.write(message); - console.log(`WebSocket server: Sent ${message.length} bytes to MUD server${isGmcp ? ' (contains GMCP data)' : ''}`); - } else { - console.error('Socket not writable, cannot send data to MUD server'); - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(Buffer.from(`ERROR: Cannot send data to MUD server: Socket not connected\r\n`)); - } - } - } catch (error) { - console.error('Error forwarding message to MUD server:', error); - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(Buffer.from(`ERROR: Failed to send data to MUD server: ${error.message}\r\n`)); - } - } - }); - - // Handle WebSocket close - ws.on('close', () => { - console.log(`WebSocket closed for ${mudHost}:${mudPort}`); - // Close socket if it's still open - const conn = connections.get(connectionId); - if (conn && conn.socket) { - conn.socket.end(); - } - // Remove from connections map - connections.delete(connectionId); - }); - - // Handle WebSocket errors - ws.on('error', (error) => { - console.error(`WebSocket error for ${mudHost}:${mudPort}:`, error.message); - // Close socket on error - const conn = connections.get(connectionId); - if (conn && conn.socket) { - conn.socket.end(); - } - // Remove from connections map - connections.delete(connectionId); - }); -}); - -// Handle HTTP server upgrade (WebSocket handshake) -server.on('upgrade', (request, socket, head) => { - // Parse URL to get query parameters - const { pathname, query } = parse(request.url, true); - - // Only handle WebSocket connections to /mud-ws - if (pathname === '/mud-ws') { - // Extract MUD server details from query parameters - const { host, port, useSSL } = query; - - if (!host || !port) { - socket.write('HTTP/1.1 400 Bad Request\r\n\r\n'); - socket.destroy(); - return; - } - - // Handle WebSocket upgrade - wss.handleUpgrade(request, socket, head, (ws) => { - wss.emit('connection', ws, request, host, port, useSSL === 'true'); - }); - } else { - // For other upgrades (not to /mud-ws), close the connection - socket.destroy(); - } -}); - -// Start the integrated server -const PORT = process.env.PORT || 3000; -server.listen(PORT, () => { - console.log(`Integrated server (HTTP + WebSocket) is running on port ${PORT}`); -}); diff --git a/production.js b/production.js deleted file mode 100644 index dcdaa41..0000000 --- a/production.js +++ /dev/null @@ -1,46 +0,0 @@ -import { spawn } from 'child_process'; -import { dirname } from 'path'; -import { fileURLToPath } from 'url'; -import { svelteKitPort } from './src/proxy-websocket-server.js'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); - -// Start the SvelteKit production server on internal port -console.log(`Starting SvelteKit production server on internal port ${svelteKitPort}`); -const sveltekit = spawn('node', ['build/index.js'], { - stdio: 'inherit', - shell: true, - cwd: __dirname, - env: { ...process.env, PORT: svelteKitPort } -}); - -// Start the Proxy WebSocket server on the main port (3000) -console.log('Starting Proxy WebSocket server on public port 3000'); -const proxyServer = spawn('node', ['src/proxy-websocket-server.js'], { - stdio: 'inherit', - shell: true, - cwd: __dirname -}); - -// Handle process exit -process.on('exit', () => { - console.log('Shutting down servers...'); - proxyServer.kill(); - sveltekit.kill(); -}); - -// Handle ctrl+c -process.on('SIGINT', () => { - console.log('Received SIGINT, shutting down servers...'); - proxyServer.kill('SIGINT'); - sveltekit.kill('SIGINT'); - process.exit(0); -}); - -// Handle termination -process.on('SIGTERM', () => { - console.log('Received SIGTERM, shutting down servers...'); - proxyServer.kill('SIGTERM'); - sveltekit.kill('SIGTERM'); - process.exit(0); -}); \ No newline at end of file diff --git a/server.js b/server.js deleted file mode 100644 index c5ad2e4..0000000 --- a/server.js +++ /dev/null @@ -1,22 +0,0 @@ -import { createServer } from 'http'; -import { handler } from './build/handler.js'; -import express from 'express'; -import { handleWebSocket } from './src/hooks.server.js'; - -// Create Express app -const app = express(); - -// Apply SvelteKit handler -app.use(handler); - -// Create HTTP server -const server = createServer(app); - -// Apply WebSocket handling -handleWebSocket(server); - -// Start server -const PORT = process.env.PORT || 3000; -server.listen(PORT, () => { - console.log(`Server running on port ${PORT}`); -}); diff --git a/src/proxy-websocket-server.js b/src/proxy-websocket-server.js deleted file mode 100644 index 3cfa7a2..0000000 --- a/src/proxy-websocket-server.js +++ /dev/null @@ -1,233 +0,0 @@ -import { WebSocketServer } from 'ws'; -import * as net from 'net'; -import * as tls from 'tls'; -import { createProxyMiddleware } from 'http-proxy-middleware'; -import express from 'express'; -import { parse } from 'url'; -import http from 'http'; - -// Define SvelteKit server port (internal only) -const SVELTEKIT_PORT = 3030; - -// Create Express app for the proxy -const app = express(); - -// Create HTTP server -const server = http.createServer(app); - -// Create WebSocket server -const wss = new WebSocketServer({ noServer: true }); - -// Active connections and their proxies -const connections = new Map(); - -// Proxy all regular HTTP requests to the SvelteKit server -app.use('/', createProxyMiddleware({ - target: `http://localhost:${SVELTEKIT_PORT}`, - changeOrigin: true, - ws: false, // Don't proxy WebSockets here, we'll handle them separately -})); - -// Handle WebSocket connections -wss.on('connection', (ws, req, mudHost, mudPort, useSSL) => { - console.log(`WebSocket connection established for ${mudHost}:${mudPort} (SSL: ${useSSL})`); - - // Create a unique ID for this connection - const connectionId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - - // Special handling for test connections - if (mudHost === 'example.com' && mudPort === '23') { - console.log('Test connection detected - using echo server mode'); - - // Send welcome message - ws.send('Hello from WebSocket test server! This is an echo server.'); - - // Echo back messages - ws.on('message', (message) => { - console.log('Test server received:', message.toString()); - ws.send(`Echo: ${message.toString()}`); - }); - - // Handle close - ws.on('close', () => { - console.log('Test connection closed'); - connections.delete(connectionId); - }); - - // Store the connection (without a socket) - connections.set(connectionId, { ws, testMode: true }); - return; - } - - let socket; - try { - // Create a TCP socket connection to the MUD server - // Use tls for SSL connections, net for regular connections - socket = useSSL - ? tls.connect({ host: mudHost, port: parseInt(mudPort), rejectUnauthorized: false }) - : net.createConnection({ host: mudHost, port: parseInt(mudPort) }); - - // Add error handler - socket.on('error', (error) => { - console.error(`Socket error for ${mudHost}:${mudPort}:`, error.message); - // Send error to client - if (ws.readyState === 1) { - ws.send(Buffer.from(`ERROR: Connection to MUD server failed: ${error.message}\r\n`)); - setTimeout(() => { - if (ws.readyState === 1) ws.close(); - }, 1000); - } - // Remove from connections map - connections.delete(connectionId); - }); - - // Store the connection - connections.set(connectionId, { ws, socket }); - } catch (error) { - console.error(`Error creating socket connection: ${error.message}`); - if (ws.readyState === 1) { - ws.send(Buffer.from(`ERROR: Failed to connect to MUD server: ${error.message}\r\n`)); - ws.close(); - } - return; - } - - // Handle data from the MUD server - only in regular mode, not test mode - if (socket) { - socket.on('data', (data) => { - // Check for GMCP data (IAC SB GMCP) - very basic check for debugging - // IAC = 255, SB = 250, GMCP = 201 - let isGmcp = false; - for (let i = 0; i < data.length - 2; i++) { - if (data[i] === 255 && data[i+1] === 250 && data[i+2] === 201) { - isGmcp = true; - console.log('WebSocket server: Detected GMCP data in server response'); - break; - } - } - - // Forward data to the WebSocket client if it's still open - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(data); - console.log(`WebSocket server: Sent ${data.length} bytes to client${isGmcp ? ' (contains GMCP data)' : ''}`); - } - }); - } - - // Socket error handler already defined above - - // Handle socket close - if (socket) { - socket.on('close', () => { - console.log(`MUD connection closed for ${mudHost}:${mudPort}`); - // Close WebSocket if it's still open - if (ws.readyState === 1) { - ws.close(); - } - // Remove from connections map - connections.delete(connectionId); - }); - } - - // Handle WebSocket messages (data from client to server) - ws.on('message', (message) => { - try { - // Skip if this is a test connection (already handled in the test mode section) - const conn = connections.get(connectionId); - if (conn.testMode) return; - - // Check for GMCP data (IAC SB GMCP) in client messages - let isGmcp = false; - if (message instanceof Buffer || message instanceof Uint8Array) { - for (let i = 0; i < message.length - 2; i++) { - if (message[i] === 255 && message[i+1] === 250 && message[i+2] === 201) { - isGmcp = true; - console.log('WebSocket server: Detected GMCP data in client message'); - break; - } - } - } - - // Forward data to the MUD server - // The message might be Buffer, ArrayBuffer, or string - if (conn.socket && conn.socket.writable) { - conn.socket.write(message); - console.log(`WebSocket server: Sent ${message.length} bytes to MUD server${isGmcp ? ' (contains GMCP data)' : ''}`); - } else { - console.error('Socket not writable, cannot send data to MUD server'); - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(Buffer.from(`ERROR: Cannot send data to MUD server: Socket not connected\r\n`)); - } - } - } catch (error) { - console.error('Error forwarding message to MUD server:', error); - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(Buffer.from(`ERROR: Failed to send data to MUD server: ${error.message}\r\n`)); - } - } - }); - - // Handle WebSocket close - ws.on('close', () => { - console.log(`WebSocket closed for ${mudHost}:${mudPort}`); - // Close socket if it's still open - const conn = connections.get(connectionId); - if (conn && conn.socket) { - conn.socket.end(); - } - // Remove from connections map - connections.delete(connectionId); - }); - - // Handle WebSocket errors - ws.on('error', (error) => { - console.error(`WebSocket error for ${mudHost}:${mudPort}:`, error.message); - // Close socket on error - const conn = connections.get(connectionId); - if (conn && conn.socket) { - conn.socket.end(); - } - // Remove from connections map - connections.delete(connectionId); - }); -}); - -// Handle HTTP server upgrade (WebSocket handshake) -server.on('upgrade', (request, socket, head) => { - // Parse URL to get query parameters - const { pathname, query } = parse(request.url, true); - - // Only handle WebSocket connections to /mud-ws - if (pathname === '/mud-ws') { - // Extract MUD server details from query parameters - const { host, port, useSSL } = query; - - if (!host || !port) { - socket.write('HTTP/1.1 400 Bad Request\r\n\r\n'); - socket.destroy(); - return; - } - - // Handle WebSocket upgrade - wss.handleUpgrade(request, socket, head, (ws) => { - wss.emit('connection', ws, request, host, port, useSSL === 'true'); - }); - } else { - // For other upgrades (not to /mud-ws), close the connection - socket.destroy(); - } -}); - -// Start the server if this file is run directly -if (import.meta.url === `file://${process.argv[1]}`) { - const PORT = process.env.PORT || 3000; - server.listen(PORT, () => { - console.log(`Proxy WebSocket server is running on port ${PORT}, forwarding to SvelteKit on port ${SVELTEKIT_PORT}`); - }); -} - -// Export SVELTEKIT_PORT for use in other files -export const svelteKitPort = SVELTEKIT_PORT; - -// Export the server for use in the main file -export default { server, SVELTEKIT_PORT }; diff --git a/unified-server.js b/unified-server.js deleted file mode 100644 index bd738ba..0000000 --- a/unified-server.js +++ /dev/null @@ -1,219 +0,0 @@ -import { createServer } from 'http'; -import express from 'express'; -import { WebSocketServer } from 'ws'; -import * as net from 'net'; -import * as tls from 'tls'; -import { parse } from 'url'; -import { handler } from './build/handler.js'; - -// Create Express app -const app = express(); - -// Create HTTP server from Express -const server = createServer(app); - -// Create WebSocket server -const wss = new WebSocketServer({ noServer: true }); - -// Active connections and their proxies -const connections = new Map(); - -// Apply SvelteKit handler as middleware -// This needs to be before any other routes -app.use(handler); - -// Handle WebSocket connections -wss.on('connection', (ws, req, mudHost, mudPort, useSSL) => { - console.log(`WebSocket connection established for ${mudHost}:${mudPort} (SSL: ${useSSL})`); - - // Create a unique ID for this connection - const connectionId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - - // Special handling for test connections - if (mudHost === 'example.com' && mudPort === '23') { - console.log('Test connection detected - using echo server mode'); - - // Send welcome message - ws.send('Hello from WebSocket test server! This is an echo server.'); - - // Echo back messages - ws.on('message', (message) => { - console.log('Test server received:', message.toString()); - ws.send(`Echo: ${message.toString()}`); - }); - - // Handle close - ws.on('close', () => { - console.log('Test connection closed'); - connections.delete(connectionId); - }); - - // Store the connection (without a socket) - connections.set(connectionId, { ws, testMode: true }); - return; - } - - let socket; - try { - // Create a TCP socket connection to the MUD server - // Use tls for SSL connections, net for regular connections - socket = useSSL - ? tls.connect({ host: mudHost, port: parseInt(mudPort), rejectUnauthorized: false }) - : net.createConnection({ host: mudHost, port: parseInt(mudPort) }); - - // Add error handler - socket.on('error', (error) => { - console.error(`Socket error for ${mudHost}:${mudPort}:`, error.message); - // Send error to client - if (ws.readyState === 1) { - ws.send(Buffer.from(`ERROR: Connection to MUD server failed: ${error.message}\r\n`)); - setTimeout(() => { - if (ws.readyState === 1) ws.close(); - }, 1000); - } - // Remove from connections map - connections.delete(connectionId); - }); - - // Store the connection - connections.set(connectionId, { ws, socket }); - } catch (error) { - console.error(`Error creating socket connection: ${error.message}`); - if (ws.readyState === 1) { - ws.send(Buffer.from(`ERROR: Failed to connect to MUD server: ${error.message}\r\n`)); - ws.close(); - } - return; - } - - // Handle data from the MUD server - only in regular mode, not test mode - if (socket) { - socket.on('data', (data) => { - // Check for GMCP data (IAC SB GMCP) - very basic check for debugging - // IAC = 255, SB = 250, GMCP = 201 - let isGmcp = false; - for (let i = 0; i < data.length - 2; i++) { - if (data[i] === 255 && data[i+1] === 250 && data[i+2] === 201) { - isGmcp = true; - console.log('WebSocket server: Detected GMCP data in server response'); - break; - } - } - - // Forward data to the WebSocket client if it's still open - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(data); - console.log(`WebSocket server: Sent ${data.length} bytes to client${isGmcp ? ' (contains GMCP data)' : ''}`); - } - }); - } - - // Handle socket close - if (socket) { - socket.on('close', () => { - console.log(`MUD connection closed for ${mudHost}:${mudPort}`); - // Close WebSocket if it's still open - if (ws.readyState === 1) { - ws.close(); - } - // Remove from connections map - connections.delete(connectionId); - }); - } - - // Handle WebSocket messages (data from client to server) - ws.on('message', (message) => { - try { - // Skip if this is a test connection (already handled in the test mode section) - const conn = connections.get(connectionId); - if (conn.testMode) return; - - // Check for GMCP data (IAC SB GMCP) in client messages - let isGmcp = false; - if (message instanceof Buffer || message instanceof Uint8Array) { - for (let i = 0; i < message.length - 2; i++) { - if (message[i] === 255 && message[i+1] === 250 && message[i+2] === 201) { - isGmcp = true; - console.log('WebSocket server: Detected GMCP data in client message'); - break; - } - } - } - - // Forward data to the MUD server - // The message might be Buffer, ArrayBuffer, or string - if (conn.socket && conn.socket.writable) { - conn.socket.write(message); - console.log(`WebSocket server: Sent ${message.length} bytes to MUD server${isGmcp ? ' (contains GMCP data)' : ''}`); - } else { - console.error('Socket not writable, cannot send data to MUD server'); - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(Buffer.from(`ERROR: Cannot send data to MUD server: Socket not connected\r\n`)); - } - } - } catch (error) { - console.error('Error forwarding message to MUD server:', error); - if (ws.readyState === 1) { // WebSocket.OPEN - ws.send(Buffer.from(`ERROR: Failed to send data to MUD server: ${error.message}\r\n`)); - } - } - }); - - // Handle WebSocket close - ws.on('close', () => { - console.log(`WebSocket closed for ${mudHost}:${mudPort}`); - // Close socket if it's still open - const conn = connections.get(connectionId); - if (conn && conn.socket) { - conn.socket.end(); - } - // Remove from connections map - connections.delete(connectionId); - }); - - // Handle WebSocket errors - ws.on('error', (error) => { - console.error(`WebSocket error for ${mudHost}:${mudPort}:`, error.message); - // Close socket on error - const conn = connections.get(connectionId); - if (conn && conn.socket) { - conn.socket.end(); - } - // Remove from connections map - connections.delete(connectionId); - }); -}); - -// Handle HTTP server upgrade (WebSocket handshake) -server.on('upgrade', (request, socket, head) => { - // Parse URL to get query parameters - const { pathname, query } = parse(request.url, true); - - // Only handle WebSocket connections to /mud-ws - if (pathname === '/mud-ws') { - // Extract MUD server details from query parameters - const { host, port, useSSL } = query; - - if (!host || !port) { - socket.write('HTTP/1.1 400 Bad Request\r\n\r\n'); - socket.destroy(); - return; - } - - // Handle WebSocket upgrade - wss.handleUpgrade(request, socket, head, (ws) => { - wss.emit('connection', ws, request, host, port, useSSL === 'true'); - }); - } else { - // For other upgrades (not to /mud-ws), close the connection - socket.destroy(); - } -}); - -// Start the unified server -const PORT = process.env.PORT || 3000; -server.listen(PORT, () => { - console.log(`Unified server (HTTP + WebSocket) is running on port ${PORT}`); -}); - -export default server; \ No newline at end of file