@rpgjs/server 4.1.2 → 4.2.0
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/CHANGELOG.md +19 -0
- package/browser/rpg.server.js +775 -375
- package/browser/rpg.server.umd.cjs +761 -361
- package/lib/Game/EventManager.js +1 -1
- package/lib/Game/EventManager.js.map +1 -1
- package/lib/Game/Map.d.ts +4 -0
- package/lib/Game/Map.js +11 -1
- package/lib/Game/Map.js.map +1 -1
- package/lib/MatchMaker.js +3 -1
- package/lib/MatchMaker.js.map +1 -1
- package/lib/Player/Player.d.ts +9 -3
- package/lib/Player/Player.js +25 -17
- package/lib/Player/Player.js.map +1 -1
- package/lib/RpgServer.d.ts +29 -0
- package/lib/Scenes/Map.d.ts +2 -3
- package/lib/Scenes/Map.js +7 -3
- package/lib/Scenes/Map.js.map +1 -1
- package/lib/entry-point.js +18 -12
- package/lib/entry-point.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/inject.d.ts +22 -0
- package/lib/inject.js +29 -0
- package/lib/inject.js.map +1 -0
- package/lib/server.d.ts +7 -5
- package/lib/server.js +96 -46
- package/lib/server.js.map +1 -1
- package/package.json +6 -7
- package/src/Game/EventManager.ts +1 -1
- package/src/Game/Map.ts +15 -1
- package/src/MatchMaker.ts +3 -1
- package/src/Player/Player.ts +19 -11
- package/src/RpgServer.ts +30 -1
- package/src/Scenes/Map.ts +6 -2
- package/src/entry-point.ts +19 -12
- package/src/index.ts +1 -0
- package/src/inject.ts +33 -0
- package/src/server.ts +98 -43
package/src/index.ts
CHANGED
package/src/inject.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InjectContext } from "@rpgjs/common";
|
|
2
|
+
|
|
3
|
+
let instanceContext: InjectContext | null = null
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dependency injection function for RPGJS server side.
|
|
7
|
+
*
|
|
8
|
+
* The server-side `inject` function is designed for retrieving instances of server-related classes in the RPGJS framework.
|
|
9
|
+
* This function is crucial for accessing singleton instances of classes like `RpgServerEngine` on the server. It facilitates
|
|
10
|
+
* a clean and efficient approach to handling dependencies within server modules, contributing to a more organized codebase.
|
|
11
|
+
*
|
|
12
|
+
* @template T The class type that you want to retrieve an instance of, specific to server-side modules.
|
|
13
|
+
* @returns {T} Returns the singleton instance of the specified class, ensuring consistent server-side behavior and state management.
|
|
14
|
+
* @since 4.2.0
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* // Example of injecting the RpgServerEngine
|
|
19
|
+
* import { inject, RpgServerEngine } from '@rpgjs/server'
|
|
20
|
+
* const server = inject(RpgServerEngine)
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function inject<T>(service: new (...args: any[]) => T, args: any[] = []): T {
|
|
24
|
+
return instanceContext!.inject(service, args);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function setInject(context: InjectContext) {
|
|
28
|
+
instanceContext = context;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function clearInject() {
|
|
32
|
+
instanceContext = null
|
|
33
|
+
}
|
package/src/server.ts
CHANGED
|
@@ -2,11 +2,12 @@ import { SceneMap } from './Scenes/Map';
|
|
|
2
2
|
import { RpgPlayer } from './Player/Player'
|
|
3
3
|
import { Query } from './Query'
|
|
4
4
|
import { DAMAGE_SKILL, DAMAGE_PHYSIC, DAMAGE_CRITICAL, COEFFICIENT_ELEMENTS } from './presets'
|
|
5
|
-
import { World, WorldClass } from 'simple-room'
|
|
5
|
+
import { World, WorldClass, Transport } from 'simple-room'
|
|
6
6
|
import { Utils, RpgPlugin, Scheduler, HookServer, RpgCommonGame, DefaultInput } from '@rpgjs/common'
|
|
7
7
|
import { Observable } from 'rxjs';
|
|
8
8
|
import { Tick } from '@rpgjs/types';
|
|
9
9
|
import { Actor, Armor, Class, DatabaseTypes, Item, Skill, State, Weapon } from '@rpgjs/database';
|
|
10
|
+
import { inject } from './inject';
|
|
10
11
|
|
|
11
12
|
export class RpgServerEngine {
|
|
12
13
|
|
|
@@ -49,10 +50,13 @@ export class RpgServerEngine {
|
|
|
49
50
|
protected totalConnected: number = 0
|
|
50
51
|
private scheduler: Scheduler = new Scheduler()
|
|
51
52
|
private playerProps: any
|
|
53
|
+
public gameEngine: RpgCommonGame = inject(RpgCommonGame)
|
|
52
54
|
|
|
53
55
|
world: WorldClass = World
|
|
54
56
|
workers: any
|
|
55
57
|
envs: any = {}
|
|
58
|
+
io: any
|
|
59
|
+
inputOptions: any = {}
|
|
56
60
|
|
|
57
61
|
/**
|
|
58
62
|
* Combat formulas
|
|
@@ -60,7 +64,9 @@ export class RpgServerEngine {
|
|
|
60
64
|
* @prop {Socket Io Server} [io]
|
|
61
65
|
* @memberof RpgServerEngine
|
|
62
66
|
*/
|
|
63
|
-
|
|
67
|
+
initialize(io, inputOptions) {
|
|
68
|
+
this.io = io
|
|
69
|
+
this.inputOptions = inputOptions
|
|
64
70
|
this.envs = inputOptions.envs || {}
|
|
65
71
|
if (this.inputOptions.workers) {
|
|
66
72
|
console.log('workers enabled')
|
|
@@ -107,18 +113,22 @@ export class RpgServerEngine {
|
|
|
107
113
|
|
|
108
114
|
if (!this.inputOptions.database) this.inputOptions.database = {}
|
|
109
115
|
|
|
116
|
+
/**
|
|
117
|
+
* data is array with object or array
|
|
118
|
+
*/
|
|
110
119
|
const datas = await RpgPlugin.emit(HookServer.AddDatabase, this.inputOptions.database) || []
|
|
111
120
|
|
|
112
|
-
for (let
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
121
|
+
for (let element of datas) {
|
|
122
|
+
if (Array.isArray(element)) {
|
|
123
|
+
for (let data of element) {
|
|
124
|
+
this.addInDatabase(data.id, data)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
for (let id in element) {
|
|
129
|
+
this.addInDatabase(element[id].id ?? id, element[id])
|
|
130
|
+
}
|
|
116
131
|
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
for (let key in this.inputOptions.database) {
|
|
120
|
-
const data = this.inputOptions.database[key]
|
|
121
|
-
this.addInDatabase(data.id, data)
|
|
122
132
|
}
|
|
123
133
|
|
|
124
134
|
this.loadScenes()
|
|
@@ -233,10 +243,31 @@ export class RpgServerEngine {
|
|
|
233
243
|
return Query._getShapesOfMap(map)
|
|
234
244
|
}
|
|
235
245
|
})
|
|
236
|
-
this.io.on('connection', this.onPlayerConnected.bind(this))
|
|
246
|
+
//this.io.on('connection', this.onPlayerConnected.bind(this))
|
|
247
|
+
this.transport(this.io)
|
|
237
248
|
await RpgPlugin.emit(HookServer.Start, this)
|
|
238
249
|
}
|
|
239
250
|
|
|
251
|
+
private transport(io): Transport {
|
|
252
|
+
const timeoutDisconnect = this.globalConfig.timeoutDisconnect ?? 0
|
|
253
|
+
const auth = this.globalConfig.disableAuth ? () => Utils.generateUID() :
|
|
254
|
+
async (socket) => {
|
|
255
|
+
const val = await RpgPlugin.emit(HookServer.Auth, [this, socket], true)
|
|
256
|
+
if (val.length == 0) {
|
|
257
|
+
return Utils.generateUID()
|
|
258
|
+
}
|
|
259
|
+
return val[val.length - 1]
|
|
260
|
+
}
|
|
261
|
+
const transport = new Transport(io, {
|
|
262
|
+
timeoutDisconnect,
|
|
263
|
+
auth
|
|
264
|
+
})
|
|
265
|
+
this.world.timeoutDisconnect = timeoutDisconnect
|
|
266
|
+
transport.onConnected(this.onPlayerConnected.bind(this))
|
|
267
|
+
transport.onDisconnected(this.onPlayerDisconnected.bind(this))
|
|
268
|
+
return transport
|
|
269
|
+
}
|
|
270
|
+
|
|
240
271
|
get tick(): Observable<Tick> {
|
|
241
272
|
return this.scheduler.tick as any
|
|
242
273
|
}
|
|
@@ -249,8 +280,8 @@ export class RpgServerEngine {
|
|
|
249
280
|
* @returns {void}
|
|
250
281
|
* @memberof RpgServerEngine
|
|
251
282
|
*/
|
|
252
|
-
send() {
|
|
253
|
-
this.world.send()
|
|
283
|
+
send(): Promise<void> {
|
|
284
|
+
return this.world.send()
|
|
254
285
|
}
|
|
255
286
|
|
|
256
287
|
private async updatePlayersMove(deltaTimeInt: number) {
|
|
@@ -316,8 +347,7 @@ export class RpgServerEngine {
|
|
|
316
347
|
maps: this.inputOptions.maps,
|
|
317
348
|
events: this.inputOptions.events,
|
|
318
349
|
worldMaps: this.inputOptions.worldMaps
|
|
319
|
-
}
|
|
320
|
-
this
|
|
350
|
+
}
|
|
321
351
|
))
|
|
322
352
|
}
|
|
323
353
|
|
|
@@ -347,11 +377,58 @@ export class RpgServerEngine {
|
|
|
347
377
|
currentPlayer._socket.emit(eventName, data)
|
|
348
378
|
}
|
|
349
379
|
|
|
350
|
-
private
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
380
|
+
private getPlayerBySession(session: string): RpgPlayer | null {
|
|
381
|
+
const users = this.world.getUsers<RpgPlayer>()
|
|
382
|
+
for (let userId in users) {
|
|
383
|
+
const user = users[userId]
|
|
384
|
+
if (user.session === session) {
|
|
385
|
+
return user
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return null
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
private onPlayerConnected(socket, playerId: string) {
|
|
392
|
+
const existingUser = this.world.getUser<RpgPlayer>(playerId, false)
|
|
393
|
+
|
|
394
|
+
this.world.connectUser(socket, playerId)
|
|
395
|
+
|
|
396
|
+
let player: RpgPlayer
|
|
397
|
+
|
|
398
|
+
if (!existingUser) {
|
|
399
|
+
const { token } = socket.handshake.auth
|
|
400
|
+
player = new RpgPlayer(playerId)
|
|
401
|
+
player.session = token
|
|
402
|
+
|
|
403
|
+
this.world.setUser(player, socket)
|
|
404
|
+
|
|
405
|
+
player._init()
|
|
406
|
+
|
|
407
|
+
if (!token) {
|
|
408
|
+
const newToken = Utils.generateUID() + '-' + Utils.generateUID() + '-' + Utils.generateUID()
|
|
409
|
+
player.session = newToken
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (!token) {
|
|
413
|
+
player.execMethod('onConnected')
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
RpgPlugin.emit(HookServer.ScalabilityPlayerConnected, player)
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
player = existingUser
|
|
421
|
+
if (player.map) {
|
|
422
|
+
player.emit('preLoadScene', {
|
|
423
|
+
reconnect: true,
|
|
424
|
+
id: player.map
|
|
425
|
+
})
|
|
426
|
+
player.emitSceneMap()
|
|
427
|
+
this.world.joinRoom(player.map, playerId)
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
socket.emit('playerJoined', { playerId, session: player.session })
|
|
355
432
|
|
|
356
433
|
socket.on('move', (data: { input: string[], frame: number }) => {
|
|
357
434
|
if (!data?.input) return
|
|
@@ -368,28 +445,6 @@ export class RpgServerEngine {
|
|
|
368
445
|
}
|
|
369
446
|
})
|
|
370
447
|
|
|
371
|
-
socket.on('disconnect', () => {
|
|
372
|
-
this.onPlayerDisconnected(playerId)
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
this.world.setUser(player, socket)
|
|
376
|
-
|
|
377
|
-
player.server = this
|
|
378
|
-
player._init()
|
|
379
|
-
|
|
380
|
-
if (!token) {
|
|
381
|
-
const newToken = Utils.generateUID() + '-' + Utils.generateUID() + '-' + Utils.generateUID()
|
|
382
|
-
player.session = newToken
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
socket.emit('playerJoined', { playerId, session: player.session })
|
|
386
|
-
|
|
387
|
-
if (!token) {
|
|
388
|
-
player.execMethod('onConnected')
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
RpgPlugin.emit(HookServer.ScalabilityPlayerConnected, player)
|
|
392
|
-
}
|
|
393
448
|
}
|
|
394
449
|
|
|
395
450
|
private onPlayerDisconnected(playerId: string) {
|