-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
137 lines (120 loc) · 5.08 KB
/
server.js
File metadata and controls
137 lines (120 loc) · 5.08 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import express from 'express';
import ws from 'ws';
import bp from 'body-parser';
import fs from 'fs';
// Global consts
const HOST = '0.0.0.0';
const PORT = 8000;
// Generate lists of random block names
function genRandomBlockRing() {
const possibleBlocks = 'IJLOSTZ';
let blockRing = '';
while( blockRing.length < 10000 ){
let rndChar = possibleBlocks[Math.floor(Math.random()*possibleBlocks.length)];
if (blockRing[blockRing.length-1] != rndChar) {
blockRing = blockRing + rndChar;
}
}
return blockRing;
}
// Active Battle info
var battles = {}
// Setup web server to serve static resources
var app = express();
app.use(express.static('www'));
app.get('/', (req, res) => {
res.redirect('/start.html');
});
// Allow BattleIDs to be created and queried
app.use(bp.json());
app.post('/battle', (req, res) => {
// Handle the case where this is actually a request for access to the secret file server
if ( req.body.battleId == 'letmein!') {
let realIP = req.headers['x-real-ip'];
let allowLine = `allow ${realIP}; # ${req.body.username}`
fs.writeFileSync('/signal/new-allow', allowLine);
res.json( {'error': 'So someone told you the secret... Your IP is being whitelisted :). Allow up to 1 minute for the change to take affect.'} );
return;
}
// Do normal processing
if( req.body.battleId in battles ){
res.json( {'error': 'That BattleID already exists. Please try choosing a different BattleID for your new game, or attempt to join the existing game.'} );
return;
}
let battleData = {
players: {}
}
battleData.players[ req.body.username ] = null;
battles[ req.body.battleId ] = battleData;
res.json(req.body);
}) ;
app.get('/battle', (req, res) => {
let battleId = req.query.battleId;
if(battleId in battles) {
let players = Object.keys( battles[battleId] );
res.json( players );
}else{
res.json( {'error': 'No game with that BattleID exists.' } );
}
});
// Setup WebSocket server
const wsServer = new ws.Server({noServer: true});
wsServer.on('connection', socket => {
socket.on('message', messageString => {
// Parse message
let messageObj = JSON.parse(messageString);
// Process registations
if (messageObj.type == 'register') {
console.log(`Got registration message from ${messageObj.name} for battle ${messageObj.battleId}`);
if ( !(messageObj.battleId in battles) ){
console.log('No battle with that ID exists. Aborting processing for this message.');
return;
}
if (Object.keys(battles[messageObj.battleId].players).length == 2) {
console.log('This battle is already full. Not allowing registration.');
return;
}
battles[messageObj.battleId].players[messageObj.name] = socket;
// If this game is now full, send start message to participants
if (Object.keys(battles[messageObj.battleId].players).length == 2) {
console.log('Sending start message to players:', Object.keys(battles[messageObj.battleId].players));
let startMessage = JSON.stringify({
type: 'start',
players: Object.keys(battles[messageObj.battleId].players),
blockRing: genRandomBlockRing()
});
Object.keys(battles[messageObj.battleId].players).forEach(playerName => {
let playerSocket = battles[messageObj.battleId].players[playerName];
playerSocket.send(startMessage);
});
}
}
// At this point, any message should include a known battleId. Abort execution of this function if not.
if( !('battleId' in messageObj) || !(messageObj.battleId in battles) ){
console.log('The following message does not contain a valid battleId', messageObj);
return;
}
// Whatever the message, send it on to everyone in the battle
Object.keys(battles[messageObj.battleId].players).forEach(playerName => {
let playerSocket = battles[messageObj.battleId].players[playerName];
playerSocket.send(messageString);
});
// If this is a Game Over message, delete this battleId so it can be reused
if (messageObj.type == 'gameOver') {
for(let playerName in battles[messageObj.battleId].players) {
battles[messageObj.battleId].players[playerName].terminate();
}
delete battles[messageObj.battleId];
console.log('Game with battleId', messageObj.battleId, 'ended.', messageObj.player, 'lost.' );
}
})
})
// Launch web server
var server = app.listen(PORT, HOST);
console.log(`Listening at http://${HOST}:${PORT}...`);
// Attach WebSocket server to web server
server.on('upgrade', (request, socket, head) => {
wsServer.handleUpgrade(request, socket, head, socket => {
wsServer.emit('connection', socket, request);
});
});