@unitn-asa/deliveroo-js-sdk 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +49 -0
- package/package.json +38 -0
- package/src/client/DjsClientSocket.js +312 -0
- package/src/client/DjsRestClient.js +432 -0
- package/src/client/connectUtil.js +51 -0
- package/src/client/index.js +21 -0
- package/src/server/DjsServer.js +136 -0
- package/src/server/DjsServerSocket.js +316 -0
- package/src/server/index.js +21 -0
- package/src/types/IOAgent.js +14 -0
- package/src/types/IOClockEvent.js +21 -0
- package/src/types/IOConfig.js +17 -0
- package/src/types/IOCrate.js +9 -0
- package/src/types/IOGameOptions.js +54 -0
- package/src/types/IOIdentity.js +12 -0
- package/src/types/IOInfo.js +11 -0
- package/src/types/IOParcel.js +11 -0
- package/src/types/IOSensing.js +15 -0
- package/src/types/IOSocketEvents.js +44 -0
- package/src/types/IOTile.js +28 -0
- package/src/types/parseClockEvent.js +17 -0
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {import("../types/IOAgent.js").IOAgent} IOAgent
|
|
4
|
+
* @typedef {import("../types/IOParcel.js").IOParcel} IOParcel
|
|
5
|
+
* @typedef {import("../types/IOConfig.js").IOConfig} IOConfig
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {{
|
|
12
|
+
* 'agents': () => IOAgent[],
|
|
13
|
+
* 'agents/:id': () => IOAgent,
|
|
14
|
+
* 'configs': () => IOConfig,
|
|
15
|
+
* 'levels': () => IOConfig[],
|
|
16
|
+
* 'level': () => IOConfig,
|
|
17
|
+
* 'maps': () => any[],
|
|
18
|
+
* 'map': () => any,
|
|
19
|
+
* 'npcs': () => any[],
|
|
20
|
+
* 'npc': () => any,
|
|
21
|
+
* 'parcels': () => IOParcel[],
|
|
22
|
+
* 'parcel': () => IOParcel,
|
|
23
|
+
* }} IODeliveroojsGETRoutes
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {{
|
|
28
|
+
* 'agents': (body: IOAgent) => IOAgent,
|
|
29
|
+
* 'levels': (body: IOConfig) => IOConfig,
|
|
30
|
+
* 'maps': (body: any) => IOConfig,
|
|
31
|
+
* 'npcs': (body: any) => {},
|
|
32
|
+
* 'parcels': (body: IOParcel) => IOParcel,
|
|
33
|
+
* }} IODeliveroojsPOSTRoutes
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {{
|
|
38
|
+
* 'agents': () => IOAgent[],
|
|
39
|
+
* 'agents/:id': () => IOAgent,
|
|
40
|
+
* 'npcs': () => any[],
|
|
41
|
+
* 'npc': (id: string) => any,
|
|
42
|
+
* 'parcels': () => IOParcel[],
|
|
43
|
+
* 'parcel': (id: string) => IOParcel,
|
|
44
|
+
* }} IODeliveroojsDELETERoutes
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @class
|
|
51
|
+
*/
|
|
52
|
+
export class DjsRestClient {
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/** @type {string} */
|
|
57
|
+
#HOST = 'http://localhost:8080';
|
|
58
|
+
/** @type {string} */
|
|
59
|
+
get HOST() { return this.#HOST }
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Initialize HOST for API calls.
|
|
65
|
+
* @param {string} HOST
|
|
66
|
+
*/
|
|
67
|
+
constructor( HOST ) {
|
|
68
|
+
this.#HOST = HOST;
|
|
69
|
+
console.log("DjsRestClient (API RESTful Client) initialized with HOST:", this.HOST);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @template { keyof IODeliveroojsGETRoutes } K
|
|
76
|
+
* @param { K } resource
|
|
77
|
+
* @param { string } token
|
|
78
|
+
* @returns {Promise<ReturnType<IODeliveroojsGETRoutes[K][]>>}
|
|
79
|
+
*/
|
|
80
|
+
async getAll ( resource, token ) {
|
|
81
|
+
|
|
82
|
+
return new Promise( (resolve, reject) => {
|
|
83
|
+
|
|
84
|
+
const url = this.HOST+'/api/'+resource;
|
|
85
|
+
|
|
86
|
+
console.log( 'GET', url );
|
|
87
|
+
|
|
88
|
+
fetch(url, {
|
|
89
|
+
method: 'GET',
|
|
90
|
+
headers: {
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
'x-token': token
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
.then( JSON.stringify )
|
|
97
|
+
|
|
98
|
+
.then( body => resolve( /** @type {any} */ (body)) )
|
|
99
|
+
|
|
100
|
+
.catch(error => {
|
|
101
|
+
console.error('An error occurred:', error);
|
|
102
|
+
reject('Error getting config');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
} );
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @template { keyof IODeliveroojsGETRoutes } K
|
|
112
|
+
* @param { K } resource
|
|
113
|
+
* @param { string } id
|
|
114
|
+
* @param { string } token
|
|
115
|
+
* @returns {Promise<ReturnType<IODeliveroojsGETRoutes[K]>>}
|
|
116
|
+
*/
|
|
117
|
+
async get ( resource, id, token ) {
|
|
118
|
+
|
|
119
|
+
return new Promise( (resolve, reject) => {
|
|
120
|
+
|
|
121
|
+
// replace placeholder ':id' with value of id in string resource
|
|
122
|
+
const url = this.HOST+'/api/'+resource.replace( ':id', id );
|
|
123
|
+
|
|
124
|
+
console.log( 'GET', url );
|
|
125
|
+
|
|
126
|
+
fetch(url, {
|
|
127
|
+
method: 'GET',
|
|
128
|
+
headers: {
|
|
129
|
+
'Content-Type': 'application/json',
|
|
130
|
+
'x-token': token
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
.then( JSON.stringify )
|
|
135
|
+
|
|
136
|
+
.then( body => resolve( /** @type {any} */ (body)) )
|
|
137
|
+
|
|
138
|
+
.catch(error => {
|
|
139
|
+
console.error('An error occurred:', error);
|
|
140
|
+
reject('Error getting config');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
} );
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @template { keyof IODeliveroojsPOSTRoutes } K
|
|
151
|
+
* @param { K } resource
|
|
152
|
+
* @param { string } token
|
|
153
|
+
* @param { Parameters<IODeliveroojsPOSTRoutes[K]>[0] } body
|
|
154
|
+
* @returns {Promise<ReturnType<IODeliveroojsPOSTRoutes[K]>>}
|
|
155
|
+
*/
|
|
156
|
+
async post ( resource, token, body ) {
|
|
157
|
+
|
|
158
|
+
return new Promise( (resolve, reject) => {
|
|
159
|
+
|
|
160
|
+
const url = this.HOST+'/api/'+resource;
|
|
161
|
+
|
|
162
|
+
console.log( 'POST', url, body );
|
|
163
|
+
|
|
164
|
+
fetch(url, {
|
|
165
|
+
method: 'POST',
|
|
166
|
+
headers: {
|
|
167
|
+
'Content-Type': 'application/json',
|
|
168
|
+
'x-token': token
|
|
169
|
+
},
|
|
170
|
+
body: JSON.stringify( body )
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
.then( JSON.stringify )
|
|
174
|
+
|
|
175
|
+
.then( body => resolve( /** @type {any} */ (body)) )
|
|
176
|
+
|
|
177
|
+
.catch(error => {
|
|
178
|
+
console.error('An error occurred:', error);
|
|
179
|
+
reject('Error getting config');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
} );
|
|
183
|
+
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
async getToken(name, team, password) {
|
|
189
|
+
return new Promise((resolve, reject) => {
|
|
190
|
+
|
|
191
|
+
console.log("Name fetch: ", name + " team fetch: ", team);
|
|
192
|
+
|
|
193
|
+
fetch(this.HOST+'/api/tokens', {
|
|
194
|
+
method: 'POST',
|
|
195
|
+
headers: {
|
|
196
|
+
'Content-Type': 'application/json',
|
|
197
|
+
'name': name,
|
|
198
|
+
'team': team,
|
|
199
|
+
'password': password
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
.then(response => {
|
|
203
|
+
if (response.ok) {
|
|
204
|
+
return response.json();
|
|
205
|
+
}
|
|
206
|
+
throw new Error(`Error generating token, Status code: ${response.status}`);
|
|
207
|
+
})
|
|
208
|
+
.then(data => {
|
|
209
|
+
console.log("token ottenuto: " + data.token.slice(-30));
|
|
210
|
+
resolve(data);
|
|
211
|
+
})
|
|
212
|
+
.catch(error => {
|
|
213
|
+
console.error('An error occurred:', error);
|
|
214
|
+
reject('No tokens available at the moment');
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
async getConfig ( token ) {
|
|
222
|
+
return new Promise((resolve, reject) => {
|
|
223
|
+
fetch(this.HOST+'/api/configs', {
|
|
224
|
+
method: 'GET',
|
|
225
|
+
headers: {
|
|
226
|
+
'Content-Type': 'application/json',
|
|
227
|
+
'x-token': token
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
.then( JSON.stringify )
|
|
231
|
+
.catch(error => {
|
|
232
|
+
console.error('An error occurred:', error);
|
|
233
|
+
reject('Error getting config');
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
*
|
|
242
|
+
* @param {string} token
|
|
243
|
+
* @param {{}} config
|
|
244
|
+
* @returns
|
|
245
|
+
*/
|
|
246
|
+
async patchConfig ( token, config ) {
|
|
247
|
+
|
|
248
|
+
console.log( "Patching config: ", config );
|
|
249
|
+
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
fetch(this.HOST+'/api/configs', {
|
|
252
|
+
method: 'PATCH',
|
|
253
|
+
headers: {
|
|
254
|
+
'Content-Type': 'application/json',
|
|
255
|
+
'x-token': token
|
|
256
|
+
},
|
|
257
|
+
body: JSON.stringify(config)
|
|
258
|
+
})
|
|
259
|
+
// parsing response
|
|
260
|
+
.then( JSON.stringify )
|
|
261
|
+
// .then( response => {
|
|
262
|
+
// console.log("config patched: " + response);
|
|
263
|
+
// for ( let [key,value] of Object.entries(response) ) {
|
|
264
|
+
// settings[key] = value;
|
|
265
|
+
// }
|
|
266
|
+
// resolve(settings);
|
|
267
|
+
// })
|
|
268
|
+
.catch(error => {
|
|
269
|
+
console.error('An error occurred:', error);
|
|
270
|
+
reject('Error patching config');
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* @param {string} token
|
|
279
|
+
* @param {string} id
|
|
280
|
+
* @returns
|
|
281
|
+
*/
|
|
282
|
+
async deleteAgent ( token, id ) {
|
|
283
|
+
return new Promise((resolve, reject) => {
|
|
284
|
+
fetch(this.HOST+'/api/agents/'+id, {
|
|
285
|
+
method: 'DELETE',
|
|
286
|
+
headers: {
|
|
287
|
+
'Content-Type': 'application/json',
|
|
288
|
+
'x-token': token
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
.then(response => {
|
|
292
|
+
if (response.ok) {
|
|
293
|
+
return response.json();
|
|
294
|
+
}
|
|
295
|
+
throw new Error(`Error deleting agent, Status code: ${response.status}`);
|
|
296
|
+
})
|
|
297
|
+
.then(data => {
|
|
298
|
+
console.log("agent deleted: " + data);
|
|
299
|
+
resolve(data);
|
|
300
|
+
})
|
|
301
|
+
.catch(error => {
|
|
302
|
+
console.error('An error occurred:', error);
|
|
303
|
+
reject('Error deleting agent');
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* @param {string} token
|
|
312
|
+
* @param {string} id
|
|
313
|
+
* @param {{score?:number, penalty?:number}} agent
|
|
314
|
+
* @returns
|
|
315
|
+
*/
|
|
316
|
+
async patchAgent ( token, id, agent ) {
|
|
317
|
+
return new Promise((resolve, reject) => {
|
|
318
|
+
fetch(this.HOST+'/api/agents/'+id, {
|
|
319
|
+
method: 'PATCH',
|
|
320
|
+
headers: {
|
|
321
|
+
'Content-Type': 'application/json',
|
|
322
|
+
'x-token': token
|
|
323
|
+
},
|
|
324
|
+
body: JSON.stringify(agent)
|
|
325
|
+
})
|
|
326
|
+
.then(response => {
|
|
327
|
+
if (response.ok) {
|
|
328
|
+
return response.json();
|
|
329
|
+
}
|
|
330
|
+
throw new Error(`Error patching agent, Status code: ${response.status}`);
|
|
331
|
+
})
|
|
332
|
+
.then(data => {
|
|
333
|
+
console.log("agent patched: " + data);
|
|
334
|
+
resolve(data);
|
|
335
|
+
})
|
|
336
|
+
.catch(error => {
|
|
337
|
+
console.warn('An error occurred:', error);
|
|
338
|
+
reject('Error patching agent');
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
*
|
|
347
|
+
* @param {string} token
|
|
348
|
+
* @param {string} id
|
|
349
|
+
* @returns
|
|
350
|
+
*/
|
|
351
|
+
async deleteParcel( token, id ) {
|
|
352
|
+
return new Promise((resolve, reject) => {
|
|
353
|
+
fetch(this.HOST+'/api/parcels/'+id, {
|
|
354
|
+
method: 'DELETE',
|
|
355
|
+
headers: {
|
|
356
|
+
'Content-Type': 'application/json',
|
|
357
|
+
'x-token': token
|
|
358
|
+
}
|
|
359
|
+
})
|
|
360
|
+
.then(response => {
|
|
361
|
+
if (response.ok) {
|
|
362
|
+
return response.json();
|
|
363
|
+
}
|
|
364
|
+
throw new Error(`Error deleting parcel, Status code: ${response.status}`);
|
|
365
|
+
})
|
|
366
|
+
.then(data => {
|
|
367
|
+
console.log("parcel deleted: " + data);
|
|
368
|
+
resolve(data);
|
|
369
|
+
})
|
|
370
|
+
.catch(error => {
|
|
371
|
+
console.warn('An error occurred:', error);
|
|
372
|
+
reject('Error deleting parcel');
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Delete all parcels from the grid.
|
|
381
|
+
* @param {*} token
|
|
382
|
+
*/
|
|
383
|
+
async deleteAllParcels( token ) {
|
|
384
|
+
return new Promise((resolve, reject) => {
|
|
385
|
+
fetch(this.HOST+'/api/parcels', {
|
|
386
|
+
method: 'DELETE',
|
|
387
|
+
headers: {
|
|
388
|
+
'Content-Type': 'application/json',
|
|
389
|
+
'x-token': token
|
|
390
|
+
}
|
|
391
|
+
})
|
|
392
|
+
.then(response => {
|
|
393
|
+
if (response.ok) {
|
|
394
|
+
return response.json();
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
throw new Error(`Error deleting all parcels, Status code: ${response.status}`);
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
.then(data => {
|
|
401
|
+
console.log("all parcels deleted: " + data);
|
|
402
|
+
resolve(data);
|
|
403
|
+
})
|
|
404
|
+
.catch(error => {
|
|
405
|
+
console.warn('An error occurred:', error);
|
|
406
|
+
reject('Error deleting all parcels');
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
// Example usage:
|
|
418
|
+
//
|
|
419
|
+
// const api = new DeliveroojsRestClient('http://localhost:8080');
|
|
420
|
+
// api.get('agents', '', 'some-token').then( agents => console.log( agents ) );
|
|
421
|
+
// api.get('agents/:id', 'some-id', 'some-token').then( agent => console.log( agent ) );
|
|
422
|
+
// api.post('agents', 'some-token', {
|
|
423
|
+
// id: 'agent-123',
|
|
424
|
+
// name: 'Agent 123',
|
|
425
|
+
// teamId: 'team-1',
|
|
426
|
+
// teamName: 'Team 1',
|
|
427
|
+
// score: 0,
|
|
428
|
+
// penalty: 0,
|
|
429
|
+
// x: 0,
|
|
430
|
+
// y: 0
|
|
431
|
+
// } )
|
|
432
|
+
// .then( agent => console.log( agent ) );
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { io } from "socket.io-client";
|
|
2
|
+
import { default as argsparser } from "args-parser";
|
|
3
|
+
import { DjsClientSocket } from "./DjsClientSocket.js";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Takes the following arguments from console:
|
|
9
|
+
* token or name
|
|
10
|
+
* e.g:
|
|
11
|
+
* $ node index.js -token=... -name=marco
|
|
12
|
+
* $ npm start -- -token=... -name=marco
|
|
13
|
+
*/
|
|
14
|
+
const args = argsparser(process? process?.argv : []);
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @returns { DjsClientSocket }
|
|
20
|
+
*/
|
|
21
|
+
export function connect ( host, token = args['token'], name = args['name'], autoconnect = true ) {
|
|
22
|
+
|
|
23
|
+
let opts = {
|
|
24
|
+
autoConnect: false,
|
|
25
|
+
withCredentials: false,
|
|
26
|
+
// extraHeaders: { 'x-token': TOKEN || token }
|
|
27
|
+
// query: { name: NAME }
|
|
28
|
+
// path: '/'
|
|
29
|
+
};
|
|
30
|
+
if ( token && token != '' )
|
|
31
|
+
opts.extraHeaders = { 'x-token': token }
|
|
32
|
+
else if ( name && name != '' )
|
|
33
|
+
opts.query = { name: name }
|
|
34
|
+
|
|
35
|
+
const enhancedClientSocket = DjsClientSocket.enhance( io( host, opts ) );
|
|
36
|
+
|
|
37
|
+
if ( autoconnect )
|
|
38
|
+
enhancedClientSocket.connect();
|
|
39
|
+
|
|
40
|
+
console.log( `Connecting to ${host} as ${ token ? 'token '+ (token).substring(0,5)+'...' : name ? 'name '+name : 'guest' }` );
|
|
41
|
+
|
|
42
|
+
return enhancedClientSocket;
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
// Example usage:
|
|
49
|
+
//
|
|
50
|
+
// const socket = connect( 'http://localhost:8080', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjczZDZkOSIsIm5hbWUiOiJub21lX21vbHRvX2x1bmdvXzEiLCJ0ZWFtSWQiOiIyNDc0ZDkiLCJ0ZWFtTmFtZSI6Im5vbWVfdGVhbV9tb2x0b19sdW5nbyIsInJvbGUiOiJ1c2VyIiwiaWF0IjoxNzQ4MzUxOTM3fQ.rhEHyAoaQhqVqhEJ5bqyu3UdcvJWK5RLWKJxkBDAX_0', true );
|
|
51
|
+
// socket.emitMove( 'up' );
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {import("../types/IOConfig.js").IOConfig} IOConfig
|
|
4
|
+
* @typedef {import("../types/IOGameOptions.js").IOGameOptions} IOGameOptions
|
|
5
|
+
*
|
|
6
|
+
* @typedef {import("../types/IOClockEvent.js").IOClockEvent} IOClockEvent
|
|
7
|
+
*
|
|
8
|
+
* @typedef {import("../types/IOAgent.js").IOAgent} IOAgent
|
|
9
|
+
* @typedef {import("../types/IOParcel.js").IOParcel} IOParcel
|
|
10
|
+
* @typedef {import("../types/IOTile.js").IOTile} IOTile
|
|
11
|
+
*
|
|
12
|
+
* @typedef {import("../types/IOIdentity.js").IOIdentity} IOIdentity
|
|
13
|
+
* @typedef {import("../types/IOInfo.js").IOInfo} IOInfo
|
|
14
|
+
* @typedef {import("../types/IOSensing.js").IOSensing} IOSensing
|
|
15
|
+
*
|
|
16
|
+
* @typedef {import("../types/IOSocketEvents.js").IOClientEvents} IOClientEvents
|
|
17
|
+
* @typedef {import("../types/IOSocketEvents.js").IOServerEvents} IOServerEvents
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export { DjsClientSocket } from './DjsClientSocket.js';
|
|
21
|
+
export { DjsRestClient } from './DjsRestClient.js';
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Server } from 'socket.io';
|
|
2
|
+
import { DjsServerSocket } from './DjsServerSocket.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("../types/IOAgent.js").IOAgent} IOAgent
|
|
6
|
+
* @typedef {import("../types/IOParcel.js").IOParcel} IOParcel
|
|
7
|
+
* @typedef {import("../types/IOTile.js").IOTile} IOTile
|
|
8
|
+
* @typedef {import("../types/IOConfig.js").IOConfig} IOConfig
|
|
9
|
+
* @typedef {import("../types/IOInfo.js").IOInfo} IOInfo
|
|
10
|
+
*
|
|
11
|
+
* @typedef {import("../types/IOSocketEvents.js").IOSensing} IOSensing
|
|
12
|
+
* @typedef {import("../types/IOSocketEvents.js").IOClientEvents} IOClientEvents on the client side these are to be emitted with .emit
|
|
13
|
+
* @typedef {import("../types/IOSocketEvents.js").IOServerEvents} IOServerEvents on the client side these are to be listened with .on
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @class
|
|
18
|
+
* @extends { Server<IOClientEvents, IOServerEvents> }
|
|
19
|
+
*/
|
|
20
|
+
export class DjsServer extends Server {
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Broadcast config to all connected clients
|
|
24
|
+
* @param { IOConfig } config
|
|
25
|
+
*/
|
|
26
|
+
broadcastConfig(config) {
|
|
27
|
+
this.emit('config', config);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Broadcast map to all connected clients
|
|
32
|
+
* @param { number } width
|
|
33
|
+
* @param { number } height
|
|
34
|
+
* @param { IOTile[] } tiles
|
|
35
|
+
*/
|
|
36
|
+
broadcastMap(width, height, tiles) {
|
|
37
|
+
this.emit('map', width, height, tiles);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Broadcast a tile update to all connected clients
|
|
42
|
+
* @param { IOTile } tile
|
|
43
|
+
* @param { IOInfo } info
|
|
44
|
+
*/
|
|
45
|
+
broadcastTile({ x, y, type }, info) {
|
|
46
|
+
this.emit('tile', { x, y, type }, info);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Broadcast controller status (agent connected/disconnected) to all clients
|
|
51
|
+
* @param { 'connected' | 'disconnected' } status
|
|
52
|
+
* @param { Parameters<IOServerEvents['controller']>[1] } agent
|
|
53
|
+
*/
|
|
54
|
+
broadcastController(status, { id, name, teamId, teamName, score }) {
|
|
55
|
+
this.emit('controller', status, { id, name, teamId, teamName, score });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Broadcast a message to all connected clients
|
|
60
|
+
* @param { string } fromId
|
|
61
|
+
* @param { string } fromName
|
|
62
|
+
* @param { any } msg
|
|
63
|
+
*/
|
|
64
|
+
broadcastMessage(fromId, fromName, msg) {
|
|
65
|
+
this.emit('msg', fromId, fromName, msg);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Broadcast a log message to all connected clients
|
|
70
|
+
* @param { 'server' | { socket:string, id:string, name:string } } src - 'server' or client
|
|
71
|
+
* @param { IOInfo } info
|
|
72
|
+
* @param { ...any } message
|
|
73
|
+
*/
|
|
74
|
+
broadcastLog(src, info, ...message) {
|
|
75
|
+
this.emit('log', src, info, ...message);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// /**
|
|
79
|
+
// * Get all sockets in a room
|
|
80
|
+
// * @param { string } roomName
|
|
81
|
+
// * @returns { Promise<import('./DjsServerSocket.js').DjsServerSocket[]> }
|
|
82
|
+
// */
|
|
83
|
+
// async fetchSocketsInRoom(roomName) {
|
|
84
|
+
// const sockets = await this.in(roomName).fetchSockets();
|
|
85
|
+
// return sockets.forEach(s => DjsServerSocket.enhance(s));
|
|
86
|
+
// }
|
|
87
|
+
|
|
88
|
+
// /**
|
|
89
|
+
// * Count sockets in a room
|
|
90
|
+
// * @param { string } roomName
|
|
91
|
+
// * @returns { Promise<number> }
|
|
92
|
+
// */
|
|
93
|
+
// async countSocketsInRoom(roomName) {
|
|
94
|
+
// const sockets = await this.fetchSocketsInRoom(roomName);
|
|
95
|
+
// return sockets.length;
|
|
96
|
+
// }
|
|
97
|
+
|
|
98
|
+
// /**
|
|
99
|
+
// * Emit to all sockets in a specific room
|
|
100
|
+
// * @param { string } roomName
|
|
101
|
+
// * @param { string } event
|
|
102
|
+
// * @param { ...any } args
|
|
103
|
+
// */
|
|
104
|
+
// emitToRoom(roomName, event, ...args) {
|
|
105
|
+
// this.to(roomName).emit(event, ...args);
|
|
106
|
+
// }
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Enhance a Socket.io Server into a DjsServer
|
|
110
|
+
* @param { Server } server
|
|
111
|
+
* @returns { DjsServer }
|
|
112
|
+
*/
|
|
113
|
+
static enhance(server) {
|
|
114
|
+
/**
|
|
115
|
+
* Mixin function to copy methods from a class prototype to an object
|
|
116
|
+
*/
|
|
117
|
+
function applyMixin(target, MixinClass) {
|
|
118
|
+
let proto = MixinClass.prototype;
|
|
119
|
+
|
|
120
|
+
const descriptors = Object.getOwnPropertyDescriptors(proto);
|
|
121
|
+
delete descriptors.constructor;
|
|
122
|
+
|
|
123
|
+
Object.defineProperties(target, descriptors);
|
|
124
|
+
|
|
125
|
+
return target;
|
|
126
|
+
}
|
|
127
|
+
applyMixin(server, DjsServer);
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Original server enhanced with DjsServer methods
|
|
131
|
+
* @type { DjsServer }
|
|
132
|
+
*/
|
|
133
|
+
// @ts-ignore
|
|
134
|
+
return server;
|
|
135
|
+
}
|
|
136
|
+
}
|