stuff and junk and things
This commit is contained in:
@@ -1,269 +1,300 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<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;
|
||||
}
|
||||
<head>
|
||||
<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;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
#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-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 {
|
||||
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;
|
||||
}
|
||||
#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 {
|
||||
background-color: #333;
|
||||
border: 2px solid #555;
|
||||
color: #00ff00;
|
||||
padding: 10px 20px;
|
||||
font-family: "Courier New", monospace;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#send:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
#send:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
#status {
|
||||
background-color: #333;
|
||||
padding: 5px 15px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
#status {
|
||||
background-color: #333;
|
||||
padding: 5px 15px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.connected {
|
||||
color: #00ff00;
|
||||
}
|
||||
.connected {
|
||||
color: #00ff00;
|
||||
}
|
||||
|
||||
.disconnected {
|
||||
color: #ff4444;
|
||||
}
|
||||
.disconnected {
|
||||
color: #ff4444;
|
||||
}
|
||||
|
||||
.connecting {
|
||||
color: #ffaa00;
|
||||
}
|
||||
.connecting {
|
||||
color: #ffaa00;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #ff4444;
|
||||
}
|
||||
.error {
|
||||
color: #ff4444;
|
||||
}
|
||||
|
||||
.system {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
.system {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.prompt {
|
||||
color: #00ccff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="status" class="connecting">Connecting...</div>
|
||||
<div id="output"></div>
|
||||
<div id="input-container">
|
||||
<input type="text" id="input" placeholder="Enter command..." disabled>
|
||||
<button id="send" disabled>Send</button>
|
||||
.prompt {
|
||||
color: #00ccff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="status" class="connecting">Connecting...</div>
|
||||
<div id="output"></div>
|
||||
<div id="input-container">
|
||||
<input
|
||||
type="text"
|
||||
id="input"
|
||||
placeholder="Enter command..."
|
||||
disabled
|
||||
/>
|
||||
<button id="send" disabled>Send</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
class MUDClient {
|
||||
constructor() {
|
||||
this.ws = null;
|
||||
this.output = document.getElementById('output');
|
||||
this.input = document.getElementById('input');
|
||||
this.sendButton = document.getElementById('send');
|
||||
this.status = document.getElementById('status');
|
||||
<script>
|
||||
class MUDClient {
|
||||
constructor() {
|
||||
this.ws = null;
|
||||
this.output = document.getElementById("output");
|
||||
this.input = document.getElementById("input");
|
||||
this.sendButton = document.getElementById("send");
|
||||
this.status = document.getElementById("status");
|
||||
|
||||
this.setupEventListeners();
|
||||
this.connect();
|
||||
}
|
||||
|
||||
connect() {
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const wsUrl = `${protocol}//${window.location.host}`;
|
||||
|
||||
this.updateStatus('Connecting...', 'connecting');
|
||||
|
||||
try {
|
||||
this. s = new WebSocket(wsUrl);
|
||||
|
||||
this.ws.onopen = () => {
|
||||
this.updateStatus('Connected', 'connected');
|
||||
this.input.disabled = false;
|
||||
this.sendButton.disabled = false;
|
||||
this.input.focus();
|
||||
};
|
||||
|
||||
this.ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
this.handleMessage(data);
|
||||
};
|
||||
|
||||
this.ws.onclose = () => {
|
||||
this.updateStatus('Disconnected', 'disconnected');
|
||||
this.input.disabled = true;
|
||||
this.sendButton.disabled = true;
|
||||
|
||||
// Attempt to reconnect after 3 seconds
|
||||
setTimeout(() => this.connect(), 3000);
|
||||
};
|
||||
|
||||
this.ws.onerror = (error) => {
|
||||
this.updateStatus('Connection Error', 'error');
|
||||
this.appendOutput('Connection error occurred. Retrying...', 'error');
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
this.updateStatus('Connection Failed', 'error');
|
||||
setTimeout(() => this.connect(), 3000);
|
||||
this.setupEventListeners();
|
||||
this.connect();
|
||||
}
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
this.input.addEventListener('keypress', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
connect() {
|
||||
const protocol =
|
||||
window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const wsUrl = `${protocol}//${window.location.host}`;
|
||||
|
||||
this.updateStatus("Connecting...", "connecting");
|
||||
|
||||
try {
|
||||
this.s = new WebSocket(wsUrl);
|
||||
|
||||
this.ws.onopen = () => {
|
||||
this.updateStatus("Connected", "connected");
|
||||
this.input.disabled = false;
|
||||
this.sendButton.disabled = false;
|
||||
this.input.focus();
|
||||
};
|
||||
|
||||
this.ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
this.handleMessage(data);
|
||||
};
|
||||
|
||||
this.ws.onclose = () => {
|
||||
this.updateStatus("Disconnected", "disconnected");
|
||||
this.input.disabled = true;
|
||||
this.sendButton.disabled = true;
|
||||
|
||||
// Attempt to reconnect after 3 seconds
|
||||
setTimeout(() => this.connect(), 3000);
|
||||
};
|
||||
|
||||
this.ws.onerror = (error) => {
|
||||
this.updateStatus("Connection Error", "error");
|
||||
this.appendOutput(
|
||||
"Connection error occurred. Retrying...",
|
||||
"error",
|
||||
);
|
||||
};
|
||||
} catch (error) {
|
||||
this.updateStatus("Connection Failed", "error");
|
||||
setTimeout(() => this.connect(), 3000);
|
||||
}
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
this.input.addEventListener("keypress", (e) => {
|
||||
if (e.key === "Enter") {
|
||||
this.sendMessage();
|
||||
}
|
||||
});
|
||||
|
||||
this.sendButton.addEventListener("click", () => {
|
||||
this.sendMessage();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.sendButton.addEventListener('click', () => {
|
||||
this.sendMessage();
|
||||
});
|
||||
|
||||
// Command history
|
||||
this.commandHistory = [];
|
||||
this.historyIndex = -1;
|
||||
|
||||
this.input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
if (this.historyIndex < this.commandHistory.length - 1) {
|
||||
this.historyIndex++;
|
||||
this.input.value = this.commandHistory[this.commandHistory.length - 1 - this.historyIndex];
|
||||
}
|
||||
} else if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
if (this.historyIndex > 0) {
|
||||
this.historyIndex--;
|
||||
this.input.value = this.commandHistory[this.commandHistory.length - 1 - this.historyIndex];
|
||||
} else if (this.historyIndex === 0) {
|
||||
this.historyIndex = -1;
|
||||
this.input.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sendMessage() {
|
||||
const message = this.input.value.trim();
|
||||
if (message && this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||
// Add to command history
|
||||
if (this.commandHistory[this.commandHistory.length - 1] !== message) {
|
||||
this.commandHistory.push(message);
|
||||
if (this.commandHistory.length > 50) {
|
||||
this.commandHistory.shift();
|
||||
}
|
||||
}
|
||||
// Command history
|
||||
this.commandHistory = [];
|
||||
this.historyIndex = -1;
|
||||
|
||||
this.ws.send(JSON.stringify({
|
||||
type: 'command',
|
||||
content: message
|
||||
}));
|
||||
this.input.addEventListener("keydown", (e) => {
|
||||
if (e.key === "ArrowUp") {
|
||||
e.preventDefault();
|
||||
if (
|
||||
this.historyIndex <
|
||||
this.commandHistory.length - 1
|
||||
) {
|
||||
this.historyIndex++;
|
||||
this.input.value =
|
||||
this.commandHistory[
|
||||
this.commandHistory.length -
|
||||
1 -
|
||||
this.historyIndex
|
||||
];
|
||||
}
|
||||
} else if (e.key === "ArrowDown") {
|
||||
e.preventDefault();
|
||||
if (this.historyIndex > 0) {
|
||||
this.historyIndex--;
|
||||
this.input.value =
|
||||
this.commandHistory[
|
||||
this.commandHistory.length -
|
||||
1 -
|
||||
this.historyIndex
|
||||
];
|
||||
} else if (this.historyIndex === 0) {
|
||||
this.historyIndex = -1;
|
||||
this.input.value = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.input.value = '';
|
||||
sendMessage() {
|
||||
const message = this.input.value.trim();
|
||||
if (
|
||||
message &&
|
||||
this.ws &&
|
||||
this.ws.readyState === WebSocket.OPEN
|
||||
) {
|
||||
// Add to command history
|
||||
if (
|
||||
this.commandHistory[
|
||||
this.commandHistory.length - 1
|
||||
] !== message
|
||||
) {
|
||||
this.commandHistory.push(message);
|
||||
if (this.commandHistory.length > 50) {
|
||||
this.commandHistory.shift();
|
||||
}
|
||||
}
|
||||
this.historyIndex = -1;
|
||||
|
||||
this.ws.send(
|
||||
JSON.stringify({
|
||||
type: "command",
|
||||
content: message,
|
||||
}),
|
||||
);
|
||||
|
||||
this.input.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
handleMessage(data) {
|
||||
switch (data.type) {
|
||||
case "message":
|
||||
this.appendOutput(data.content);
|
||||
break;
|
||||
case "error":
|
||||
this.appendOutput(data.content, "error");
|
||||
break;
|
||||
case "system":
|
||||
this.appendOutput(data.content, "system");
|
||||
break;
|
||||
default:
|
||||
this.appendOutput(data.content);
|
||||
}
|
||||
}
|
||||
|
||||
appendOutput(text, className = "") {
|
||||
const div = document.createElement("div");
|
||||
if (className) {
|
||||
div.className = className;
|
||||
}
|
||||
|
||||
// Check if this looks like a prompt
|
||||
if (text.includes("] > ")) {
|
||||
div.className = "prompt";
|
||||
}
|
||||
|
||||
div.textContent = text;
|
||||
this.output.appendChild(div);
|
||||
this.output.scrollTop = this.output.scrollHeight;
|
||||
}
|
||||
|
||||
updateStatus(message, className) {
|
||||
this.status.textContent = `Status: ${message}`;
|
||||
this.status.className = className;
|
||||
}
|
||||
}
|
||||
|
||||
handleMessage(data) {
|
||||
switch (data.type) {
|
||||
case 'message':
|
||||
this.appendOutput(data.content);
|
||||
break;
|
||||
case 'error':
|
||||
this.appendOutput(data.content, 'error');
|
||||
break;
|
||||
case 'system':
|
||||
this.appendOutput(data.content, 'system');
|
||||
break;
|
||||
default:
|
||||
this.appendOutput(data.content);
|
||||
}
|
||||
}
|
||||
|
||||
appendOutput(text, className = '') {
|
||||
const div = document.createElement('div');
|
||||
if (className) {
|
||||
div.className = className;
|
||||
}
|
||||
|
||||
// Check if this looks like a prompt
|
||||
if (text.includes('] > ')) {
|
||||
div.className = 'prompt';
|
||||
}
|
||||
|
||||
div.textContent = text;
|
||||
this.output.appendChild(div);
|
||||
this.output.scrollTop = this.output.scrollHeight;
|
||||
}
|
||||
|
||||
updateStatus(message, className) {
|
||||
this.status.textContent = `Status: ${message}`;
|
||||
this.status.className = className;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the MUD client when the page loads
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new MUDClient();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
// Initialize the MUD client when the page loads
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
new MUDClient();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user