@rpgjs/client 5.0.0-beta.10 → 5.0.0-beta.12
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 +21 -0
- package/dist/Game/AnimationManager.d.ts +1 -0
- package/dist/Game/AnimationManager.js +3 -0
- package/dist/Game/AnimationManager.js.map +1 -1
- package/dist/Game/ClientVisuals.d.ts +61 -0
- package/dist/Game/ClientVisuals.js +96 -0
- package/dist/Game/ClientVisuals.js.map +1 -0
- package/dist/Game/ClientVisuals.spec.d.ts +1 -0
- package/dist/Game/EventComponentResolver.d.ts +16 -0
- package/dist/Game/EventComponentResolver.js +52 -0
- package/dist/Game/EventComponentResolver.js.map +1 -0
- package/dist/Game/EventComponentResolver.spec.d.ts +1 -0
- package/dist/Game/Map.js +9 -0
- package/dist/Game/Map.js.map +1 -1
- package/dist/Game/Object.js +2 -2
- package/dist/Game/Object.js.map +1 -1
- package/dist/Game/Object.spec.d.ts +1 -0
- package/dist/Game/ProjectileManager.d.ts +98 -0
- package/dist/Game/ProjectileManager.js +196 -0
- package/dist/Game/ProjectileManager.js.map +1 -0
- package/dist/Game/ProjectileManager.spec.d.ts +1 -0
- package/dist/RpgClient.d.ts +117 -13
- package/dist/RpgClientEngine.d.ts +82 -4
- package/dist/RpgClientEngine.js +296 -51
- package/dist/RpgClientEngine.js.map +1 -1
- package/dist/components/animations/fx.ce.js +58 -0
- package/dist/components/animations/fx.ce.js.map +1 -0
- package/dist/components/animations/hit.ce.js.map +1 -1
- package/dist/components/animations/index.d.ts +1 -0
- package/dist/components/animations/index.js +3 -1
- package/dist/components/animations/index.js.map +1 -1
- package/dist/components/character.ce.js +140 -40
- package/dist/components/character.ce.js.map +1 -1
- package/dist/components/dynamics/bar.ce.js +4 -3
- package/dist/components/dynamics/bar.ce.js.map +1 -1
- package/dist/components/dynamics/image.ce.js +2 -1
- package/dist/components/dynamics/image.ce.js.map +1 -1
- package/dist/components/dynamics/shape.ce.js +3 -2
- package/dist/components/dynamics/shape.ce.js.map +1 -1
- package/dist/components/dynamics/text.ce.js +9 -8
- package/dist/components/dynamics/text.ce.js.map +1 -1
- package/dist/components/gui/dialogbox/index.ce.js +3 -2
- package/dist/components/gui/dialogbox/index.ce.js.map +1 -1
- package/dist/components/gui/gameover.ce.js +3 -2
- package/dist/components/gui/gameover.ce.js.map +1 -1
- package/dist/components/gui/hud/hud.ce.js.map +1 -1
- package/dist/components/gui/menu/equip-menu.ce.js +2 -1
- package/dist/components/gui/menu/equip-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/exit-menu.ce.js +2 -1
- package/dist/components/gui/menu/exit-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/items-menu.ce.js +3 -2
- package/dist/components/gui/menu/items-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/main-menu.ce.js +3 -2
- package/dist/components/gui/menu/main-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/options-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/skills-menu.ce.js.map +1 -1
- package/dist/components/gui/mobile/mobile.ce.js.map +1 -1
- package/dist/components/gui/notification/notification.ce.js.map +1 -1
- package/dist/components/gui/save-load.ce.js +2 -1
- package/dist/components/gui/save-load.ce.js.map +1 -1
- package/dist/components/gui/shop/shop.ce.js +3 -2
- package/dist/components/gui/shop/shop.ce.js.map +1 -1
- package/dist/components/gui/title-screen.ce.js +3 -2
- package/dist/components/gui/title-screen.ce.js.map +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +1 -0
- package/dist/components/player-components.ce.js +11 -10
- package/dist/components/player-components.ce.js.map +1 -1
- package/dist/components/prebuilt/hp-bar.ce.js +4 -3
- package/dist/components/prebuilt/hp-bar.ce.js.map +1 -1
- package/dist/components/prebuilt/light-halo.ce.js +2 -1
- package/dist/components/prebuilt/light-halo.ce.js.map +1 -1
- package/dist/components/scenes/canvas.ce.js +12 -4
- package/dist/components/scenes/canvas.ce.js.map +1 -1
- package/dist/components/scenes/draw-map.ce.js +6 -3
- package/dist/components/scenes/draw-map.ce.js.map +1 -1
- package/dist/components/scenes/event-layer.ce.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +10 -5
- package/dist/module.js +18 -0
- package/dist/module.js.map +1 -1
- package/dist/services/actionInput.d.ts +14 -0
- package/dist/services/actionInput.js +59 -0
- package/dist/services/actionInput.js.map +1 -0
- package/dist/services/actionInput.spec.d.ts +1 -0
- package/dist/services/mmorpg-connection.d.ts +5 -0
- package/dist/services/mmorpg-connection.js +50 -0
- package/dist/services/mmorpg-connection.js.map +1 -0
- package/dist/services/mmorpg-connection.spec.d.ts +1 -0
- package/dist/services/mmorpg.d.ts +10 -4
- package/dist/services/mmorpg.js +48 -30
- package/dist/services/mmorpg.js.map +1 -1
- package/dist/services/pointerContext.d.ts +11 -0
- package/dist/services/pointerContext.js +48 -0
- package/dist/services/pointerContext.js.map +1 -0
- package/dist/services/pointerContext.spec.d.ts +1 -0
- package/dist/services/standalone-message.d.ts +1 -0
- package/dist/services/standalone-message.js +9 -0
- package/dist/services/standalone-message.js.map +1 -0
- package/dist/services/standalone.d.ts +3 -1
- package/dist/services/standalone.js +34 -15
- package/dist/services/standalone.js.map +1 -1
- package/dist/services/standalone.spec.d.ts +1 -0
- package/dist/utils/mapId.d.ts +1 -0
- package/dist/utils/mapId.js +6 -0
- package/dist/utils/mapId.js.map +1 -0
- package/package.json +7 -7
- package/src/Game/AnimationManager.ts +4 -0
- package/src/Game/ClientVisuals.spec.ts +56 -0
- package/src/Game/ClientVisuals.ts +184 -0
- package/src/Game/EventComponentResolver.spec.ts +84 -0
- package/src/Game/EventComponentResolver.ts +74 -0
- package/src/Game/Map.ts +10 -0
- package/src/Game/Object.spec.ts +46 -0
- package/src/Game/Object.ts +2 -2
- package/src/Game/ProjectileManager.spec.ts +449 -0
- package/src/Game/ProjectileManager.ts +346 -0
- package/src/RpgClient.ts +130 -15
- package/src/RpgClientEngine.ts +405 -69
- package/src/components/animations/fx.ce +101 -0
- package/src/components/animations/index.ts +4 -2
- package/src/components/character.ce +185 -40
- package/src/components/dynamics/bar.ce +4 -3
- package/src/components/dynamics/image.ce +2 -1
- package/src/components/dynamics/shape.ce +3 -2
- package/src/components/dynamics/text.ce +9 -8
- package/src/components/gui/dialogbox/index.ce +3 -2
- package/src/components/gui/gameover.ce +2 -1
- package/src/components/gui/menu/equip-menu.ce +2 -1
- package/src/components/gui/menu/exit-menu.ce +2 -1
- package/src/components/gui/menu/items-menu.ce +3 -2
- package/src/components/gui/menu/main-menu.ce +2 -1
- package/src/components/gui/save-load.ce +2 -1
- package/src/components/gui/shop/shop.ce +3 -2
- package/src/components/gui/title-screen.ce +2 -1
- package/src/components/index.ts +2 -1
- package/src/components/player-components.ce +11 -10
- package/src/components/prebuilt/hp-bar.ce +4 -3
- package/src/components/prebuilt/light-halo.ce +2 -2
- package/src/components/scenes/canvas.ce +10 -2
- package/src/components/scenes/draw-map.ce +17 -3
- package/src/index.ts +4 -0
- package/src/module.ts +24 -0
- package/src/services/actionInput.spec.ts +155 -0
- package/src/services/actionInput.ts +120 -0
- package/src/services/mmorpg-connection.spec.ts +99 -0
- package/src/services/mmorpg-connection.ts +69 -0
- package/src/services/mmorpg.ts +60 -34
- package/src/services/pointerContext.spec.ts +36 -0
- package/src/services/pointerContext.ts +84 -0
- package/src/services/standalone-message.ts +7 -0
- package/src/services/standalone.spec.ts +34 -0
- package/src/services/standalone.ts +42 -12
- package/src/utils/mapId.ts +2 -0
package/dist/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","names":[],"sources":["../src/module.ts"],"sourcesContent":["import { findModules, provideModules } from \"@rpgjs/common\";\nimport { FactoryProvider } from \"@signe/di\";\nimport { RpgClientEngine } from \"./RpgClientEngine\";\nimport { RpgClient } from \"./RpgClient\";\nimport { inject } from \"@signe/di\";\nimport { RpgGui } from \"./Gui/Gui\";\nimport { getSoundMetadata } from \"./Sound\";\n\n/**\n * Type for client modules that can be either:\n * - An object implementing RpgClient interface\n * - A class decorated with @RpgModule decorator\n */\nexport type RpgClientModule = RpgClient | (new () => any);\n\n/**\n * Provides client modules configuration to Dependency Injection\n * \n * This function accepts an array of client modules that can be either:\n * - Objects implementing the RpgClient interface\n * - Classes decorated with the @RpgModule decorator (which will be instantiated)\n * \n * @param modules - Array of client modules (objects or classes)\n * @returns FactoryProvider configuration for DI\n * @example\n * ```ts\n * // Using an object\n * provideClientModules([\n * {\n * engine: {\n * onConnected(engine) {\n * console.log('Client connected')\n * }\n * }\n * }\n * ])\n * \n * // Using a decorated class\n * @RpgModule<RpgClient>({\n * engine: {\n * onStart(engine) {\n * console.log('Client started')\n * }\n * }\n * })\n * class MyClientModule {}\n * \n * provideClientModules([MyClientModule])\n * ```\n */\nexport function provideClientModules(modules: RpgClientModule[]): FactoryProvider {\n return provideModules(modules, \"client\", (modules, context) => {\n const mainModuleClient = findModules(context, 'Client')\n modules = [...mainModuleClient, ...modules]\n modules = modules.map((module) => {\n // If module is a class (constructor function), instantiate it\n // The RpgModule decorator adds properties to the prototype, which will be accessible via the instance\n if (typeof module === 'function') {\n const instance = new module() as any;\n // Copy all enumerable properties (including from prototype) to a plain object\n const moduleObj: any = {};\n for (const key in instance) {\n moduleObj[key] = instance[key];\n }\n module = moduleObj;\n }\n if ('client' in module) {\n module = module.client as any;\n }\n if (module.spritesheets) {\n const spritesheets = [...module.spritesheets];\n module.spritesheets = {\n load: (engine: RpgClientEngine) => {\n spritesheets.forEach((spritesheet) => {\n engine.addSpriteSheet(spritesheet);\n });\n },\n };\n }\n if (module.spritesheetResolver) {\n const resolver = module.spritesheetResolver;\n module.spritesheetResolver = {\n load: (engine: RpgClientEngine) => {\n engine.setSpritesheetResolver(resolver);\n },\n };\n }\n if (module.sounds) {\n const sounds = [...module.sounds];\n module.sounds = {\n load: (engine: RpgClientEngine) => {\n sounds.forEach((sound) => {\n // Check if it's a class decorated with @Sound\n if (typeof sound === 'function' || (sound && sound.constructor && sound.constructor !== Object)) {\n const metadata = getSoundMetadata(sound);\n if (metadata) {\n // Handle single sound\n if (metadata.id && metadata.sound) {\n engine.addSound({\n id: metadata.id,\n src: metadata.sound,\n loop: metadata.loop,\n volume: metadata.volume,\n });\n }\n // Handle multiple sounds\n if (metadata.sounds) {\n Object.entries(metadata.sounds).forEach(([soundId, soundSrc]) => {\n engine.addSound({\n id: soundId,\n src: soundSrc,\n loop: metadata.loop,\n volume: metadata.volume,\n });\n });\n }\n } else {\n // Not a decorated class, treat as regular sound object\n engine.addSound(sound);\n }\n } else {\n // Regular sound object\n engine.addSound(sound);\n }\n });\n },\n };\n }\n if (module.soundResolver) {\n const resolver = module.soundResolver;\n module.soundResolver = {\n load: (engine: RpgClientEngine) => {\n engine.setSoundResolver(resolver);\n },\n };\n }\n if (module.gui) {\n const gui = [...module.gui];\n module.gui = {\n load: (engine: RpgClientEngine) => {\n const guiService = inject(engine.context, RpgGui) as RpgGui;\n gui.forEach((gui) => {\n guiService.add(gui);\n });\n },\n };\n }\n if (module.componentAnimations) {\n const componentAnimations = [...module.componentAnimations];\n module.componentAnimations = {\n load: (engine: RpgClientEngine) => {\n componentAnimations.forEach((componentAnimation) => {\n engine.addComponentAnimation(componentAnimation);\n });\n },\n };\n }\n if (module.transitions) {\n const transitions = [...module.transitions];\n module.transitions = {\n load: (engine: RpgClientEngine) => {\n const guiService = inject(engine.context, RpgGui) as RpgGui;\n transitions.forEach((transition) => {\n guiService.add({\n name: transition.id,\n component: transition.component,\n data: transition.props || {}\n });\n });\n },\n };\n }\n if (module.particles) {\n const particles = [...module.particles];\n module.particles = {\n load: (engine: RpgClientEngine) => {\n particles.forEach((particle) => {\n engine.addParticle(particle);\n });\n },\n };\n }\n if (module.sprite) {\n const sprite = {...module.sprite};\n module.sprite = {\n ...sprite,\n load: (engine: RpgClientEngine) => {\n if (sprite.componentsBehind) {\n sprite.componentsBehind.forEach((component) => {\n engine.addSpriteComponentBehind(component);\n });\n }\n if (sprite.componentsInFront) {\n sprite.componentsInFront.forEach((component) => {\n engine.addSpriteComponentInFront(component);\n });\n }\n if (sprite.components) {\n Object.entries(sprite.components).forEach(([id, component]) => {\n engine.registerSpriteComponent(id, component);\n });\n }\n },\n };\n }\n return module;\n });\n return modules\n });\n}\n\nexport const GlobalConfigToken = \"GlobalConfigToken\";\n\nexport function provideGlobalConfig(config: any) {\n return {\n provide: GlobalConfigToken,\n useValue: config ?? {},\n };\n}\n\nexport function provideClientGlobalConfig(config: any = {}) {\n if (!config.keyboardControls) {\n config.keyboardControls = {\n up: 'up',\n down: 'down',\n left: 'left',\n right: 'right',\n action: 'space',\n escape: 'escape'\n }\n }\n return provideGlobalConfig(config)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"module.js","names":[],"sources":["../src/module.ts"],"sourcesContent":["import { findModules, provideModules } from \"@rpgjs/common\";\nimport { FactoryProvider } from \"@signe/di\";\nimport { RpgClientEngine } from \"./RpgClientEngine\";\nimport { RpgClient } from \"./RpgClient\";\nimport { inject } from \"@signe/di\";\nimport { RpgGui } from \"./Gui/Gui\";\nimport { getSoundMetadata } from \"./Sound\";\n\n/**\n * Type for client modules that can be either:\n * - An object implementing RpgClient interface\n * - A class decorated with @RpgModule decorator\n */\nexport type RpgClientModule = RpgClient | (new () => any);\n\n/**\n * Provides client modules configuration to Dependency Injection\n * \n * This function accepts an array of client modules that can be either:\n * - Objects implementing the RpgClient interface\n * - Classes decorated with the @RpgModule decorator (which will be instantiated)\n * \n * @param modules - Array of client modules (objects or classes)\n * @returns FactoryProvider configuration for DI\n * @example\n * ```ts\n * // Using an object\n * provideClientModules([\n * {\n * engine: {\n * onConnected(engine) {\n * console.log('Client connected')\n * }\n * }\n * }\n * ])\n * \n * // Using a decorated class\n * @RpgModule<RpgClient>({\n * engine: {\n * onStart(engine) {\n * console.log('Client started')\n * }\n * }\n * })\n * class MyClientModule {}\n * \n * provideClientModules([MyClientModule])\n * ```\n */\nexport function provideClientModules(modules: RpgClientModule[]): FactoryProvider {\n return provideModules(modules, \"client\", (modules, context) => {\n const mainModuleClient = findModules(context, 'Client')\n modules = [...mainModuleClient, ...modules]\n modules = modules.map((module) => {\n // If module is a class (constructor function), instantiate it\n // The RpgModule decorator adds properties to the prototype, which will be accessible via the instance\n if (typeof module === 'function') {\n const instance = new module() as any;\n // Copy all enumerable properties (including from prototype) to a plain object\n const moduleObj: any = {};\n for (const key in instance) {\n moduleObj[key] = instance[key];\n }\n module = moduleObj;\n }\n if ('client' in module) {\n module = module.client as any;\n }\n if (module.spritesheets) {\n const spritesheets = [...module.spritesheets];\n module.spritesheets = {\n load: (engine: RpgClientEngine) => {\n spritesheets.forEach((spritesheet) => {\n engine.addSpriteSheet(spritesheet);\n });\n },\n };\n }\n if (module.spritesheetResolver) {\n const resolver = module.spritesheetResolver;\n module.spritesheetResolver = {\n load: (engine: RpgClientEngine) => {\n engine.setSpritesheetResolver(resolver);\n },\n };\n }\n if (module.sounds) {\n const sounds = [...module.sounds];\n module.sounds = {\n load: (engine: RpgClientEngine) => {\n sounds.forEach((sound) => {\n // Check if it's a class decorated with @Sound\n if (typeof sound === 'function' || (sound && sound.constructor && sound.constructor !== Object)) {\n const metadata = getSoundMetadata(sound);\n if (metadata) {\n // Handle single sound\n if (metadata.id && metadata.sound) {\n engine.addSound({\n id: metadata.id,\n src: metadata.sound,\n loop: metadata.loop,\n volume: metadata.volume,\n });\n }\n // Handle multiple sounds\n if (metadata.sounds) {\n Object.entries(metadata.sounds).forEach(([soundId, soundSrc]) => {\n engine.addSound({\n id: soundId,\n src: soundSrc,\n loop: metadata.loop,\n volume: metadata.volume,\n });\n });\n }\n } else {\n // Not a decorated class, treat as regular sound object\n engine.addSound(sound);\n }\n } else {\n // Regular sound object\n engine.addSound(sound);\n }\n });\n },\n };\n }\n if (module.soundResolver) {\n const resolver = module.soundResolver;\n module.soundResolver = {\n load: (engine: RpgClientEngine) => {\n engine.setSoundResolver(resolver);\n },\n };\n }\n if (module.gui) {\n const gui = [...module.gui];\n module.gui = {\n load: (engine: RpgClientEngine) => {\n const guiService = inject(engine.context, RpgGui) as RpgGui;\n gui.forEach((gui) => {\n guiService.add(gui);\n });\n },\n };\n }\n if (module.componentAnimations) {\n const componentAnimations = [...module.componentAnimations];\n module.componentAnimations = {\n load: (engine: RpgClientEngine) => {\n componentAnimations.forEach((componentAnimation) => {\n engine.addComponentAnimation(componentAnimation);\n });\n },\n };\n }\n if (module.clientVisuals) {\n const clientVisuals = { ...module.clientVisuals };\n module.clientVisuals = {\n load: (engine: RpgClientEngine) => {\n engine.registerClientVisuals(clientVisuals);\n },\n };\n }\n if (module.projectiles) {\n const projectiles = { ...module.projectiles };\n module.projectiles = {\n ...projectiles,\n load: (engine: RpgClientEngine) => {\n if (projectiles.components) {\n Object.entries(projectiles.components).forEach(([type, component]) => {\n engine.registerProjectileComponent(type, component);\n });\n }\n },\n };\n }\n if (module.transitions) {\n const transitions = [...module.transitions];\n module.transitions = {\n load: (engine: RpgClientEngine) => {\n const guiService = inject(engine.context, RpgGui) as RpgGui;\n transitions.forEach((transition) => {\n guiService.add({\n name: transition.id,\n component: transition.component,\n data: transition.props || {}\n });\n });\n },\n };\n }\n if (module.particles) {\n const particles = [...module.particles];\n module.particles = {\n load: (engine: RpgClientEngine) => {\n particles.forEach((particle) => {\n engine.addParticle(particle);\n });\n },\n };\n }\n if (module.sprite) {\n const sprite = {...module.sprite};\n module.sprite = {\n ...sprite,\n load: (engine: RpgClientEngine) => {\n if (sprite.componentsBehind) {\n sprite.componentsBehind.forEach((component) => {\n engine.addSpriteComponentBehind(component);\n });\n }\n if (sprite.componentsInFront) {\n sprite.componentsInFront.forEach((component) => {\n engine.addSpriteComponentInFront(component);\n });\n }\n if (sprite.components) {\n Object.entries(sprite.components).forEach(([id, component]) => {\n engine.registerSpriteComponent(id, component);\n });\n }\n if (sprite.eventComponent) {\n engine.addEventComponentResolver(sprite.eventComponent);\n }\n },\n };\n }\n return module;\n });\n return modules\n });\n}\n\nexport const GlobalConfigToken = \"GlobalConfigToken\";\n\nexport function provideGlobalConfig(config: any) {\n return {\n provide: GlobalConfigToken,\n useValue: config ?? {},\n };\n}\n\nexport function provideClientGlobalConfig(config: any = {}) {\n if (!config.keyboardControls) {\n config.keyboardControls = {\n up: 'up',\n down: 'down',\n left: 'left',\n right: 'right',\n action: 'space',\n escape: 'escape'\n }\n }\n return provideGlobalConfig(config)\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Direction, RpgActionInput, RpgActionName } from '@rpgjs/common';
|
|
2
|
+
export type KeyboardActionDataResolver<TClient = any, TSprite = any> = (client: TClient, sprite: TSprite) => any;
|
|
3
|
+
export interface KeyboardActionConfig<TClient = any, TSprite = any> {
|
|
4
|
+
bind: any;
|
|
5
|
+
action?: RpgActionName;
|
|
6
|
+
data?: any | KeyboardActionDataResolver<TClient, TSprite>;
|
|
7
|
+
}
|
|
8
|
+
export declare function normalizeActionInput(action: RpgActionName, data?: any): RpgActionInput;
|
|
9
|
+
export declare function normalizeActionInput(action: RpgActionInput): RpgActionInput;
|
|
10
|
+
export declare function isKeyboardActionConfig(value: any): value is KeyboardActionConfig;
|
|
11
|
+
export declare function getKeyboardControlBind(control: any): any;
|
|
12
|
+
export declare function keyboardEventMatchesBind(event: KeyboardEvent, bind: any): boolean;
|
|
13
|
+
export declare function resolveKeyboardActionInput(control: any, client: any, sprite: any, defaultAction?: RpgActionName): RpgActionInput;
|
|
14
|
+
export declare function resolveKeyboardDirectionInput(event: KeyboardEvent, keyboardControls: any): Direction | undefined;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Direction } from "@rpgjs/common";
|
|
2
|
+
//#region src/services/actionInput.ts
|
|
3
|
+
function normalizeActionInput(action, data) {
|
|
4
|
+
if (typeof action === "object") return action;
|
|
5
|
+
return data === void 0 ? { action } : {
|
|
6
|
+
action,
|
|
7
|
+
data
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function isKeyboardActionConfig(value) {
|
|
11
|
+
return value !== null && typeof value === "object" && Object.prototype.hasOwnProperty.call(value, "bind");
|
|
12
|
+
}
|
|
13
|
+
function getKeyboardControlBind(control) {
|
|
14
|
+
return isKeyboardActionConfig(control) ? control.bind : control;
|
|
15
|
+
}
|
|
16
|
+
var KEY_CODE_NAMES = {
|
|
17
|
+
32: "space",
|
|
18
|
+
27: "escape",
|
|
19
|
+
37: "left",
|
|
20
|
+
38: "up",
|
|
21
|
+
39: "right",
|
|
22
|
+
40: "down"
|
|
23
|
+
};
|
|
24
|
+
var normalizeKeyboardName = (value) => {
|
|
25
|
+
if (typeof value !== "string") return void 0;
|
|
26
|
+
const normalized = value.toLowerCase();
|
|
27
|
+
if (normalized === " " || normalized === "spacebar" || normalized === "space") return "space";
|
|
28
|
+
if (normalized.startsWith("arrow")) return normalized.slice(5);
|
|
29
|
+
return normalized;
|
|
30
|
+
};
|
|
31
|
+
function keyboardEventMatchesBind(event, bind) {
|
|
32
|
+
if (Array.isArray(bind)) return bind.some((item) => keyboardEventMatchesBind(event, item));
|
|
33
|
+
if (typeof bind === "number") return event.keyCode === bind;
|
|
34
|
+
const expected = normalizeKeyboardName(bind);
|
|
35
|
+
if (!expected) return false;
|
|
36
|
+
return normalizeKeyboardName(event.key) === expected || normalizeKeyboardName(event.code) === expected || KEY_CODE_NAMES[event.keyCode] === expected;
|
|
37
|
+
}
|
|
38
|
+
function resolveKeyboardActionInput(control, client, sprite, defaultAction = "action") {
|
|
39
|
+
if (!isKeyboardActionConfig(control)) return { action: defaultAction };
|
|
40
|
+
const action = control.action ?? defaultAction;
|
|
41
|
+
const data = typeof control.data === "function" ? control.data(client, sprite) : control.data;
|
|
42
|
+
return data === void 0 ? { action } : {
|
|
43
|
+
action,
|
|
44
|
+
data
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function resolveKeyboardDirectionInput(event, keyboardControls) {
|
|
48
|
+
const directions = [
|
|
49
|
+
[keyboardControls?.up, Direction.Up],
|
|
50
|
+
[keyboardControls?.down, Direction.Down],
|
|
51
|
+
[keyboardControls?.left, Direction.Left],
|
|
52
|
+
[keyboardControls?.right, Direction.Right]
|
|
53
|
+
];
|
|
54
|
+
for (const [control, direction] of directions) if (keyboardEventMatchesBind(event, getKeyboardControlBind(control))) return direction;
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { getKeyboardControlBind, isKeyboardActionConfig, keyboardEventMatchesBind, normalizeActionInput, resolveKeyboardActionInput, resolveKeyboardDirectionInput };
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=actionInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actionInput.js","names":[],"sources":["../../src/services/actionInput.ts"],"sourcesContent":["import { Direction, type RpgActionInput, type RpgActionName } from \"@rpgjs/common\";\n\nexport type KeyboardActionDataResolver<TClient = any, TSprite = any> = (\n client: TClient,\n sprite: TSprite,\n) => any;\n\nexport interface KeyboardActionConfig<TClient = any, TSprite = any> {\n bind: any;\n action?: RpgActionName;\n data?: any | KeyboardActionDataResolver<TClient, TSprite>;\n}\n\nexport function normalizeActionInput(action: RpgActionName, data?: any): RpgActionInput;\nexport function normalizeActionInput(action: RpgActionInput): RpgActionInput;\nexport function normalizeActionInput(action: RpgActionName | RpgActionInput, data?: any): RpgActionInput {\n if (typeof action === \"object\") {\n return action;\n }\n return data === undefined\n ? { action }\n : { action, data };\n}\n\nexport function isKeyboardActionConfig(value: any): value is KeyboardActionConfig {\n return value !== null\n && typeof value === \"object\"\n && Object.prototype.hasOwnProperty.call(value, \"bind\");\n}\n\nexport function getKeyboardControlBind(control: any): any {\n return isKeyboardActionConfig(control) ? control.bind : control;\n}\n\nconst KEY_CODE_NAMES: Record<number, string> = {\n 32: \"space\",\n 27: \"escape\",\n 37: \"left\",\n 38: \"up\",\n 39: \"right\",\n 40: \"down\",\n};\n\nconst normalizeKeyboardName = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const normalized = value.toLowerCase();\n if (\n normalized === \" \" ||\n normalized === \"spacebar\" ||\n normalized === \"space\"\n ) {\n return \"space\";\n }\n if (normalized.startsWith(\"arrow\")) {\n return normalized.slice(\"arrow\".length);\n }\n return normalized;\n};\n\nexport function keyboardEventMatchesBind(\n event: KeyboardEvent,\n bind: any\n): boolean {\n if (Array.isArray(bind)) {\n return bind.some(item => keyboardEventMatchesBind(event, item));\n }\n\n if (typeof bind === \"number\") {\n return event.keyCode === bind;\n }\n\n const expected = normalizeKeyboardName(bind);\n if (!expected) return false;\n\n return (\n normalizeKeyboardName(event.key) === expected ||\n normalizeKeyboardName(event.code) === expected ||\n KEY_CODE_NAMES[event.keyCode] === expected\n );\n}\n\nexport function resolveKeyboardActionInput(\n control: any,\n client: any,\n sprite: any,\n defaultAction: RpgActionName = \"action\",\n): RpgActionInput {\n if (!isKeyboardActionConfig(control)) {\n return { action: defaultAction };\n }\n\n const action = control.action ?? defaultAction;\n const data = typeof control.data === \"function\"\n ? control.data(client, sprite)\n : control.data;\n\n return data === undefined\n ? { action }\n : { action, data };\n}\n\nexport function resolveKeyboardDirectionInput(\n event: KeyboardEvent,\n keyboardControls: any\n): Direction | undefined {\n const directions: Array<[any, Direction]> = [\n [keyboardControls?.up, Direction.Up],\n [keyboardControls?.down, Direction.Down],\n [keyboardControls?.left, Direction.Left],\n [keyboardControls?.right, Direction.Right],\n ];\n\n for (const [control, direction] of directions) {\n if (keyboardEventMatchesBind(event, getKeyboardControlBind(control))) {\n return direction;\n }\n }\n\n return undefined;\n}\n"],"mappings":";;AAeA,SAAgB,qBAAqB,QAAwC,MAA4B;CACvG,IAAI,OAAO,WAAW,UACpB,OAAO;CAET,OAAO,SAAS,KAAA,IACZ,EAAE,OAAO,IACT;EAAE;EAAQ;CAAK;AACrB;AAEA,SAAgB,uBAAuB,OAA2C;CAChF,OAAO,UAAU,QACZ,OAAO,UAAU,YACjB,OAAO,UAAU,eAAe,KAAK,OAAO,MAAM;AACzD;AAEA,SAAgB,uBAAuB,SAAmB;CACxD,OAAO,uBAAuB,OAAO,IAAI,QAAQ,OAAO;AAC1D;AAEA,IAAM,iBAAyC;CAC7C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,IAAM,yBAAyB,UAAuC;CACpE,IAAI,OAAO,UAAU,UAAU,OAAO,KAAA;CACtC,MAAM,aAAa,MAAM,YAAY;CACrC,IACE,eAAe,OACf,eAAe,cACf,eAAe,SAEf,OAAO;CAET,IAAI,WAAW,WAAW,OAAO,GAC/B,OAAO,WAAW,MAAM,CAAc;CAExC,OAAO;AACT;AAEA,SAAgB,yBACd,OACA,MACS;CACT,IAAI,MAAM,QAAQ,IAAI,GACpB,OAAO,KAAK,MAAK,SAAQ,yBAAyB,OAAO,IAAI,CAAC;CAGhE,IAAI,OAAO,SAAS,UAClB,OAAO,MAAM,YAAY;CAG3B,MAAM,WAAW,sBAAsB,IAAI;CAC3C,IAAI,CAAC,UAAU,OAAO;CAEtB,OACE,sBAAsB,MAAM,GAAG,MAAM,YACrC,sBAAsB,MAAM,IAAI,MAAM,YACtC,eAAe,MAAM,aAAa;AAEtC;AAEA,SAAgB,2BACd,SACA,QACA,QACA,gBAA+B,UACf;CAChB,IAAI,CAAC,uBAAuB,OAAO,GACjC,OAAO,EAAE,QAAQ,cAAc;CAGjC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,OAAO,OAAO,QAAQ,SAAS,aACjC,QAAQ,KAAK,QAAQ,MAAM,IAC3B,QAAQ;CAEZ,OAAO,SAAS,KAAA,IACZ,EAAE,OAAO,IACT;EAAE;EAAQ;CAAK;AACrB;AAEA,SAAgB,8BACd,OACA,kBACuB;CACvB,MAAM,aAAsC;EAC1C,CAAC,kBAAkB,IAAI,UAAU,EAAE;EACnC,CAAC,kBAAkB,MAAM,UAAU,IAAI;EACvC,CAAC,kBAAkB,MAAM,UAAU,IAAI;EACvC,CAAC,kBAAkB,OAAO,UAAU,KAAK;CAC3C;CAEA,KAAK,MAAM,CAAC,SAAS,cAAc,YACjC,IAAI,yBAAyB,OAAO,uBAAuB,OAAO,CAAC,GACjE,OAAO;AAKb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function parseSocketMessage(data: any): any;
|
|
2
|
+
export declare function isNativeSocketEvent(event: string): event is "error" | "open" | "close";
|
|
3
|
+
export declare function waitForRpgjsConnected(conn: any, timeoutMs?: number, options?: {
|
|
4
|
+
ignoreCleanClose?: boolean;
|
|
5
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region src/services/mmorpg-connection.ts
|
|
2
|
+
function parseSocketMessage(data) {
|
|
3
|
+
if (typeof data !== "string") return data;
|
|
4
|
+
try {
|
|
5
|
+
return JSON.parse(data);
|
|
6
|
+
} catch {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function isNativeSocketEvent(event) {
|
|
11
|
+
return event === "open" || event === "close" || event === "error";
|
|
12
|
+
}
|
|
13
|
+
function waitForRpgjsConnected(conn, timeoutMs = 1e4, options = {}) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
let timeoutId;
|
|
16
|
+
const cleanup = () => {
|
|
17
|
+
conn.removeEventListener("message", onMessage);
|
|
18
|
+
conn.removeEventListener("close", onClose);
|
|
19
|
+
conn.removeEventListener("error", onError);
|
|
20
|
+
if (timeoutId !== void 0) window.clearTimeout(timeoutId);
|
|
21
|
+
};
|
|
22
|
+
const rejectWith = (error) => {
|
|
23
|
+
cleanup();
|
|
24
|
+
reject(error);
|
|
25
|
+
};
|
|
26
|
+
const onMessage = (event) => {
|
|
27
|
+
if (parseSocketMessage(event.data)?.type !== "connected") return;
|
|
28
|
+
cleanup();
|
|
29
|
+
resolve();
|
|
30
|
+
};
|
|
31
|
+
const onClose = (event) => {
|
|
32
|
+
const rawReason = event.reason;
|
|
33
|
+
if (options.ignoreCleanClose && (event.code === 1e3 || rawReason instanceof Event || typeof rawReason !== "string")) return;
|
|
34
|
+
rejectWith(new Error(typeof rawReason === "string" && rawReason ? rawReason : "WebSocket closed before RPGJS connection was accepted"));
|
|
35
|
+
};
|
|
36
|
+
const onError = (event) => {
|
|
37
|
+
rejectWith(new Error(event.message || "WebSocket connection failed"));
|
|
38
|
+
};
|
|
39
|
+
conn.addEventListener("message", onMessage);
|
|
40
|
+
conn.addEventListener("close", onClose);
|
|
41
|
+
conn.addEventListener("error", onError);
|
|
42
|
+
timeoutId = window.setTimeout(() => {
|
|
43
|
+
rejectWith(/* @__PURE__ */ new Error("RPGJS connection timeout"));
|
|
44
|
+
}, timeoutMs);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { isNativeSocketEvent, waitForRpgjsConnected };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=mmorpg-connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mmorpg-connection.js","names":[],"sources":["../../src/services/mmorpg-connection.ts"],"sourcesContent":["export function parseSocketMessage(data: any) {\n if (typeof data !== \"string\") {\n return data;\n }\n try {\n return JSON.parse(data);\n }\n catch {\n return undefined;\n }\n}\n\nexport function isNativeSocketEvent(event: string) {\n return event === \"open\" || event === \"close\" || event === \"error\";\n}\n\nexport function waitForRpgjsConnected(\n conn: any,\n timeoutMs = 10000,\n options: { ignoreCleanClose?: boolean } = {},\n): Promise<void> {\n return new Promise((resolve, reject) => {\n let timeoutId: number | undefined;\n\n const cleanup = () => {\n conn.removeEventListener(\"message\", onMessage);\n conn.removeEventListener(\"close\", onClose);\n conn.removeEventListener(\"error\", onError);\n if (timeoutId !== undefined) {\n window.clearTimeout(timeoutId);\n }\n };\n const rejectWith = (error: Error) => {\n cleanup();\n reject(error);\n };\n const onMessage = (event: MessageEvent) => {\n const data = parseSocketMessage(event.data);\n if (data?.type !== \"connected\") {\n return;\n }\n cleanup();\n resolve();\n };\n const onClose = (event: CloseEvent) => {\n const rawReason: unknown = (event as any).reason;\n if (\n options.ignoreCleanClose\n && (event.code === 1000 || rawReason instanceof Event || typeof rawReason !== \"string\")\n ) {\n return;\n }\n const reason = typeof rawReason === \"string\" && rawReason\n ? rawReason\n : \"WebSocket closed before RPGJS connection was accepted\";\n rejectWith(new Error(reason));\n };\n const onError = (event: ErrorEvent) => {\n rejectWith(new Error(event.message || \"WebSocket connection failed\"));\n };\n\n conn.addEventListener(\"message\", onMessage);\n conn.addEventListener(\"close\", onClose);\n conn.addEventListener(\"error\", onError);\n timeoutId = window.setTimeout(() => {\n rejectWith(new Error(\"RPGJS connection timeout\"));\n }, timeoutMs);\n });\n}\n"],"mappings":";AAAA,SAAgB,mBAAmB,MAAW;CAC5C,IAAI,OAAO,SAAS,UAClB,OAAO;CAET,IAAI;EACF,OAAO,KAAK,MAAM,IAAI;CACxB,QACM;EACJ;CACF;AACF;AAEA,SAAgB,oBAAoB,OAAe;CACjD,OAAO,UAAU,UAAU,UAAU,WAAW,UAAU;AAC5D;AAEA,SAAgB,sBACd,MACA,YAAY,KACZ,UAA0C,CAAC,GAC5B;CACf,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,IAAI;EAEJ,MAAM,gBAAgB;GACpB,KAAK,oBAAoB,WAAW,SAAS;GAC7C,KAAK,oBAAoB,SAAS,OAAO;GACzC,KAAK,oBAAoB,SAAS,OAAO;GACzC,IAAI,cAAc,KAAA,GAChB,OAAO,aAAa,SAAS;EAEjC;EACA,MAAM,cAAc,UAAiB;GACnC,QAAQ;GACR,OAAO,KAAK;EACd;EACA,MAAM,aAAa,UAAwB;GAEzC,IADa,mBAAmB,MAAM,IAClC,GAAM,SAAS,aACjB;GAEF,QAAQ;GACR,QAAQ;EACV;EACA,MAAM,WAAW,UAAsB;GACrC,MAAM,YAAsB,MAAc;GAC1C,IACE,QAAQ,qBACJ,MAAM,SAAS,OAAQ,qBAAqB,SAAS,OAAO,cAAc,WAE9E;GAKF,WAAW,IAAI,MAHA,OAAO,cAAc,YAAY,YAC5C,YACA,uDACuB,CAAC;EAC9B;EACA,MAAM,WAAW,UAAsB;GACrC,WAAW,IAAI,MAAM,MAAM,WAAW,6BAA6B,CAAC;EACtE;EAEA,KAAK,iBAAiB,WAAW,SAAS;EAC1C,KAAK,iBAAiB,SAAS,OAAO;EACtC,KAAK,iBAAiB,SAAS,OAAO;EACtC,YAAY,OAAO,iBAAiB;GAClC,2BAAW,IAAI,MAAM,0BAA0B,CAAC;EAClD,GAAG,SAAS;CACd,CAAC;AACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
import { Context } from '@signe/di';
|
|
2
2
|
import { RpgGui } from '../Gui/Gui';
|
|
3
3
|
import { RpgClientEngine } from '../RpgClientEngine';
|
|
4
|
-
import { AbstractWebsocket, SocketUpdateProperties } from './AbstractSocket';
|
|
4
|
+
import { AbstractWebsocket, SocketQuery, SocketUpdateProperties } from './AbstractSocket';
|
|
5
5
|
import { UpdateMapService } from '@rpgjs/common';
|
|
6
|
-
interface MmorpgOptions {
|
|
6
|
+
export interface MmorpgOptions {
|
|
7
7
|
host?: string;
|
|
8
8
|
connectionId?: string;
|
|
9
9
|
connectionIdScope?: "local" | "session" | "ephemeral";
|
|
10
|
+
query?: SocketQuery | (() => SocketQuery | undefined);
|
|
11
|
+
socketOptions?: Record<string, any>;
|
|
10
12
|
}
|
|
11
|
-
declare class BridgeWebsocket extends AbstractWebsocket {
|
|
13
|
+
export declare class BridgeWebsocket extends AbstractWebsocket {
|
|
12
14
|
protected context: Context;
|
|
13
15
|
private options;
|
|
14
16
|
private socket;
|
|
15
17
|
private privateId;
|
|
16
18
|
private pendingOn;
|
|
19
|
+
private acceptedOpenListeners;
|
|
17
20
|
private targetRoom;
|
|
18
21
|
constructor(context: Context, options?: MmorpgOptions);
|
|
19
22
|
private resolveConnectionId;
|
|
23
|
+
private resolveQuery;
|
|
20
24
|
connection(listeners?: (data: any) => void): Promise<void>;
|
|
21
25
|
on(key: string, callback: (data: any) => void): void;
|
|
22
26
|
off(event: string, callback: (data: any) => void): void;
|
|
23
27
|
emit(event: string, data: any): void;
|
|
28
|
+
private attachEvent;
|
|
29
|
+
private emitAcceptedOpen;
|
|
24
30
|
updateProperties({ room, host, query }: SocketUpdateProperties): void;
|
|
25
|
-
private
|
|
31
|
+
private isNativeSocketEvent;
|
|
26
32
|
reconnect(_listeners?: (data: any) => void): Promise<void>;
|
|
27
33
|
getCurrentRoom(): string;
|
|
28
34
|
}
|
package/dist/services/mmorpg.js
CHANGED
|
@@ -4,6 +4,7 @@ import { RpgGui } from "../Gui/Gui.js";
|
|
|
4
4
|
import { RpgClientEngine } from "../RpgClientEngine.js";
|
|
5
5
|
import { provideKeyboardControls } from "./keyboardControls.js";
|
|
6
6
|
import { connectionRoom } from "../node_modules/.pnpm/@signe_sync@3.0.1/node_modules/@signe/sync/dist/client/index.js";
|
|
7
|
+
import { isNativeSocketEvent, waitForRpgjsConnected } from "./mmorpg-connection.js";
|
|
7
8
|
import { UpdateMapService, UpdateMapToken } from "@rpgjs/common";
|
|
8
9
|
//#region src/services/mmorpg.ts
|
|
9
10
|
var BridgeWebsocket = class extends AbstractWebsocket {
|
|
@@ -12,6 +13,7 @@ var BridgeWebsocket = class extends AbstractWebsocket {
|
|
|
12
13
|
this.context = context;
|
|
13
14
|
this.options = options;
|
|
14
15
|
this.pendingOn = [];
|
|
16
|
+
this.acceptedOpenListeners = /* @__PURE__ */ new Set();
|
|
15
17
|
this.targetRoom = "lobby-1";
|
|
16
18
|
this.privateId = this.resolveConnectionId();
|
|
17
19
|
}
|
|
@@ -27,19 +29,31 @@ var BridgeWebsocket = class extends AbstractWebsocket {
|
|
|
27
29
|
storage.setItem(key, id);
|
|
28
30
|
return id;
|
|
29
31
|
}
|
|
32
|
+
resolveQuery() {
|
|
33
|
+
return (typeof this.options.query === "function" ? this.options.query() : this.options.query) ?? {};
|
|
34
|
+
}
|
|
30
35
|
async connection(listeners) {
|
|
31
36
|
class Room {}
|
|
32
37
|
const instance = new Room();
|
|
33
38
|
const host = this.options.host || window.location.host;
|
|
34
39
|
this.socket = await connectionRoom({
|
|
40
|
+
maxRetries: 0,
|
|
41
|
+
...this.options.socketOptions,
|
|
35
42
|
host,
|
|
36
43
|
room: this.targetRoom,
|
|
37
44
|
id: this.privateId,
|
|
38
|
-
query: {
|
|
45
|
+
query: {
|
|
46
|
+
...this.resolveQuery(),
|
|
47
|
+
id: this.privateId
|
|
48
|
+
}
|
|
39
49
|
}, instance);
|
|
40
|
-
|
|
41
|
-
this.pendingOn.forEach(({ event, callback }) => this.socket.on(event, callback));
|
|
50
|
+
const pendingOn = this.pendingOn;
|
|
42
51
|
this.pendingOn = [];
|
|
52
|
+
pendingOn.filter(({ event }) => !this.isNativeSocketEvent(event)).forEach(({ event, callback }) => this.attachEvent(event, callback));
|
|
53
|
+
await waitForRpgjsConnected(this.socket.conn);
|
|
54
|
+
pendingOn.filter(({ event }) => this.isNativeSocketEvent(event)).forEach(({ event, callback }) => this.attachEvent(event, callback));
|
|
55
|
+
this.emitAcceptedOpen();
|
|
56
|
+
listeners?.(this.socket);
|
|
43
57
|
}
|
|
44
58
|
on(key, callback) {
|
|
45
59
|
if (!this.socket) {
|
|
@@ -49,15 +63,38 @@ var BridgeWebsocket = class extends AbstractWebsocket {
|
|
|
49
63
|
});
|
|
50
64
|
return;
|
|
51
65
|
}
|
|
52
|
-
this.
|
|
66
|
+
this.attachEvent(key, callback);
|
|
53
67
|
}
|
|
54
68
|
off(event, callback) {
|
|
55
69
|
if (!this.socket) return;
|
|
70
|
+
if (event === "open") {
|
|
71
|
+
this.acceptedOpenListeners.delete(callback);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (this.isNativeSocketEvent(event)) {
|
|
75
|
+
this.socket.conn.removeEventListener(event, callback);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
56
78
|
this.socket.off(event, callback);
|
|
57
79
|
}
|
|
58
80
|
emit(event, data) {
|
|
59
81
|
this.socket.emit(event, data);
|
|
60
82
|
}
|
|
83
|
+
attachEvent(event, callback) {
|
|
84
|
+
if (event === "open") {
|
|
85
|
+
this.acceptedOpenListeners.add(callback);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (this.isNativeSocketEvent(event)) {
|
|
89
|
+
this.socket.conn.addEventListener(event, callback);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.socket.on(event, callback);
|
|
93
|
+
}
|
|
94
|
+
emitAcceptedOpen() {
|
|
95
|
+
const event = new Event("open");
|
|
96
|
+
this.acceptedOpenListeners.forEach((callback) => callback(event));
|
|
97
|
+
}
|
|
61
98
|
updateProperties({ room, host, query }) {
|
|
62
99
|
if (!this.socket?.conn) return;
|
|
63
100
|
this.targetRoom = room;
|
|
@@ -66,41 +103,22 @@ var BridgeWebsocket = class extends AbstractWebsocket {
|
|
|
66
103
|
id: this.privateId,
|
|
67
104
|
host: host || this.options.host || window.location.host,
|
|
68
105
|
query: {
|
|
106
|
+
...this.resolveQuery(),
|
|
69
107
|
...query,
|
|
70
108
|
id: this.privateId
|
|
71
109
|
}
|
|
72
110
|
});
|
|
73
111
|
}
|
|
74
|
-
|
|
75
|
-
return
|
|
76
|
-
let timeoutId;
|
|
77
|
-
const onOpen = () => {
|
|
78
|
-
cleanup();
|
|
79
|
-
resolve();
|
|
80
|
-
};
|
|
81
|
-
const onError = () => {
|
|
82
|
-
cleanup();
|
|
83
|
-
reject(/* @__PURE__ */ new Error("WebSocket reconnect failed"));
|
|
84
|
-
};
|
|
85
|
-
const cleanup = () => {
|
|
86
|
-
conn.removeEventListener("open", onOpen);
|
|
87
|
-
conn.removeEventListener("error", onError);
|
|
88
|
-
if (timeoutId !== void 0) window.clearTimeout(timeoutId);
|
|
89
|
-
};
|
|
90
|
-
conn.addEventListener("open", onOpen);
|
|
91
|
-
conn.addEventListener("error", onError);
|
|
92
|
-
timeoutId = window.setTimeout(() => {
|
|
93
|
-
cleanup();
|
|
94
|
-
reject(/* @__PURE__ */ new Error("WebSocket reconnect timeout"));
|
|
95
|
-
}, timeoutMs);
|
|
96
|
-
});
|
|
112
|
+
isNativeSocketEvent(event) {
|
|
113
|
+
return isNativeSocketEvent(event);
|
|
97
114
|
}
|
|
98
115
|
async reconnect(_listeners) {
|
|
99
116
|
if (!this.socket?.conn) return;
|
|
100
117
|
const conn = this.socket.conn;
|
|
101
|
-
const
|
|
118
|
+
const connected = waitForRpgjsConnected(conn, 1e4, { ignoreCleanClose: true });
|
|
102
119
|
conn.reconnect();
|
|
103
|
-
await
|
|
120
|
+
await connected;
|
|
121
|
+
this.emitAcceptedOpen();
|
|
104
122
|
}
|
|
105
123
|
getCurrentRoom() {
|
|
106
124
|
return this.targetRoom || this.socket?.conn?.room || "lobby-1";
|
|
@@ -131,6 +149,6 @@ function provideMmorpg(options) {
|
|
|
131
149
|
];
|
|
132
150
|
}
|
|
133
151
|
//#endregion
|
|
134
|
-
export { provideMmorpg };
|
|
152
|
+
export { BridgeWebsocket, provideMmorpg };
|
|
135
153
|
|
|
136
154
|
//# sourceMappingURL=mmorpg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mmorpg.js","names":[],"sources":["../../src/services/mmorpg.ts"],"sourcesContent":["import { Context } from \"@signe/di\";\nimport { connectionRoom } from \"@signe/sync/client\";\nimport { RpgGui } from \"../Gui/Gui\";\nimport { RpgClientEngine } from \"../RpgClientEngine\";\nimport { AbstractWebsocket, SocketUpdateProperties, WebSocketToken } from \"./AbstractSocket\";\nimport { UpdateMapService, UpdateMapToken } from \"@rpgjs/common\";\nimport { provideKeyboardControls } from \"./keyboardControls\";\nimport { provideSaveClient } from \"./save\";\n\
|
|
1
|
+
{"version":3,"file":"mmorpg.js","names":[],"sources":["../../src/services/mmorpg.ts"],"sourcesContent":["import { Context } from \"@signe/di\";\nimport { connectionRoom } from \"@signe/sync/client\";\nimport { RpgGui } from \"../Gui/Gui\";\nimport { RpgClientEngine } from \"../RpgClientEngine\";\nimport { AbstractWebsocket, SocketQuery, SocketUpdateProperties, WebSocketToken } from \"./AbstractSocket\";\nimport { UpdateMapService, UpdateMapToken } from \"@rpgjs/common\";\nimport { provideKeyboardControls } from \"./keyboardControls\";\nimport { provideSaveClient } from \"./save\";\nimport { isNativeSocketEvent, waitForRpgjsConnected } from \"./mmorpg-connection\";\n\nexport interface MmorpgOptions {\n host?: string;\n connectionId?: string;\n connectionIdScope?: \"local\" | \"session\" | \"ephemeral\";\n query?: SocketQuery | (() => SocketQuery | undefined);\n socketOptions?: Record<string, any>;\n}\n\nexport class BridgeWebsocket extends AbstractWebsocket {\n private socket: any;\n private privateId: string;\n private pendingOn: Array<{ event: string; callback: (data: any) => void }> = [];\n private acceptedOpenListeners = new Set<(data: any) => void>();\n private targetRoom = \"lobby-1\";\n\n constructor(protected context: Context, private options: MmorpgOptions = {}) {\n super(context);\n this.privateId = this.resolveConnectionId();\n }\n\n private resolveConnectionId(): string {\n if (this.options.connectionId) {\n return this.options.connectionId;\n }\n\n const scope = this.options.connectionIdScope ?? \"local\";\n const key = \"rpgjs-user-id\";\n\n if (scope === \"ephemeral\") {\n return crypto.randomUUID();\n }\n\n const storage =\n scope === \"session\"\n ? window.sessionStorage\n : window.localStorage;\n\n const existing = storage.getItem(key);\n if (existing) {\n return existing;\n }\n\n const id = crypto.randomUUID();\n storage.setItem(key, id);\n return id;\n }\n\n private resolveQuery(): SocketQuery {\n const query = typeof this.options.query === \"function\"\n ? this.options.query()\n : this.options.query;\n\n return query ?? {};\n }\n\n async connection(listeners?: (data: any) => void) {\n // tmp\n class Room {\n \n }\n const instance = new Room()\n const host = this.options.host || window.location.host;\n this.socket = await connectionRoom({\n maxRetries: 0,\n ...this.options.socketOptions,\n host,\n room: this.targetRoom,\n id: this.privateId,\n query: {\n ...this.resolveQuery(),\n id: this.privateId,\n },\n }, instance)\n\n const pendingOn = this.pendingOn;\n this.pendingOn = [];\n pendingOn\n .filter(({ event }) => !this.isNativeSocketEvent(event))\n .forEach(({ event, callback }) => this.attachEvent(event, callback));\n await waitForRpgjsConnected(this.socket.conn);\n pendingOn\n .filter(({ event }) => this.isNativeSocketEvent(event))\n .forEach(({ event, callback }) => this.attachEvent(event, callback));\n this.emitAcceptedOpen();\n listeners?.(this.socket)\n }\n\n on(key: string, callback: (data: any) => void) {\n if (!this.socket) {\n this.pendingOn.push({ event: key, callback });\n return;\n }\n this.attachEvent(key, callback);\n }\n\n off(event: string, callback: (data: any) => void) {\n if (!this.socket) return;\n if (event === \"open\") {\n this.acceptedOpenListeners.delete(callback);\n return;\n }\n if (this.isNativeSocketEvent(event)) {\n this.socket.conn.removeEventListener(event, callback);\n return;\n }\n this.socket.off(event, callback);\n }\n\n emit(event: string, data: any) {\n this.socket.emit(event, data);\n }\n\n private attachEvent(event: string, callback: (data: any) => void) {\n if (event === \"open\") {\n this.acceptedOpenListeners.add(callback);\n return;\n }\n if (this.isNativeSocketEvent(event)) {\n this.socket.conn.addEventListener(event, callback);\n return;\n }\n this.socket.on(event, callback);\n }\n\n private emitAcceptedOpen() {\n const event = new Event(\"open\");\n this.acceptedOpenListeners.forEach((callback) => callback(event));\n }\n\n updateProperties({ room, host, query }: SocketUpdateProperties) {\n if (!this.socket?.conn) return;\n this.targetRoom = room;\n this.socket.conn.updateProperties({\n room,\n id: this.privateId,\n host: host || this.options.host || window.location.host,\n query: {\n ...this.resolveQuery(),\n ...query,\n id: this.privateId,\n },\n })\n }\n\n private isNativeSocketEvent(event: string) {\n return isNativeSocketEvent(event);\n }\n\n async reconnect(_listeners?: (data: any) => void): Promise<void> {\n if (!this.socket?.conn) return;\n const conn = this.socket.conn;\n const connected = waitForRpgjsConnected(conn, 10000, { ignoreCleanClose: true });\n conn.reconnect();\n await connected;\n this.emitAcceptedOpen();\n }\n\n getCurrentRoom(): string {\n return this.targetRoom || this.socket?.conn?.room || \"lobby-1\";\n }\n}\n\nclass UpdateMapStandaloneService extends UpdateMapService {\n constructor(protected context: Context, private _options: MmorpgOptions) {\n super(context);\n }\n\n async update(_map: any) {\n // In MMORPG mode, clients are untrusted and must not push map definitions.\n // Map bootstrap/update is handled server-side by @rpgjs/vite.\n return;\n }\n}\n\nexport function provideMmorpg(options: MmorpgOptions) {\n return [\n {\n provide: WebSocketToken,\n useFactory: (context: Context) => new BridgeWebsocket(context, options),\n },\n {\n provide: UpdateMapToken,\n useFactory: (context: Context) => new UpdateMapStandaloneService(context, options),\n },\n provideKeyboardControls(),\n provideSaveClient(),\n RpgGui,\n RpgClientEngine,\n ];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ClientPointerPosition {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
}
|
|
5
|
+
export interface ClientPointerContext {
|
|
6
|
+
screen(): ClientPointerPosition | null;
|
|
7
|
+
world(): ClientPointerPosition | null;
|
|
8
|
+
update(screen: ClientPointerPosition | null, world?: ClientPointerPosition | null): ClientPointerPosition | null;
|
|
9
|
+
updateFromEvent(event: any): ClientPointerPosition | null;
|
|
10
|
+
}
|
|
11
|
+
export declare function createClientPointerContext(): ClientPointerContext;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//#region src/services/pointerContext.ts
|
|
2
|
+
function toPosition(point) {
|
|
3
|
+
const x = Number(point?.x);
|
|
4
|
+
const y = Number(point?.y);
|
|
5
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return null;
|
|
6
|
+
return {
|
|
7
|
+
x,
|
|
8
|
+
y
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function extractGlobalPoint(event) {
|
|
12
|
+
return toPosition(event?.global) ?? toPosition(event?.data?.global) ?? toPosition(event);
|
|
13
|
+
}
|
|
14
|
+
function extractWorldPoint(event, global) {
|
|
15
|
+
const target = event?.currentTarget ?? event?.target;
|
|
16
|
+
if (target && global && typeof target.toLocal === "function") return toPosition(target.toLocal(global));
|
|
17
|
+
if (typeof event?.getLocalPosition === "function") return toPosition(event.getLocalPosition(target));
|
|
18
|
+
if (typeof event?.data?.getLocalPosition === "function") return toPosition(event.data.getLocalPosition(target));
|
|
19
|
+
return global;
|
|
20
|
+
}
|
|
21
|
+
function createClientPointerContext() {
|
|
22
|
+
let lastScreen = null;
|
|
23
|
+
let lastWorld = null;
|
|
24
|
+
const update = (screen, world) => {
|
|
25
|
+
const nextScreen = toPosition(screen);
|
|
26
|
+
const nextWorld = toPosition(world) ?? nextScreen;
|
|
27
|
+
if (nextScreen) lastScreen = nextScreen;
|
|
28
|
+
if (nextWorld) lastWorld = nextWorld;
|
|
29
|
+
return lastWorld ? { ...lastWorld } : null;
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
screen() {
|
|
33
|
+
return lastScreen ? { ...lastScreen } : null;
|
|
34
|
+
},
|
|
35
|
+
world() {
|
|
36
|
+
return lastWorld ? { ...lastWorld } : null;
|
|
37
|
+
},
|
|
38
|
+
update,
|
|
39
|
+
updateFromEvent(event) {
|
|
40
|
+
const global = extractGlobalPoint(event);
|
|
41
|
+
return update(global, extractWorldPoint(event, global));
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { createClientPointerContext };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=pointerContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pointerContext.js","names":[],"sources":["../../src/services/pointerContext.ts"],"sourcesContent":["export interface ClientPointerPosition {\n x: number;\n y: number;\n}\n\nexport interface ClientPointerContext {\n screen(): ClientPointerPosition | null;\n world(): ClientPointerPosition | null;\n update(screen: ClientPointerPosition | null, world?: ClientPointerPosition | null): ClientPointerPosition | null;\n updateFromEvent(event: any): ClientPointerPosition | null;\n}\n\nfunction toPosition(point: any): ClientPointerPosition | null {\n const x = Number(point?.x);\n const y = Number(point?.y);\n\n if (!Number.isFinite(x) || !Number.isFinite(y)) {\n return null;\n }\n\n return { x, y };\n}\n\nfunction extractGlobalPoint(event: any): ClientPointerPosition | null {\n return toPosition(event?.global)\n ?? toPosition(event?.data?.global)\n ?? toPosition(event);\n}\n\nfunction extractWorldPoint(event: any, global: ClientPointerPosition | null): ClientPointerPosition | null {\n const target = event?.currentTarget ?? event?.target;\n\n if (target && global && typeof target.toLocal === \"function\") {\n return toPosition(target.toLocal(global));\n }\n\n if (typeof event?.getLocalPosition === \"function\") {\n return toPosition(event.getLocalPosition(target));\n }\n\n if (typeof event?.data?.getLocalPosition === \"function\") {\n return toPosition(event.data.getLocalPosition(target));\n }\n\n return global;\n}\n\nexport function createClientPointerContext(): ClientPointerContext {\n let lastScreen: ClientPointerPosition | null = null;\n let lastWorld: ClientPointerPosition | null = null;\n\n const update = (screen: ClientPointerPosition | null, world?: ClientPointerPosition | null) => {\n const nextScreen = toPosition(screen);\n const nextWorld = toPosition(world) ?? nextScreen;\n\n if (nextScreen) {\n lastScreen = nextScreen;\n }\n\n if (nextWorld) {\n lastWorld = nextWorld;\n }\n\n return lastWorld ? { ...lastWorld } : null;\n };\n\n return {\n screen() {\n return lastScreen ? { ...lastScreen } : null;\n },\n\n world() {\n return lastWorld ? { ...lastWorld } : null;\n },\n\n update,\n\n updateFromEvent(event: any) {\n const global = extractGlobalPoint(event);\n const world = extractWorldPoint(event, global);\n return update(global, world);\n },\n };\n}\n"],"mappings":";AAYA,SAAS,WAAW,OAA0C;CAC5D,MAAM,IAAI,OAAO,OAAO,CAAC;CACzB,MAAM,IAAI,OAAO,OAAO,CAAC;CAEzB,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,GAC3C,OAAO;CAGT,OAAO;EAAE;EAAG;CAAE;AAChB;AAEA,SAAS,mBAAmB,OAA0C;CACpE,OAAO,WAAW,OAAO,MAAM,KAC1B,WAAW,OAAO,MAAM,MAAM,KAC9B,WAAW,KAAK;AACvB;AAEA,SAAS,kBAAkB,OAAY,QAAoE;CACzG,MAAM,SAAS,OAAO,iBAAiB,OAAO;CAE9C,IAAI,UAAU,UAAU,OAAO,OAAO,YAAY,YAChD,OAAO,WAAW,OAAO,QAAQ,MAAM,CAAC;CAG1C,IAAI,OAAO,OAAO,qBAAqB,YACrC,OAAO,WAAW,MAAM,iBAAiB,MAAM,CAAC;CAGlD,IAAI,OAAO,OAAO,MAAM,qBAAqB,YAC3C,OAAO,WAAW,MAAM,KAAK,iBAAiB,MAAM,CAAC;CAGvD,OAAO;AACT;AAEA,SAAgB,6BAAmD;CACjE,IAAI,aAA2C;CAC/C,IAAI,YAA0C;CAE9C,MAAM,UAAU,QAAsC,UAAyC;EAC7F,MAAM,aAAa,WAAW,MAAM;EACpC,MAAM,YAAY,WAAW,KAAK,KAAK;EAEvC,IAAI,YACF,aAAa;EAGf,IAAI,WACF,YAAY;EAGd,OAAO,YAAY,EAAE,GAAG,UAAU,IAAI;CACxC;CAEA,OAAO;EACL,SAAS;GACP,OAAO,aAAa,EAAE,GAAG,WAAW,IAAI;EAC1C;EAEA,QAAQ;GACN,OAAO,YAAY,EAAE,GAAG,UAAU,IAAI;EACxC;EAEA;EAEA,gBAAgB,OAAY;GAC1B,MAAM,SAAS,mBAAmB,KAAK;GAEvC,OAAO,OAAO,QADA,kBAAkB,OAAO,MACjB,CAAK;EAC7B;CACF;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function normalizeStandaloneMessage(event: unknown): any;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/services/standalone-message.ts
|
|
2
|
+
function normalizeStandaloneMessage(event) {
|
|
3
|
+
const raw = event && typeof event === "object" && "data" in event ? event.data : event;
|
|
4
|
+
return typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
export { normalizeStandaloneMessage };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=standalone-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone-message.js","names":[],"sources":["../../src/services/standalone-message.ts"],"sourcesContent":["export function normalizeStandaloneMessage(event: unknown): any {\n const raw = event && typeof event === \"object\" && \"data\" in event\n ? (event as MessageEvent).data\n : event;\n\n return typeof raw === \"string\" ? JSON.parse(raw) : raw;\n}\n"],"mappings":";AAAA,SAAgB,2BAA2B,OAAqB;CAC9D,MAAM,MAAM,SAAS,OAAO,UAAU,YAAY,UAAU,QACvD,MAAuB,OACxB;CAEJ,OAAO,OAAO,QAAQ,WAAW,KAAK,MAAM,GAAG,IAAI;AACrD"}
|
|
@@ -11,7 +11,8 @@ declare class BridgeWebsocket extends AbstractWebsocket {
|
|
|
11
11
|
private server;
|
|
12
12
|
private room;
|
|
13
13
|
private socket;
|
|
14
|
-
private
|
|
14
|
+
private socketRoom?;
|
|
15
|
+
private listeners;
|
|
15
16
|
private rooms;
|
|
16
17
|
private serverInstance;
|
|
17
18
|
constructor(context: Context, server: any, options?: StandaloneOptions);
|
|
@@ -55,6 +56,7 @@ declare class BridgeWebsocket extends AbstractWebsocket {
|
|
|
55
56
|
* ```
|
|
56
57
|
*/
|
|
57
58
|
reconnect(listeners?: (data: any) => void): Promise<void>;
|
|
59
|
+
private detachCurrentSocket;
|
|
58
60
|
getServer(): any;
|
|
59
61
|
getSocket(): any;
|
|
60
62
|
}
|