This commit is contained in:
Kim Ravn Hansen
2025-09-05 18:42:22 +02:00
parent 1720db9eb7
commit fb915f2681
4 changed files with 116 additions and 198 deletions

View File

@@ -1,3 +1,4 @@
{
"tabWidth": 4
"tabWidth": 4,
"printWidth": 170
}

View File

@@ -4,103 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebSocket MUD</title>
<style>
body {
font-family: "Courier New", monospace;
background-color: #1a1a1a;
color: #00ff00;
margin: 0;
padding: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
#container {
display: flex;
flex-direction: column;
height: 100vh;
max-width: 1200px;
margin: 0 auto;
padding: 10px;
}
#output {
flex: 1;
background-color: #000;
border: 2px solid #333;
padding: 15px;
overflow-y: auto;
white-space: pre-wrap;
font-size: 14px;
line-height: 1.4;
margin-bottom: 10px;
}
#input-container {
display: flex;
gap: 10px;
}
#input {
flex: 1;
background-color: #222;
border: 2px solid #333;
color: #00ff00;
padding: 10px;
font-family: "Courier New", monospace;
font-size: 14px;
}
#input:focus {
outline: none;
border-color: #00ff00;
}
#send {
background-color: #333;
border: 2px solid #555;
color: #00ff00;
padding: 10px 20px;
font-family: "Courier New", monospace;
cursor: pointer;
}
#send:hover {
background-color: #444;
}
#status {
background-color: #333;
padding: 5px 15px;
margin-bottom: 10px;
border-radius: 3px;
}
.connected {
color: #00ff00;
}
.disconnected {
color: #ff4444;
}
.connecting {
color: #ffaa00;
}
.error {
color: #ff4444;
}
.system {
color: #aaaaaa;
}
.prompt {
color: #00ccff;
}
</style>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="container">
@@ -138,7 +42,7 @@
this.updateStatus("Connecting...", "connecting");
try {
this.s = new WebSocket(wsUrl);
this.ws = new WebSocket(wsUrl);
this.ws.onopen = () => {
this.updateStatus("Connected", "connected");
@@ -148,6 +52,7 @@
};
this.ws.onmessage = (event) => {
console.log(event);
const data = JSON.parse(event.data);
this.handleMessage(data);
};
@@ -169,6 +74,7 @@
);
};
} catch (error) {
console.error(error);
this.updateStatus("Connection Failed", "error");
setTimeout(() => this.connect(), 3000);
}
@@ -254,18 +160,16 @@
}
handleMessage(data) {
switch (data.type) {
case "message":
this.appendOutput(data.content);
break;
console.log(data);
switch (data[0]) {
case "error":
this.appendOutput(data.content, "error");
this.appendOutput(data[1], "error");
break;
case "system":
this.appendOutput(data.content, "system");
this.appendOutput(data[1], "system");
break;
default:
this.appendOutput(data.content);
this.appendOutput(data[1]);
}
}

95
server/public/style.css Normal file
View File

@@ -0,0 +1,95 @@
body {
font-family: "Courier New", monospace;
background-color: #1a1a1a;
color: #00ff00;
margin: 0;
padding: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
#container {
display: flex;
flex-direction: column;
height: 100vh;
max-width: 1200px;
margin: 0 auto;
padding: 10px;
}
#output {
flex: 1;
background-color: #000;
border: 2px solid #333;
padding: 15px;
overflow-y: auto;
white-space: pre-wrap;
font-size: 14px;
line-height: 1.4;
margin-bottom: 10px;
}
#input-container {
display: flex;
gap: 10px;
}
#input {
flex: 1;
background-color: #222;
border: 2px solid #333;
color: #00ff00;
padding: 10px;
font-family: "Courier New", monospace;
font-size: 14px;
}
#input:focus {
outline: none;
border-color: #00ff00;
}
#send {
background-color: #333;
border: 2px solid #555;
color: #00ff00;
padding: 10px 20px;
font-family: "Courier New", monospace;
cursor: pointer;
}
#send:hover {
background-color: #444;
}
#status {
background-color: #333;
padding: 5px 15px;
margin-bottom: 10px;
border-radius: 3px;
}
.connected {
color: #00ff00;
}
.disconnected {
color: #ff4444;
}
.connecting {
color: #ffaa00;
}
.error {
color: #ff4444;
}
.system {
color: #aaaaaa;
}
.prompt {
color: #00ccff;
}

View File

@@ -104,14 +104,8 @@ class MudServer {
// We haven"t gotten a username yet, so we expect one.
//----------------------------------------------------
if (!message.hasUsername()) {
console.error(
"User should have sent a username” message, but sent something else instead",
);
this.send(
websocket,
MSG_CALAMITY,
"I expected you to send me a username, but you sent me something else instead. You bad! Goodbye...",
);
console.error("User should have sent a “username” message, but sent something else instead");
this.send(websocket, MSG_CALAMITY, "I expected you to send me a username, but you sent me something else instead. You bad! Goodbye...");
// for now, just close the socket.
websocket.close();
@@ -120,7 +114,9 @@ class MudServer {
const player = this.game.players.get(message.username);
if (!player) {
// player not found - for now, just close the connection - make a better
//----------------------------------------------------
// Invalid Username.
//----------------------------------------------------
console.log("Invalid username sent during login: %s", username);
this.send(websocket, MSG_ERROR, "Invalid username");
this.send(
@@ -186,86 +182,6 @@ class MudServer {
this.showRoom(player);
}
/**
*
* @param {Player} player
* @param {string} input
*/
processCommand(player, input) {
const args = input.toLowerCase().split(" ");
const command = args[0];
switch (command) {
case "look":
case "l":
this.showRoom(player);
break;
case "go":
case "move":
if (args[1]) {
this.movePlayer(player, args[1]);
} else {
player.sendMessage("Go where?");
}
break;
case "north":
case "n":
this.movePlayer(player, "north");
break;
case "south":
case "s":
this.movePlayer(player, "south");
break;
case "east":
case "e":
this.movePlayer(player, "east");
break;
case "west":
case "w":
this.movePlayer(player, "west");
break;
case "say":
if (args.length > 1) {
const message = args.slice(1).join(" ");
this.sayToRoom(player, message);
} else {
player.sendMessage("Say what?");
}
break;
case "who":
this.showOnlinePlayers(player);
break;
case "inventory":
case "inv":
this.showInventory(player);
break;
case "help":
this.showHelp(player);
break;
case "quit":
player.sendMessage("Goodbye!");
player.websocket.close();
break;
default:
player.sendMessage(
`Unknown command: ${command}. Type "help" for available commands.`,
);
}
player.sendPrompt();
}
/**
* Called when a websocket connection is closing.
*
@@ -289,7 +205,7 @@ class MudServer {
}
// Create HTTP server for serving the client
const server = http.createServer((req, res) => {
const httpServer = http.createServer((req, res) => {
// let filePath = path.join(__dirname, "public", req.url === "/" ? "index.html" : req.url);
let filePath = path.join(
"public",
@@ -324,15 +240,17 @@ const server = http.createServer((req, res) => {
});
// Create WebSocket server
const websocketServer = new WebSocketServer({ server });
const websocketServer = new WebSocketServer({ server: httpServer });
const mudServer = new MudServer();
websocketServer.on("connection", (ws) => {
mudServer.onConnectionEstabished(ws);
});
// websocketServer.on("connection", mudServer.onConnectionEstabished);
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
httpServer.listen(PORT, () => {
console.log(`MUD server running on port ${PORT}`);
console.log(`WebSocket server ready for connections`);
});