-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
153 lines (143 loc) · 5.85 KB
/
server.js
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
const WebSocket = require('ws');
const Storage = require('./lib/storage');
const Driver = require('./lib/howlplay-ws-driver');
const Queue = require('./lib/functionQueue');
const config = require('./config/config');
const util = require('./lib/util');
// Initialize variables
let storage = new Storage();
let connectionId = 0;
let started = false;
let startTime = new Date();
const wss = new WebSocket.Server({ port: config.port }, ()=> {
console.log("Started Listening On Port: ", config.port);
console.log("Server running at: ", startTime);
});
wss.on('connection', (ws) => {
console.log("New connection ...");
// Push this socket to connection pool
let currentId = connectionId;
let currentConnection = {
id: connectionId,
lastPing: new Date(),
dead: false,
ws: ws
};
storage.data.connections[connectionId] = currentConnection;
connectionId++;
ws.on('message', (data) => {
let dataView = new Uint8Array(data);
console.log(dataView[0]);
switch(dataView[0]){
case 0:
Driver.handlers.pingHandler(currentConnection, data, storage).then(()=>{}).catch(()=>{});
break;
case 1:
console.log("Request to set nickname");
Driver.handlers.nicknameHandler(currentConnection, data, storage).then((nickname) => {
console.log("Nickname set", nickname);
Driver.emitters.confirmNicknameEmitter(null).then((buf) => ws.send(buf));
}).catch(() => {
Driver.emitters.rejectNicknameEmitter(null).then((buf) => ws.send(buf));
});
break;
case 4:
Driver.handlers.quizHandler(currentConnection, data, storage).then((quiz) => {
let payload = [quiz.quizDuration];
Driver.emitters.confirmQuizEmitter(null).then((buf) => ws.send(buf));
Driver.emitters.gameDetailsEmitter(payload).then((buf) => ws.send(buf));
}).catch(() => {
Driver.emitters.rejectQuizEmitter(null).then((buf) => ws.send(buf));
});
break;
case 7:
Driver.handlers.quizAnswersHandler(currentConnection, data, storage).then((answers) => {
let payload = [answers.index, answers.answers.length];
Driver.emitters.confirmAnswersEmitter(payload).then(buf => ws.send(buf));
}).catch(() => {
Driver.emitters.rejectAnswersEmitter(null).then(buf => ws.send(buf));
});
break;
case 12:
console.log("LET ZE GAMES BEGIN!");
started = true;
wss.broadcast((client) => {
Driver.emitters.startGameEmitter().then((buf) => { client.send(buf) });
});
break;
case 13:
console.log("End Ze Game!");
wss.broadcast((client) => {
Driver.emitters.endGameEmitter().then((buf) => { client.send(buf) });
});
break;
case 14:
console.log("Distribute game details");
Driver.handlers.gameDetailsHandler(currentConnection, data, storage).then((users) => {
var buffer = util.stringToArrayBuffer(JSON.stringify(users));
Driver.emitters.gameDetailsEmitter(buffer).then((buf) => {
console.log("Sending buf");
ws.send(buf);
});
}).catch(() => {
ws.send("Failed to retrieve players");
});
break;
case 15:
console.log("Return the start datetime (Should be made to be dependent on protocol 12)");
var buffer = util.stringToArrayBuffer(String(startTime));
Driver.emitters.gameStartTimeEmitter(buffer).then((buf) => {
ws.send(buf);
});
break;
case 16:
console.log("Soft Restarting Server");
// Disconnect everyone
wss.broadcast((client) => {
client.close();
}, () => {
// Clear Queue and DB of people (TBH people gets removed when disconnect, but assume it gets removed?)
Queue.clearQueue();
Driver.handlers.clearStorageHandler(storage).then(() => {
started = false;
connectionId = 0;
startTime = new Date();
});
});
break;
default:
break;
}
});
ws.on('error', (e) => {
console.log("Websocket error", e)
});
ws.on('close', async () => {
console.log("Connection " + currentId + " is dead.");
currentConnection.dead = true;
await storage.data.participants.remove({_id: currentId});
});
// Continue to ping the client
let pingInterval = setInterval(async () => {
// If we haven't seen a ping in 4 seconds, set it to dead, and stop ping.
let now = new Date();
if((now.getTime() - currentConnection.lastPing.getTime()) > 4000) {
clearInterval(pingInterval);
currentConnection.ws.close();
return;
}
// Otherwise, we emit ping
Driver.emitters.pingEmitter(currentConnection, storage).then((buff) => {
ws.send(buff);
}).catch(() => {});
}, 1000);
});
// Broadcasting function
wss.broadcast = function broadcast(action, callback) {
wss.clients.forEach(function each(client) {
action(client);
});
if (callback) {
callback();
}
};