generated from drawwithcode/node-and-p5
-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.js
185 lines (151 loc) · 4.11 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// load express library
const express = require('express');
const {v4: uuid} = require('uuid');
// create the app
const app = express();
// define the port where client files will be provided
const port = process.env.PORT || 3000;
// start to listen to that port
const server = app.listen(port);
// provide static access to the files
// in the "public" folder
app.use(express.static('public'));
app.use('/face-api', express.static(__dirname + '/node_modules/face-api.js/dist/'));
// load socket library
const socket = require('socket.io');
// create a socket connection
const io = socket(server);
// define which function should be called
// when a new connection is opened from client
io.on('connection', onConnection);
// callback function: the paramenter (in this case socket)
// will contain all the information on the new connection
function onConnection(socket) {
const room = getRoom(socket);
// when a new connection is created, print its id
console.log('New socket. Id: ' + socket.id + ' connected to room ' + room.id);
socket.on('player.updated', function(...args) {
socket.to(room.id).broadcast.emit('player.updated', socket.id, ...args);
});
socket.on('disconnect', function() {
room.removePlayer(socket);
});
}
console.log('Server is running.\n' +
'Check out at http://localhost:' +
port +
'/ ');
/**
* Limit of players per room.
*
* @type {number}
*/
const playersPerRoom = 12;
const rooms = [];
/**
* Retrieves a room for the player which automatically joins the room.
*
* @param {Socket} player
* @return {Room}
*/
function getRoom(player) {
const room = rooms.find((room) => !room.isRoomFull());
if (typeof room === 'undefined') {
// Array.push returns the new length of the array,
// so the index will be new length minus one.
rooms.push(new Room(player));
return getRoom(player);
}
room.addPlayer(player);
return room;
}
/**
*
* @property {string} id
* @property {int} playing - The index of the current player
* @property {int} playing - The index of the current player
* @property {Socket[]} players - Array of the players in the room.
*/
class Room {
constructor(player) {
this.players = [];
this.id = uuid();
if (player) {
this.addPlayer(player);
}
}
/**
*
* @return {Socket[]} - The list of connected players
*/
get connectedPlayers() {
return this.players.filter((p) => p.connected);
}
/**
* Checks if the rooms is full.
* @return {boolean}
*/
isRoomFull() {
return this.players.length >= playersPerRoom;
}
/**
* Checks if the player is already in the room.
*
* @param player
* @return {boolean}
*/
isPlayerIn(player) {
return this.players.findIndex((p) => p.id === player.id) !== -1;
}
/**
*
* @param {string|int|Socket} player
* @return {number}
*/
getPlayerIndex(player) {
// Checks if it's already the index and returns it.
if (typeof player === 'number') {
return player < this.players.length ? player : -1;
}
let id;
if (typeof player === 'string') {
id = player;
} else if (typeof player === 'object' && player.id) {
id = player.id;
}
return this.players.findIndex((p) => p.id === id);
}
/**
* To be triggered when player leaves. Emits player.left event.
*
* @param {Socket} player
*/
removePlayer(player) {
const index = this.getPlayerIndex(player);
if (index > -1) {
this.players = this.players.slice(index, 1);
console.debug('Player left.', 'Is room full?', this.isRoomFull());
} else {
console.debug('Player was not in this room.');
}
this.emit('player.left', player.id);
}
/**
* Adds a player to the room.
* @param {Socket} player
*/
addPlayer(player) {
// To avoid strange behaviours.
if (this.isPlayerIn(player)) {
return;
}
// Uses socket .join() function to join the socket room.
player.join(this.id);
this.players.push(player);
console.log(
'Player ' + this.players.length + ' connected. ID: ' + player.id);
}
emit(event, ...args) {
return io.to(this.id).emit(event, ...args);
}
}