@rpgjs/server 3.3.2 → 4.0.0-beta.3

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.
Files changed (152) hide show
  1. package/LICENSE +19 -0
  2. package/lib/Game/Map.d.ts +58 -5
  3. package/lib/Game/Map.js +185 -80
  4. package/lib/Game/Map.js.map +1 -1
  5. package/lib/Game/WorldMaps.d.ts +3 -2
  6. package/lib/Game/WorldMaps.js +6 -11
  7. package/lib/Game/WorldMaps.js.map +1 -1
  8. package/lib/Gui/DialogGui.d.ts +1 -1
  9. package/lib/Gui/DialogGui.js +12 -13
  10. package/lib/Gui/DialogGui.js.map +1 -1
  11. package/lib/Gui/Gui.js +2 -6
  12. package/lib/Gui/Gui.js.map +1 -1
  13. package/lib/Gui/MenuGui.js +4 -8
  14. package/lib/Gui/MenuGui.js.map +1 -1
  15. package/lib/Gui/NotificationGui.js +4 -8
  16. package/lib/Gui/NotificationGui.js.map +1 -1
  17. package/lib/Gui/ShopGui.js +4 -8
  18. package/lib/Gui/ShopGui.js.map +1 -1
  19. package/lib/Gui/index.js +6 -13
  20. package/lib/Gui/index.js.map +1 -1
  21. package/lib/Interfaces/Gui.js +1 -2
  22. package/lib/Interfaces/StateStore.js +1 -2
  23. package/lib/MatchMaker.js +28 -46
  24. package/lib/MatchMaker.js.map +1 -1
  25. package/lib/Monitor/index.js +3 -5
  26. package/lib/Monitor/index.js.map +1 -1
  27. package/lib/Player/BattleManager.js +17 -16
  28. package/lib/Player/BattleManager.js.map +1 -1
  29. package/lib/Player/ClassManager.js +6 -10
  30. package/lib/Player/ClassManager.js.map +1 -1
  31. package/lib/Player/ComponentManager.d.ts +4 -4
  32. package/lib/Player/ComponentManager.js +37 -24
  33. package/lib/Player/ComponentManager.js.map +1 -1
  34. package/lib/Player/EffectManager.js +8 -12
  35. package/lib/Player/EffectManager.js.map +1 -1
  36. package/lib/Player/ElementManager.js +5 -9
  37. package/lib/Player/ElementManager.js.map +1 -1
  38. package/lib/Player/GoldManager.js +1 -5
  39. package/lib/Player/GoldManager.js.map +1 -1
  40. package/lib/Player/GuiManager.js +17 -15
  41. package/lib/Player/GuiManager.js.map +1 -1
  42. package/lib/Player/ItemFixture.js +1 -5
  43. package/lib/Player/ItemFixture.js.map +1 -1
  44. package/lib/Player/ItemManager.d.ts +3 -3
  45. package/lib/Player/ItemManager.js +29 -31
  46. package/lib/Player/ItemManager.js.map +1 -1
  47. package/lib/Player/MoveManager.d.ts +7 -6
  48. package/lib/Player/MoveManager.js +67 -74
  49. package/lib/Player/MoveManager.js.map +1 -1
  50. package/lib/Player/ParameterManager.js +10 -14
  51. package/lib/Player/ParameterManager.js.map +1 -1
  52. package/lib/Player/Player.d.ts +7 -1
  53. package/lib/Player/Player.js +193 -191
  54. package/lib/Player/Player.js.map +1 -1
  55. package/lib/Player/SkillManager.js +18 -22
  56. package/lib/Player/SkillManager.js.map +1 -1
  57. package/lib/Player/StateManager.js +9 -13
  58. package/lib/Player/StateManager.js.map +1 -1
  59. package/lib/Player/VariableManager.js +1 -5
  60. package/lib/Player/VariableManager.js.map +1 -1
  61. package/lib/Query.d.ts +2 -1
  62. package/lib/Query.js +19 -15
  63. package/lib/Query.js.map +1 -1
  64. package/lib/RpgServer.d.ts +11 -3
  65. package/lib/RpgServer.js +1 -2
  66. package/lib/Scenes/Map.d.ts +27 -4
  67. package/lib/Scenes/Map.js +117 -122
  68. package/lib/Scenes/Map.js.map +1 -1
  69. package/lib/decorators/event.js +4 -7
  70. package/lib/decorators/event.js.map +1 -1
  71. package/lib/decorators/map.d.ts +1 -1
  72. package/lib/decorators/map.js +5 -9
  73. package/lib/decorators/map.js.map +1 -1
  74. package/lib/entry-point.js +59 -65
  75. package/lib/entry-point.js.map +1 -1
  76. package/lib/express/api.d.ts +3 -0
  77. package/lib/express/api.js +105 -0
  78. package/lib/express/api.js.map +1 -0
  79. package/lib/express/errors/NotAuthorized.d.ts +4 -0
  80. package/lib/express/errors/NotAuthorized.js +7 -0
  81. package/lib/express/errors/NotAuthorized.js.map +1 -0
  82. package/lib/express/errors/NotFound.d.ts +4 -0
  83. package/lib/express/errors/NotFound.js +7 -0
  84. package/lib/express/errors/NotFound.js.map +1 -0
  85. package/lib/express/server.js +20 -5
  86. package/lib/express/server.js.map +1 -1
  87. package/lib/index.js +15 -68
  88. package/lib/index.js.map +1 -1
  89. package/lib/logs/index.js +5 -11
  90. package/lib/logs/index.js.map +1 -1
  91. package/lib/logs/item.js +11 -15
  92. package/lib/logs/item.js.map +1 -1
  93. package/lib/logs/log.js +1 -5
  94. package/lib/logs/log.js.map +1 -1
  95. package/lib/logs/skill.js +6 -10
  96. package/lib/logs/skill.js.map +1 -1
  97. package/lib/logs/state.js +5 -9
  98. package/lib/logs/state.js.map +1 -1
  99. package/lib/models/Item.js +1 -2
  100. package/lib/presets/index.js +28 -36
  101. package/lib/presets/index.js.map +1 -1
  102. package/lib/server.d.ts +23 -2
  103. package/lib/server.js +227 -134
  104. package/lib/server.js.map +1 -1
  105. package/package.json +24 -16
  106. package/src/Game/Map.ts +513 -0
  107. package/src/Game/WorldMaps.ts +45 -0
  108. package/src/Gui/DialogGui.ts +67 -0
  109. package/src/Gui/Gui.ts +45 -0
  110. package/src/Gui/MenuGui.ts +26 -0
  111. package/src/Gui/NotificationGui.ts +10 -0
  112. package/src/Gui/ShopGui.ts +43 -0
  113. package/src/Gui/index.ts +13 -0
  114. package/src/Interfaces/Gui.ts +4 -0
  115. package/src/Interfaces/StateStore.ts +5 -0
  116. package/src/MatchMaker.ts +63 -0
  117. package/src/Monitor/index.ts +78 -0
  118. package/src/Player/BattleManager.ts +123 -0
  119. package/src/Player/ClassManager.ts +72 -0
  120. package/src/Player/ComponentManager.ts +538 -0
  121. package/src/Player/EffectManager.ts +94 -0
  122. package/src/Player/ElementManager.ts +142 -0
  123. package/src/Player/GoldManager.ts +26 -0
  124. package/src/Player/GuiManager.ts +308 -0
  125. package/src/Player/ItemFixture.ts +24 -0
  126. package/src/Player/ItemManager.ts +474 -0
  127. package/src/Player/MoveManager.ts +635 -0
  128. package/src/Player/ParameterManager.ts +468 -0
  129. package/src/Player/Player.ts +931 -0
  130. package/src/Player/SkillManager.ts +229 -0
  131. package/src/Player/StateManager.ts +230 -0
  132. package/src/Player/VariableManager.ts +55 -0
  133. package/src/Query.ts +172 -0
  134. package/src/RpgServer.ts +429 -0
  135. package/src/Scenes/Map.ts +302 -0
  136. package/src/decorators/event.ts +57 -0
  137. package/src/decorators/map.ts +223 -0
  138. package/src/entry-point.ts +102 -0
  139. package/src/express/api.ts +118 -0
  140. package/src/express/errors/NotAuthorized.ts +6 -0
  141. package/src/express/errors/NotFound.ts +6 -0
  142. package/src/express/server.ts +93 -0
  143. package/src/index.ts +28 -0
  144. package/src/logs/index.ts +11 -0
  145. package/src/logs/item.ts +31 -0
  146. package/src/logs/log.ts +3 -0
  147. package/src/logs/skill.ts +16 -0
  148. package/src/logs/state.ts +13 -0
  149. package/src/models/Item.ts +11 -0
  150. package/src/presets/index.ts +71 -0
  151. package/src/server.ts +394 -0
  152. package/tsconfig.json +27 -0
