forked from Luca-spopo/ittlab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DotBots-server.js
101 lines (91 loc) · 2.78 KB
/
DotBots-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
"use strict";
var
const assert = function(val, mess)
{
if (!val)
(null).assertionFailed = 0 //HAXXX
//TODO: When you have internet, check how to stacktrace
}
let play = {main : ()=>null };//require("server-play")
const dbglog = console.log;
/*
Modes/Lifecycle of a player:
Registering (Give your name, synch timestamps)
=> Preparing (Spawn location decided, etc, preparations made by server)
=> Playing (Player is playing right now)
=> Dead (Player has died, and camera is lingering)
=> Preparing
*/
{
const nameCheck = /^[a-z_0-9]{1,10}$/i
const PlayerTable = new Map(); //WebSocket => Player Details
const NamePool = new Set();
//PlayerTable is sent to other modules as context, and is thus const.
const PlayerFSM = function* ()
{
const [player, ws, FSM] = yield; //Bind to these variables, given on connection
const FSMcall = FSM.next.bind(FSM, FSM);
assert(yield == "FSM:getName")
{ //Get name
let name = yield
while (NamePool.has(name) || !nameCheck.test(name)) //Input name
{
ws.send(1) //Name invalid
name = yield
}
NamePool.add(name)
player.name = name;
ws.send(0)
}
assert(yield == "FSM:ts")
{ //Synch timestamps
let min = 9999; //a 10 second max lag is a very reasonable assumption.
let minstart = 0
let minnum = -1
const id = new Buffer([0])
const pongHandler = (data) => { if(data[0]===id[0]) FSMcall() }
ws.on("pong", pongHandler)
for(let i=0; i<10; i++)
{
let lag = Date.now()
id[0] = Math.floor(Math.random()*256);
ws.ping(id)
//We need to have a mechanism so yield's source is trusted.
//This mechanism is making FSMcall created yields return the FSM
//In the future we will have async/await to deal with this stuff
//TODO: Change the generator mechanism to use asynch/await with nodejs7
assert(FSM === (yield)); //Wait for pong to callback
lag = Date.now() - lag;
dbglog("Detected lag of: ", lag); //DEBUG:
if(lag < min)
min = lag;
minstart = start;
minnum = i;
}
ws.removeListener("pong", pongHandler)
dbglog("Minimum latency: ", min)
//min is the time it takes to send a message to the client
}
}
let messageHandler = function(message)
{
let details = PlayerTable.get(this)
details.onMessage.next(message)
}
let connectPlayer = function(ws)
{
let FSM = PlayerFSM();
let details = {onMessage : FSM};
PlayerTable.set(ws, details)
FSM.next();
FSM.next([details, ws, FSM])
ws.on("message", messageHandler)
//ws.on("close", disconnectHandler)
}
let main = function()
{
play.main({PlayerTable : PlayerTable});
exports.connectPlayer = connectPlayer; //Start accepting connections
}
exports.main = main;
}