forked from tcecspectator/mytcecgui
-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathchat_server.js
126 lines (113 loc) · 3.1 KB
/
chat_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
// chat_server.js
// @authors octopoulo <[email protected]>, Aloril <[email protected]>
// @version 2021-02-05
/*
globals
console, exports, require
*/
'use strict';
let Module = require('./js/chess-wasm.js'),
{Stringify} = require('./js/common.js'),
Net = require('net');
let frc = false,
LS = console.log,
port = 8090,
server = new Net.Server();
server.listen(port, () => {
LS(`Server listening for connection requests on socket localhost:${port}.`);
});
let chess,
voting = {}; //indexed by fen, supports 1-2 clients
/**
* Load chess-wasm
*/
async function load_wasm() {
let instance = await Module();
chess = new instance.Chess();
LS('chess library loaded');
}
function vote(data) {
LS('vote, data=' + Stringify(data));
if (typeof data.fen == "string") { //needed because fen string here don't match fen strings in Python
let lst = data.fen.split(" ");
data.fen = lst[0] + " " + lst[1] + " " + lst[5];
}
if (!(data.fen in voting) || typeof data.move != "string" || data.move.length > 5) {
LS('Not found');
return;
}
if (!data.time) {
LS('Old GUI, no voting');
return;
}
let entry = voting[data.fen],
move = data.move;
LS('entry: ' + Stringify(entry.votes) + ' ' + Stringify(entry.byIP));
if (!(move in entry.votes)) {
entry.votes[move] = 0;
}
if (data.ip in entry.byIP) {
if (entry.byIP[data.ip] == move) {
LS("Same move as earlier: " + move);
return;
}
LS(`Reduce vote: ${entry.byIP[data.ip]} by ${data.ip}`);
entry.votes[entry.byIP[data.ip]]--;
}
entry.votes[move]++;
entry.byIP[data.ip] = move;
let msg = Stringify({
fen: data.fen,
votes: Object.entries(entry.votes),
});
LS(`Sending data: ${msg}.`);
LS('---');
entry.socket.write(msg.length.toString().padStart(4, " ") + msg);
}
server.on('connection', async socket => {
let ip = socket.remoteAddress;
LS(`A new connection has been established: ${ip}.`);
if (ip != '::ffff:127.0.0.1') {
LS('Not local connection, closing');
socket.destroy();
return;
}
if (!chess)
await load_wasm();
socket.on('data', chunk => {
// CHECK THIS: FIX: handle 2 messages in one packet or incomplete packets:
// Error can triggered by "go movetime 100" for example. Could use same method as chat_engine.read_votes does.
LS('data');
let data, text;
try {
text = chunk.toString();
data = JSON.parse(text);
}
catch (e) {
LS(`bad data: ${data}, text: ${text}`);
LS(e);
return;
}
if (data.voting != undefined) {
if (data.voting) {
voting[data.fen] = {
votes: {},
byIP: {},
socket: socket
};
LS("created empty voting");
} else if ( data.fen in voting ) {
delete voting[data.fen];
LS("deleted voting");
}
}
LS(`Data received from client: ${text}`);
});
socket.on('end', () => {
LS('Closing connection with the client');
});
socket.on('error', err => {
LS(`Error: ${err}`);
});
});
exports.vote = vote;