@@ -0,0 +1,118 @@
1
+ import { Router } from 'express'
2
+ import { RpgServerEngine } from '../server'
3
+ import { Query } from '../Query'
4
+ import { RpgMap } from '../Game/Map'
5
+ import { NotAuthorized } from './errors/NotAuthorized'
6
+ import { NotFound } from './errors/NotFound'
7
+
8
+ type ApiConfig = {
9
+ enabled?: boolean,
10
+ authSecret?: string,
11
+ }
12
+
13
+ export function api(rpgServer: RpgServerEngine): Router {
14
+ const router = new Router()
15
+
16
+ router.use((req, res, next) => {
17
+ try {
18
+ const apiConfig: ApiConfig = rpgServer.globalConfig.api || {}
19
+ const enabled = apiConfig.enabled === undefined ? false : apiConfig.enabled
20
+ const { dev } = req.query
21
+ if (process.env.NODE_ENV === 'development' && dev) {
22
+ return next()
23
+ }
24
+ if (!enabled) {
25
+ throw new NotAuthorized('API disabled')
26
+ }
27
+ const authSecret = apiConfig.authSecret
28
+ if (!authSecret) {
29
+ throw new NotAuthorized('API secret not defined')
30
+ }
31
+ // headers
32
+ const authHeader = req.headers.authorization
33
+ if (!authHeader) {
34
+ throw new NotAuthorized('Authorization header not defined')
35
+ }
36
+ const [type, token] = authHeader.split(' ')
37
+ if (type !== 'Bearer') {
38
+ throw new NotAuthorized('Authorization type not supported')
39
+ }
40
+ if (token !== authSecret) {
41
+ throw new NotAuthorized('Authorization token not valid')
42
+ }
43
+ next()
44
+ }
45
+ catch (err) {
46
+ next(err)
47
+ }
48
+ })
49
+
50
+ router.get('/players', (req, res) => {
51
+ const players = Query.getPlayers()
52
+ res.json(players)
53
+ })
54
+
55
+ router.put('/maps', (req, res, next) => {
56
+ try {
57
+ const { mapId, data, mapFile } = req.body
58
+ const maps = rpgServer.sceneMap.getMaps()
59
+ const findMap = maps.find(map => {
60
+ if (mapId) {
61
+ return map.id === mapId
62
+ }
63
+ else if (mapFile) {
64
+ return map.file === mapFile
65
+ }
66
+ })
67
+ if (findMap) {
68
+ const map = Query.getRoom<RpgMap>(findMap.id as string)
69
+ map.update(data)
70
+ res.json({ success: true })
71
+ }
72
+ else {
73
+ throw new NotFound('Map not found')
74
+ }
75
+ }
76
+ catch (err) {
77
+ next(err)
78
+ }
79
+ })
80
+
81
+ router.put('/tilesets', async (req, res, next) => {
82
+ try {
83
+ const { data, tilesetId } = req.body
84
+ const maps = Query.getRooms<RpgMap>()
85
+ for (let [id, map] of maps) {
86
+ const findTileset = map.tilesets.find(tileset => tileset.name === tilesetId)
87
+ if (findTileset) {
88
+ await map.updateTileset(data)
89
+ }
90
+ }
91
+ res.json({ success: true })
92
+ }
93
+ catch (err) {
94
+ next(err)
95
+ }
96
+ })
97
+
98
+ router.put('/worlds', (req, res, next) => {
99
+ try {
100
+ const { worldId, data } = req.body
101
+ const sceneMap = rpgServer.sceneMap
102
+ const world = sceneMap.getWorldMaps(worldId)
103
+ if (world) {
104
+ sceneMap.deleteWorldMaps(worldId)
105
+ sceneMap.createDynamicWorldMaps(data)
106
+ res.json({ success: true })
107
+ }
108
+ else {
109
+ throw new NotFound('World not found')
110
+ }
111
+ }
112
+ catch (err) {
113
+ next(err)
114
+ }
115
+ })
116
+
117
+ return router
118
+ }
@@ -0,0 +1,6 @@
1
+ export class NotAuthorized extends Error {
2
+ status = 401
3
+ constructor(message?: string) {
4
+ super(message || 'Not authorized')
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ export class NotFound extends Error {
2
+ status = 404
3
+ constructor(message?: string) {
4
+ super(message || 'Not found')
5
+ }
6
+ }
@@ -0,0 +1,93 @@
1
+ import http from 'http'
2
+ import path from 'path'
3
+ import express from 'express'
4
+ import { Server } from 'socket.io'
5
+ import entryPoint from '../entry-point'
6
+ import PrettyError from 'pretty-error'
7
+ import { ModuleType } from '@rpgjs/common'
8
+ import { RpgServerEngine } from '../server'
9
+ import { api } from './api'
10
+ import { Query } from '../Query'
11
+
12
+ type ExpressServerOptions = {
13
+ basePath: string,
14
+ globalConfig?: any,
15
+ }
16
+
17
+ export function expressServer(modules: ModuleType[], options: ExpressServerOptions): Promise<{
18
+ app: express.Express,
19
+ server: http.Server,
20
+ game: RpgServerEngine
21
+ }> {
22
+ return new Promise((resolve, reject) => {
23
+ const dirname = options.basePath
24
+ const PORT = process.env.PORT || 3000
25
+ const pe = new PrettyError()
26
+ const app = express()
27
+ const server = http.createServer(app)
28
+ const io = new Server(server, {
29
+ maxHttpBufferSize: 1e10,
30
+ cors: {
31
+ origin: "*",
32
+ methods: ["GET", "POST"]
33
+ }
34
+ })
35
+
36
+ // @ts-ignore
37
+ const isBuilt = !!import.meta.env.VITE_BUILT
38
+
39
+ // @ts-ignore
40
+ const hasStatic = process.env.STATIC_DIRECTORY_ENABLED
41
+ const staticDirectory = isBuilt ? '' : 'dist'
42
+ // @ts-ignore
43
+ const staticEnabled = (isBuilt && hasStatic === undefined) || hasStatic === 'true'
44
+
45
+ if (!isBuilt) {
46
+ app.use(express.json({
47
+ // TODO
48
+ limit: '50mb'
49
+ }))
50
+ }
51
+
52
+ if (staticEnabled) {
53
+ app.use('/', express.static(path.join(dirname, '..', staticDirectory, 'client')))
54
+ }
55
+
56
+ async function start() {
57
+ const rpgGame = await entryPoint(modules, { io, ...options })
58
+ rpgGame.app = app
59
+ rpgGame.start()
60
+ app.use('/api', api(rpgGame))
61
+ app.use((err: any, req: any, res: any, next: any) => {
62
+ const status = err.status || 500
63
+ res.status(status).json({ error: err.message })
64
+ })
65
+ resolve({
66
+ app,
67
+ server,
68
+ game: rpgGame
69
+ })
70
+ }
71
+
72
+ // @ts-ignore
73
+ const serverPort = (import.meta.env.VITE_SERVER_URL || '').split(':')[1] || PORT
74
+ server.listen(serverPort, start)
75
+
76
+ process.on('uncaughtException', function (error) {
77
+ console.log(pe.render(error))
78
+ })
79
+
80
+ process.on('unhandledRejection', function (reason: any) {
81
+ console.log(pe.render(reason))
82
+ })
83
+
84
+ if (import.meta['hot']) {
85
+ import.meta['hot'].on("vite:beforeFullReload", () => {
86
+ server.close()
87
+ Query.getPlayers().forEach(player => {
88
+ player.gameReload()
89
+ })
90
+ });
91
+ }
92
+ })
93
+ }
package/src/index.ts ADDED
@@ -0,0 +1,28 @@
1
+ export { default as entryPoint } from './entry-point'
2
+ export {
3
+ Direction,
4
+ Input,
5
+ Control,
6
+ RpgPlugin,
7
+ HookServer,
8
+ HookClient,
9
+ RpgModule,
10
+ RpgShape,
11
+ ShapePositioning,
12
+ AbstractObject
13
+ } from '@rpgjs/common'
14
+ export { RpgServer, RpgPlayerHooks, RpgServerEngineHooks } from './RpgServer'
15
+ export { EventData } from './decorators/event'
16
+ export { MapData } from './decorators/map'
17
+ export { RpgPlayer, RpgEvent, EventMode } from './Player/Player'
18
+ export { RpgMap } from './Game/Map'
19
+ export { RpgWorldMaps } from './Game/WorldMaps'
20
+ export { Query, Query as RpgWorld } from './Query'
21
+ export { default as Monitor } from './Monitor'
22
+ export * as Presets from './presets'
23
+ export { Move, Frequency, Speed } from './Player/MoveManager'
24
+ export { RpgServerEngine } from './server'
25
+ export { SceneMap as RpgSceneMap, RpgClassMap } from './Scenes/Map'
26
+ export { RpgMatchMaker } from './MatchMaker'
27
+ export { IStoreState } from './Interfaces/StateStore'
28
+ export { Components } from './Player/ComponentManager'
@@ -0,0 +1,11 @@
1
+ import { ItemLog } from './item'
2
+ import { SkillLog } from './skill'
3
+ import { StateLog } from './state'
4
+ import { Log } from './log'
5
+
6
+ export {
7
+ ItemLog,
8
+ SkillLog,
9
+ StateLog,
10
+ Log
11
+ }
@@ -0,0 +1,31 @@
1
+ import { Log } from './log'
2
+
3
+ export class ItemLog {
4
+ static notInInventory(itemClass) {
5
+ return new Log('ITEM_NOT_INVENTORY', `The item ${itemClass.name} is not in inventory`)
6
+ }
7
+ static notUseItem(itemClass) {
8
+ return new Log('NOT_USE_ITEM', `The player cannot use the ${itemClass.name} item.`)
9
+ }
10
+ static chanceToUseFailed(itemClass) {
11
+ return new Log('USE_CHANCE_ITEM_FAILED', `Chance to use the ${itemClass.name} item has failed`)
12
+ }
13
+ static invalidToEquiped(itemClass) {
14
+ return new Log('INVALID_ITEM_TO_EQUIP', `The item ${itemClass.name} is not a weapon or armor`)
15
+ }
16
+ static isAlreadyEquiped(itemClass) {
17
+ return new Log('ITEM_ALREADY_EQUIPED', `The item ${itemClass.name} is already equiped`)
18
+ }
19
+ static haveNotPrice(itemClass) {
20
+ return new Log('NOT_PRICE', `Define a price > 0 to buy ${itemClass.name}`)
21
+ }
22
+ static notEnoughGold(itemClass, nb) {
23
+ return new Log('NOT_ENOUGH_GOLD', `not enough gold to buy ${nb} ${itemClass.name}`)
24
+ }
25
+ static tooManyToSell(itemClass, nbToSell, nb) {
26
+ return new Log('TOO_MANY_ITEM_TO_SELL', `Too many items to sell: ${nbToSell} ${itemClass.name}, only ${nb} in inventory`)
27
+ }
28
+ static restriction(itemClass) {
29
+ return new Log('RESTRICTION_ITEM', `A state blocks the use of the ${itemClass.name} skill`)
30
+ }
31
+ }
@@ -0,0 +1,3 @@
1
+ export class Log {
2
+ constructor(private id: string, private msg: string) {}
3
+ }
@@ -0,0 +1,16 @@
1
+ import { Log } from './log'
2
+
3
+ export class SkillLog {
4
+ static notLearned(skillClass) {
5
+ return new Log('SKILL_NOT_LEARNED', `the skill ${skillClass.name} is not learned`)
6
+ }
7
+ static notEnoughSp(skillClass, skillSp, playerSp) {
8
+ return new Log('NOT_ENOUGH_SP', `not enough SP to use ${skillClass.name} skill. ${skillSp} Skill'SP is is greater than ${playerSp} Player'SP`)
9
+ }
10
+ static chanceToUseFailed(skillClass) {
11
+ return new Log('USE_CHANCE_SKILL_FAILED', `Chance to use the ${skillClass.name} skill has failed`)
12
+ }
13
+ static restriction(skillClass) {
14
+ return new Log('RESTRICTION_SKILL', `A state blocks the use of the ${skillClass.name} skill`)
15
+ }
16
+ }
@@ -0,0 +1,13 @@
1
+ import { Log } from './log'
2
+
3
+ export class StateLog {
4
+ static addFailed(stateClass) {
5
+ return new Log('ADD_STATE_FAILED', `Adding the ${stateClass.name} state has failed`)
6
+ }
7
+ static removeFailed(stateClass) {
8
+ return new Log('REMOVE_STATE_FAILED', `Removing the ${stateClass.name} state has failed`)
9
+ }
10
+ static notApplied(stateClass) {
11
+ return new Log('STATE_NOT_APPLIED', `State ${stateClass.name} does not exist`)
12
+ }
13
+ }
@@ -0,0 +1,11 @@
1
+ import { ItemOptions } from '@rpgjs/database'
2
+ import { RpgPlayer } from '../Player/Player';
3
+
4
+ export interface ItemModel extends ItemOptions {
5
+ id: string
6
+ equipped?: boolean
7
+ onUseFailed?: (player: RpgPlayer) => {}
8
+ onUse?: (player: RpgPlayer) => {}
9
+ onAdd?: (player: RpgPlayer) => {}
10
+ onRemove?: (player: RpgPlayer) => {}
11
+ }
@@ -0,0 +1,71 @@
1
+ import { Utils } from '@rpgjs/common'
2
+
3
+ const { random } = Utils
4
+
5
+ export const MAXHP: string = 'maxHp'
6
+ export const MAXSP: string = 'maxSp'
7
+ export const ATK: string = 'atk'
8
+ export const PDEF: string = 'pdef'
9
+ export const SDEF: string = 'sdef'
10
+ export const STR: string = 'str'
11
+ export const AGI: string = 'agi'
12
+ export const INT: string = 'int'
13
+ export const DEX: string = 'dex'
14
+
15
+ export const MAXHP_CURVE = {
16
+ start: 741,
17
+ end: 7467
18
+ }
19
+ export const MAXSP_CURVE = {
20
+ start: 534,
21
+ end: 5500
22
+ }
23
+ export const STR_CURVE = {
24
+ start: 67,
25
+ end: 635
26
+ }
27
+ export const AGI_CURVE = {
28
+ start: 58,
29
+ end: 582
30
+ }
31
+ export const INT_CURVE = {
32
+ start: 36,
33
+ end: 7318
34
+ }
35
+ export const DEX_CURVE = {
36
+ start: 54,
37
+ end: 564
38
+ }
39
+
40
+ export const DAMAGE_CRITICAL = function(damage, a, b) {
41
+ if (random(0, 100) < 4 * a[DEX] / b[AGI]) {
42
+ damage *= 2
43
+ }
44
+ return damage
45
+ }
46
+
47
+ export const DAMAGE_PHYSIC = function(a, b) {
48
+ let damage = Math.round((a[ATK] - b[PDEF] / 2) * ((20 + a[STR]) / 20))
49
+ if (damage < 0) damage = 0
50
+ return damage
51
+ }
52
+
53
+ export const DAMAGE_GUARD = function(damage) {
54
+ return damage / 2
55
+ }
56
+
57
+ export const COEFFICIENT_ELEMENTS = function(a, b, bDef) {
58
+ return ((a.rate + 1) * (b.rate + 1)) / (bDef.rate == 0 ? bDef.rate * 4 : 1)
59
+ }
60
+
61
+ export const DAMAGE_SKILL = function(a, b, skill) {
62
+ let power = skill.power + (a[ATK] * (skill.coefficient[ATK] || 0))
63
+ if (power > 0) {
64
+ power -= b[PDEF] * (skill.coefficient[PDEF] || 0) / 2
65
+ power -= b[SDEF] * (skill.coefficient[SDEF] || 0) / 2
66
+ power = Math.max(power, 0)
67
+ }
68
+ let rate = 20;
69
+ [STR, DEX, AGI, INT].forEach(val => rate += a[val] * (skill.coefficient[val] || 0))
70
+ return Math.round(power * rate / 20)
71
+ }