Repository navigation
Expand file tree
/
Copy pathserver.js
More file actions
113 lines (96 loc) · 3.49 KB
/
Copy pathserver.js
File metadata and controls
113 lines (96 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const express = require('express');
const http = require('http');
const socketIO = require('socket.io');
const fs = require('fs');
const path = require('path');
const app = express();
const server = http.createServer(app);
const io = socketIO(server);
// Set Content-Security-Policy header to allow resources from self and inline scripts/styles for development
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy', "default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' ws://localhost:3000 ws://127.0.0.1:3000;");
next();
});
// Serve static files from the public folder
app.use(express.static('public'));
// In-memory message history and user tracking
let messageHistory = [];
const users = {};
const rooms = {};
const MESSAGE_FILE = path.join(__dirname, 'messages.json');
const MAX_HISTORY = 100;
// Load message history from file
function loadMessages() {
try {
const data = fs.readFileSync(MESSAGE_FILE, 'utf8');
messageHistory = JSON.parse(data);
} catch (e) {
messageHistory = [];
}
}
// Save message history to file
function saveMessages() {
fs.writeFileSync(MESSAGE_FILE, JSON.stringify(messageHistory.slice(-MAX_HISTORY), null, 2));
}
// Emoji replacement (simple)
function emojify(text) {
const emojiMap = {
':smile:': '😄', ':sad:': '😢', ':heart:': '❤️', ':thumbsup:': '👍', ':fire:': '🔥', ':laugh:': '😂', ':cry:': '😭', ':star:': '⭐', ':100:': '💯', ':clap:': '👏', ':wave:': '👋', ':ok:': '👌', ':wink:': '😉', ':angry:': '😠', ':sunglasses:': '😎', ':party:': '🥳', ':thinking:': '🤔', ':sleep:': '😴', ':poop:': '💩', ':rocket:': '🚀'
};
return text.replace(/:[a-z0-9_]+:/g, m => emojiMap[m] || m);
}
loadMessages();
// WebSocket logic
io.on('connection', (socket) => {
let username = '';
let currentRoom = 'main';
// Join default room
socket.join(currentRoom);
// Send message history
socket.emit('message history', messageHistory.filter(m => m.room === currentRoom));
// Handle username set
socket.on('set username', (name) => {
username = name || 'Anonymous';
users[socket.id] = { username, room: currentRoom };
socket.to(currentRoom).emit('system message', `${username} joined the chat`);
socket.emit('system message', `Welcome, ${username}!`);
});
// Handle room join
socket.on('join room', (room) => {
socket.leave(currentRoom);
socket.to(currentRoom).emit('system message', `${username} left the room`);
currentRoom = room;
socket.join(room);
users[socket.id].room = room;
socket.emit('message history', messageHistory.filter(m => m.room === room));
socket.to(room).emit('system message', `${username} joined the room`);
});
// Typing status
socket.on('typing', (isTyping) => {
socket.to(currentRoom).emit('typing', { username, isTyping });
});
// Chat message
socket.on('chat message', (msg) => {
if (!username) return;
const message = {
username,
text: emojify(msg),
time: new Date().toISOString(),
room: currentRoom
};
messageHistory.push(message);
saveMessages();
io.to(currentRoom).emit('chat message', message);
});
// Disconnect
socket.on('disconnect', () => {
if (username) {
socket.to(currentRoom).emit('system message', `${username} left the chat`);
}
delete users[socket.id];
});
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});