@cavegiant/cave-world-r3f 1.0.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 +25 -0
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/dist/core/connector-label/readiness.d.ts +11 -0
- package/dist/core/connector-label/readiness.d.ts.map +1 -0
- package/dist/core/connector-label/readiness.js +31 -0
- package/dist/core/connector-label/readiness.js.map +1 -0
- package/dist/core/connector-label/types.d.ts +64 -0
- package/dist/core/connector-label/types.d.ts.map +1 -0
- package/dist/core/connector-label/types.js +47 -0
- package/dist/core/connector-label/types.js.map +1 -0
- package/dist/core/context/cave-world-context.d.ts +96 -0
- package/dist/core/context/cave-world-context.d.ts.map +1 -0
- package/dist/core/context/cave-world-context.js +100 -0
- package/dist/core/context/cave-world-context.js.map +1 -0
- package/dist/core/errors.d.ts +34 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events/event-bus.d.ts +122 -0
- package/dist/core/events/event-bus.d.ts.map +1 -0
- package/dist/core/events/event-bus.js +62 -0
- package/dist/core/events/event-bus.js.map +1 -0
- package/dist/core/hooks/use-cave-event.d.ts +13 -0
- package/dist/core/hooks/use-cave-event.d.ts.map +1 -0
- package/dist/core/hooks/use-cave-event.js +12 -0
- package/dist/core/hooks/use-cave-event.js.map +1 -0
- package/dist/core/i18n/messages.d.ts +82 -0
- package/dist/core/i18n/messages.d.ts.map +1 -0
- package/dist/core/i18n/messages.js +131 -0
- package/dist/core/i18n/messages.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +47 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logging/logger.d.ts +29 -0
- package/dist/core/logging/logger.d.ts.map +1 -0
- package/dist/core/logging/logger.js +47 -0
- package/dist/core/logging/logger.js.map +1 -0
- package/dist/core/registry/component-registry.d.ts +41 -0
- package/dist/core/registry/component-registry.d.ts.map +1 -0
- package/dist/core/registry/component-registry.js +34 -0
- package/dist/core/registry/component-registry.js.map +1 -0
- package/dist/core/registry/object-registry.d.ts +38 -0
- package/dist/core/registry/object-registry.d.ts.map +1 -0
- package/dist/core/registry/object-registry.js +32 -0
- package/dist/core/registry/object-registry.js.map +1 -0
- package/dist/explore/cave-explore.d.ts +85 -0
- package/dist/explore/cave-explore.d.ts.map +1 -0
- package/dist/explore/cave-explore.js +204 -0
- package/dist/explore/cave-explore.js.map +1 -0
- package/dist/explore/cave-orbit-viewer.d.ts +76 -0
- package/dist/explore/cave-orbit-viewer.d.ts.map +1 -0
- package/dist/explore/cave-orbit-viewer.js +123 -0
- package/dist/explore/cave-orbit-viewer.js.map +1 -0
- package/dist/explore/characters/character-configs.d.ts +38 -0
- package/dist/explore/characters/character-configs.d.ts.map +1 -0
- package/dist/explore/characters/character-configs.js +45 -0
- package/dist/explore/characters/character-configs.js.map +1 -0
- package/dist/explore/characters/character-controls.d.ts +44 -0
- package/dist/explore/characters/character-controls.d.ts.map +1 -0
- package/dist/explore/characters/character-pose.d.ts +19 -0
- package/dist/explore/characters/character-pose.d.ts.map +1 -0
- package/dist/explore/characters/character-pose.js +13 -0
- package/dist/explore/characters/character-pose.js.map +1 -0
- package/dist/explore/characters/local-character-model.d.ts +53 -0
- package/dist/explore/characters/local-character-model.d.ts.map +1 -0
- package/dist/explore/characters/local-character-model.js +36 -0
- package/dist/explore/characters/local-character-model.js.map +1 -0
- package/dist/explore/characters/mixamo-style-bone-map.d.ts +9 -0
- package/dist/explore/characters/mixamo-style-bone-map.d.ts.map +1 -0
- package/dist/explore/characters/mixamo-style-bone-map.js +28 -0
- package/dist/explore/characters/mixamo-style-bone-map.js.map +1 -0
- package/dist/explore/characters/remote-character-controller.d.ts +38 -0
- package/dist/explore/characters/remote-character-controller.d.ts.map +1 -0
- package/dist/explore/characters/remote-character-controller.js +135 -0
- package/dist/explore/characters/remote-character-controller.js.map +1 -0
- package/dist/explore/characters/remote-character.d.ts +19 -0
- package/dist/explore/characters/remote-character.d.ts.map +1 -0
- package/dist/explore/characters/remote-character.js +63 -0
- package/dist/explore/characters/remote-character.js.map +1 -0
- package/dist/explore/connected-spaces-renderer.d.ts +16 -0
- package/dist/explore/connected-spaces-renderer.d.ts.map +1 -0
- package/dist/explore/connected-spaces-renderer.js +103 -0
- package/dist/explore/connected-spaces-renderer.js.map +1 -0
- package/dist/explore/hooks/use-action-shortcuts.d.ts +16 -0
- package/dist/explore/hooks/use-action-shortcuts.d.ts.map +1 -0
- package/dist/explore/hooks/use-action-shortcuts.js +23 -0
- package/dist/explore/hooks/use-action-shortcuts.js.map +1 -0
- package/dist/explore/hooks/use-active-space-notify.d.ts +11 -0
- package/dist/explore/hooks/use-active-space-notify.d.ts.map +1 -0
- package/dist/explore/hooks/use-active-space-notify.js +17 -0
- package/dist/explore/hooks/use-active-space-notify.js.map +1 -0
- package/dist/explore/hooks/use-character-sync.d.ts +46 -0
- package/dist/explore/hooks/use-character-sync.d.ts.map +1 -0
- package/dist/explore/hooks/use-character-sync.js +72 -0
- package/dist/explore/hooks/use-character-sync.js.map +1 -0
- package/dist/explore/hooks/use-connector-preloader.d.ts +20 -0
- package/dist/explore/hooks/use-connector-preloader.d.ts.map +1 -0
- package/dist/explore/hooks/use-connector-preloader.js +78 -0
- package/dist/explore/hooks/use-connector-preloader.js.map +1 -0
- package/dist/explore/hooks/use-connector-transitions.d.ts +31 -0
- package/dist/explore/hooks/use-connector-transitions.d.ts.map +1 -0
- package/dist/explore/hooks/use-connector-transitions.js +63 -0
- package/dist/explore/hooks/use-connector-transitions.js.map +1 -0
- package/dist/explore/hooks/use-explore-actions.d.ts +17 -0
- package/dist/explore/hooks/use-explore-actions.d.ts.map +1 -0
- package/dist/explore/hooks/use-explore-actions.js +134 -0
- package/dist/explore/hooks/use-explore-actions.js.map +1 -0
- package/dist/explore/hooks/use-load-error-notify.d.ts +11 -0
- package/dist/explore/hooks/use-load-error-notify.d.ts.map +1 -0
- package/dist/explore/hooks/use-load-error-notify.js +18 -0
- package/dist/explore/hooks/use-load-error-notify.js.map +1 -0
- package/dist/explore/hooks/use-primary-space-loader.d.ts +24 -0
- package/dist/explore/hooks/use-primary-space-loader.d.ts.map +1 -0
- package/dist/explore/hooks/use-primary-space-loader.js +29 -0
- package/dist/explore/hooks/use-primary-space-loader.js.map +1 -0
- package/dist/explore/index.d.ts +37 -0
- package/dist/explore/index.d.ts.map +1 -0
- package/dist/explore/index.js +107 -0
- package/dist/explore/index.js.map +1 -0
- package/dist/explore/loaders/cave-loader.d.ts +58 -0
- package/dist/explore/loaders/cave-loader.d.ts.map +1 -0
- package/dist/explore/loaders/cave-loader.js +79 -0
- package/dist/explore/loaders/cave-loader.js.map +1 -0
- package/dist/explore/math/space-transforms.d.ts +49 -0
- package/dist/explore/math/space-transforms.d.ts.map +1 -0
- package/dist/explore/math/space-transforms.js +54 -0
- package/dist/explore/math/space-transforms.js.map +1 -0
- package/dist/explore/overlays/action-bubble.d.ts +8 -0
- package/dist/explore/overlays/action-bubble.d.ts.map +1 -0
- package/dist/explore/overlays/action-bubble.js +18 -0
- package/dist/explore/overlays/action-bubble.js.map +1 -0
- package/dist/explore/overlays/action-panel.d.ts +12 -0
- package/dist/explore/overlays/action-panel.d.ts.map +1 -0
- package/dist/explore/overlays/action-panel.js +69 -0
- package/dist/explore/overlays/action-panel.js.map +1 -0
- package/dist/explore/overlays/connector-label-beacon.d.ts +11 -0
- package/dist/explore/overlays/connector-label-beacon.d.ts.map +1 -0
- package/dist/explore/overlays/connector-label-beacon.js +38 -0
- package/dist/explore/overlays/connector-label-beacon.js.map +1 -0
- package/dist/explore/overlays/connector-label-tag-shell.d.ts +16 -0
- package/dist/explore/overlays/connector-label-tag-shell.d.ts.map +1 -0
- package/dist/explore/overlays/connector-label-tag-shell.js +18 -0
- package/dist/explore/overlays/connector-label-tag-shell.js.map +1 -0
- package/dist/explore/overlays/detail-window.d.ts +9 -0
- package/dist/explore/overlays/detail-window.d.ts.map +1 -0
- package/dist/explore/overlays/detail-window.js +92 -0
- package/dist/explore/overlays/detail-window.js.map +1 -0
- package/dist/explore/overlays/explore-helper.d.ts +44 -0
- package/dist/explore/overlays/explore-helper.d.ts.map +1 -0
- package/dist/explore/overlays/explore-helper.js +57 -0
- package/dist/explore/overlays/explore-helper.js.map +1 -0
- package/dist/explore/overlays/icons.d.ts +16 -0
- package/dist/explore/overlays/icons.d.ts.map +1 -0
- package/dist/explore/overlays/icons.js +34 -0
- package/dist/explore/overlays/icons.js.map +1 -0
- package/dist/explore/overlays/space-load-error-overlay.d.ts +27 -0
- package/dist/explore/overlays/space-load-error-overlay.d.ts.map +1 -0
- package/dist/explore/overlays/space-load-error-overlay.js +24 -0
- package/dist/explore/overlays/space-load-error-overlay.js.map +1 -0
- package/dist/explore/services/websocket.service.d.ts +180 -0
- package/dist/explore/services/websocket.service.d.ts.map +1 -0
- package/dist/explore/services/websocket.service.js +187 -0
- package/dist/explore/services/websocket.service.js.map +1 -0
- package/dist/explore/simple-character.d.ts +46 -0
- package/dist/explore/simple-character.d.ts.map +1 -0
- package/dist/explore/simple-character.js +119 -0
- package/dist/explore/simple-character.js.map +1 -0
- package/dist/explore/stores/action-prompt.store.d.ts +27 -0
- package/dist/explore/stores/action-prompt.store.d.ts.map +1 -0
- package/dist/explore/stores/action-prompt.store.js +14 -0
- package/dist/explore/stores/action-prompt.store.js.map +1 -0
- package/dist/explore/stores/cave-explore.store.d.ts +77 -0
- package/dist/explore/stores/cave-explore.store.d.ts.map +1 -0
- package/dist/explore/stores/cave-explore.store.js +66 -0
- package/dist/explore/stores/cave-explore.store.js.map +1 -0
- package/dist/explore/stores/explore-context.d.ts +35 -0
- package/dist/explore/stores/explore-context.d.ts.map +1 -0
- package/dist/explore/stores/explore-context.js +43 -0
- package/dist/explore/stores/explore-context.js.map +1 -0
- package/dist/explore/styles/cave-world-css.d.ts +10 -0
- package/dist/explore/styles/cave-world-css.d.ts.map +1 -0
- package/dist/explore/styles/cave-world-css.js +935 -0
- package/dist/explore/styles/cave-world-css.js.map +1 -0
- package/dist/explore/styles/inject.d.ts +32 -0
- package/dist/explore/styles/inject.d.ts.map +1 -0
- package/dist/explore/styles/inject.js +40 -0
- package/dist/explore/styles/inject.js.map +1 -0
- package/dist/explore/utils/schedule-idle.d.ts +12 -0
- package/dist/explore/utils/schedule-idle.d.ts.map +1 -0
- package/dist/explore/utils/schedule-idle.js +16 -0
- package/dist/explore/utils/schedule-idle.js.map +1 -0
- package/dist/explore/viewer-shared.d.ts +56 -0
- package/dist/explore/viewer-shared.d.ts.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/space/cave-base-layer.d.ts +42 -0
- package/dist/space/cave-base-layer.d.ts.map +1 -0
- package/dist/space/cave-base-layer.js +221 -0
- package/dist/space/cave-base-layer.js.map +1 -0
- package/dist/space/cave-custom-layer.d.ts +12 -0
- package/dist/space/cave-custom-layer.d.ts.map +1 -0
- package/dist/space/cave-custom-layer.js +17 -0
- package/dist/space/cave-custom-layer.js.map +1 -0
- package/dist/space/cave-env.d.ts +6 -0
- package/dist/space/cave-env.d.ts.map +1 -0
- package/dist/space/cave-env.js +23 -0
- package/dist/space/cave-env.js.map +1 -0
- package/dist/space/cave-space.d.ts +46 -0
- package/dist/space/cave-space.d.ts.map +1 -0
- package/dist/space/cave-space.js +37 -0
- package/dist/space/cave-space.js.map +1 -0
- package/dist/space/connector-label-host.d.ts +21 -0
- package/dist/space/connector-label-host.d.ts.map +1 -0
- package/dist/space/connector-label-host.js +65 -0
- package/dist/space/connector-label-host.js.map +1 -0
- package/dist/space/index.d.ts +18 -0
- package/dist/space/index.d.ts.map +1 -0
- package/dist/space/index.js +47 -0
- package/dist/space/index.js.map +1 -0
- package/dist/space/objects/builtin-registrar.d.ts +17 -0
- package/dist/space/objects/builtin-registrar.d.ts.map +1 -0
- package/dist/space/objects/builtin-registrar.js +19 -0
- package/dist/space/objects/builtin-registrar.js.map +1 -0
- package/dist/space/objects/custom-object.d.ts +9 -0
- package/dist/space/objects/custom-object.d.ts.map +1 -0
- package/dist/space/objects/custom-object.js +56 -0
- package/dist/space/objects/custom-object.js.map +1 -0
- package/dist/space/objects/image-object.d.ts +7 -0
- package/dist/space/objects/image-object.d.ts.map +1 -0
- package/dist/space/objects/image-object.js +14 -0
- package/dist/space/objects/image-object.js.map +1 -0
- package/dist/space/objects/model-object/fbx-object.d.ts +8 -0
- package/dist/space/objects/model-object/fbx-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/fbx-object.js +26 -0
- package/dist/space/objects/model-object/fbx-object.js.map +1 -0
- package/dist/space/objects/model-object/gltf-object.d.ts +9 -0
- package/dist/space/objects/model-object/gltf-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/gltf-object.js +66 -0
- package/dist/space/objects/model-object/gltf-object.js.map +1 -0
- package/dist/space/objects/model-object/index.d.ts +9 -0
- package/dist/space/objects/model-object/index.d.ts.map +1 -0
- package/dist/space/objects/model-object/index.js +12 -0
- package/dist/space/objects/model-object/index.js.map +1 -0
- package/dist/space/objects/model-object/splat-object.d.ts +9 -0
- package/dist/space/objects/model-object/splat-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/splat-object.js +19 -0
- package/dist/space/objects/model-object/splat-object.js.map +1 -0
- package/dist/space/objects/object-components/windows/index.d.ts +5 -0
- package/dist/space/objects/object-components/windows/index.d.ts.map +1 -0
- package/dist/space/objects/object-components/windows/index.js +20 -0
- package/dist/space/objects/object-components/windows/index.js.map +1 -0
- package/dist/space/objects/placeholder-object.d.ts +7 -0
- package/dist/space/objects/placeholder-object.d.ts.map +1 -0
- package/dist/space/objects/placeholder-object.js +12 -0
- package/dist/space/objects/placeholder-object.js.map +1 -0
- package/dist/space/objects/poi-object.d.ts +7 -0
- package/dist/space/objects/poi-object.d.ts.map +1 -0
- package/dist/space/objects/poi-object.js +38 -0
- package/dist/space/objects/poi-object.js.map +1 -0
- package/dist/space/objects/portal-object.d.ts +7 -0
- package/dist/space/objects/portal-object.d.ts.map +1 -0
- package/dist/space/objects/portal-object.js +84 -0
- package/dist/space/objects/portal-object.js.map +1 -0
- package/dist/space/objects/video-object.d.ts +7 -0
- package/dist/space/objects/video-object.d.ts.map +1 -0
- package/dist/space/objects/video-object.js +32 -0
- package/dist/space/objects/video-object.js.map +1 -0
- package/dist/space/polygon-boundary.d.ts +10 -0
- package/dist/space/polygon-boundary.d.ts.map +1 -0
- package/dist/space/polygon-boundary.js +205 -0
- package/dist/space/polygon-boundary.js.map +1 -0
- package/dist/space/splats/spark/robust-splat-mesh.d.ts +59 -0
- package/dist/space/splats/spark/robust-splat-mesh.d.ts.map +1 -0
- package/dist/space/splats/spark/robust-splat-mesh.js +105 -0
- package/dist/space/splats/spark/robust-splat-mesh.js.map +1 -0
- package/dist/space/splats/spark/splat-mesh.d.ts +5 -0
- package/dist/space/splats/spark/splat-mesh.d.ts.map +1 -0
- package/dist/space/splats/spark/splat-mesh.js +7 -0
- package/dist/space/splats/spark/splat-mesh.js.map +1 -0
- package/dist/space/splats/spark/splat-spread-reveal.d.ts +14 -0
- package/dist/space/splats/spark/splat-spread-reveal.d.ts.map +1 -0
- package/dist/space/splats/spark/splat-spread-reveal.js +45 -0
- package/dist/space/splats/spark/splat-spread-reveal.js.map +1 -0
- package/dist/space/utils/cave-world-player.d.ts +3 -0
- package/dist/space/utils/cave-world-player.d.ts.map +1 -0
- package/dist/space/utils/cave-world-player.js +5 -0
- package/dist/space/utils/cave-world-player.js.map +1 -0
- package/dist/space/utils/configure-canvas.d.ts +20 -0
- package/dist/space/utils/configure-canvas.d.ts.map +1 -0
- package/dist/space/utils/configure-canvas.js +12 -0
- package/dist/space/utils/configure-canvas.js.map +1 -0
- package/dist/space/utils/polygon-boundary-geometry.d.ts +8 -0
- package/dist/space/utils/polygon-boundary-geometry.d.ts.map +1 -0
- package/dist/space/utils/polygon-boundary-geometry.js +20 -0
- package/dist/space/utils/polygon-boundary-geometry.js.map +1 -0
- package/dist/space/utils/polygon-boundary-segments.d.ts +50 -0
- package/dist/space/utils/polygon-boundary-segments.d.ts.map +1 -0
- package/dist/space/utils/polygon-boundary-segments.js +64 -0
- package/dist/space/utils/polygon-boundary-segments.js.map +1 -0
- package/dist/space/utils/rotation-compat.d.ts +4 -0
- package/dist/space/utils/rotation-compat.d.ts.map +1 -0
- package/dist/space/utils/rotation-compat.js +9 -0
- package/dist/space/utils/rotation-compat.js.map +1 -0
- package/dist/space/utils/select-splat-level.d.ts +52 -0
- package/dist/space/utils/select-splat-level.d.ts.map +1 -0
- package/dist/space/utils/select-splat-level.js +43 -0
- package/dist/space/utils/select-splat-level.js.map +1 -0
- package/dist/space/utils/spark-performance.d.ts +10 -0
- package/dist/space/utils/spark-performance.d.ts.map +1 -0
- package/dist/space/utils/spark-performance.js +10 -0
- package/dist/space/utils/spark-performance.js.map +1 -0
- package/dist/space/utils/splat-collider-helper.d.ts +5 -0
- package/dist/space/utils/splat-collider-helper.d.ts.map +1 -0
- package/dist/space/utils/splat-collider-helper.js +162 -0
- package/dist/space/utils/splat-collider-helper.js.map +1 -0
- package/dist/space/utils/touch-primary-device.d.ts +16 -0
- package/dist/space/utils/touch-primary-device.d.ts.map +1 -0
- package/dist/space/utils/touch-primary-device.js +52 -0
- package/dist/space/utils/touch-primary-device.js.map +1 -0
- package/dist/space/utils/use-visibility-frameloop.d.ts +20 -0
- package/dist/space/utils/use-visibility-frameloop.d.ts.map +1 -0
- package/dist/space/utils/use-visibility-frameloop.js +18 -0
- package/dist/space/utils/use-visibility-frameloop.js.map +1 -0
- package/dist/styles.css +930 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/space-types.d.ts +404 -0
- package/dist/types/space-types.d.ts.map +1 -0
- package/doc/API.md +617 -0
- package/doc/ARCHITECTURE.md +264 -0
- package/doc/multiplayer-protocol.md +757 -0
- package/doc/scene-json-structure.md +567 -0
- package/package.json +131 -0
|
@@ -0,0 +1,757 @@
|
|
|
1
|
+
# 多人游戏数据同步系统 - 前端接口文档
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
本文档描述了多人游戏数据同步系统的WebSocket API接口,供前端开发者集成使用。系统支持实时多人游戏数据同步,包括位置、旋转、动画状态等。
|
|
6
|
+
|
|
7
|
+
## 连接信息
|
|
8
|
+
|
|
9
|
+
- **协议**: WebSocket (WSS)
|
|
10
|
+
- **端点**: 由后端配置的WebSocket API Gateway端点
|
|
11
|
+
- **认证**: 支持JWT认证和匿名访问
|
|
12
|
+
|
|
13
|
+
## 消息格式
|
|
14
|
+
|
|
15
|
+
所有消息都采用JSON格式,包含以下字段:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"action": "动作名称",
|
|
20
|
+
"data": {
|
|
21
|
+
// 具体数据内容
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 客户端到服务器消息
|
|
27
|
+
|
|
28
|
+
### 1. 加入游戏
|
|
29
|
+
|
|
30
|
+
**动作**: `JOIN_GAME`
|
|
31
|
+
|
|
32
|
+
**描述**: 玩家加入指定应用的游戏
|
|
33
|
+
|
|
34
|
+
**消息格式**:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"action": "JOIN_GAME",
|
|
39
|
+
"data": {
|
|
40
|
+
"appId": "your-app-id"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**参数说明**:
|
|
46
|
+
|
|
47
|
+
- `appId` (string, 必需): 应用ID
|
|
48
|
+
|
|
49
|
+
**响应**: 服务器会发送 `JOIN_SUCCESS` 消息
|
|
50
|
+
|
|
51
|
+
**重复加入处理**:
|
|
52
|
+
|
|
53
|
+
- 如果玩家已存在,系统会更新连接信息并返回 `isRejoin: true`
|
|
54
|
+
- 如果玩家不存在,系统会创建新玩家并返回 `isRejoin: false`
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### 2. 更新玩家状态
|
|
59
|
+
|
|
60
|
+
**动作**: `UPDATE_STATE`
|
|
61
|
+
|
|
62
|
+
**描述**: 更新玩家的位置、旋转、动画或Avatar状态
|
|
63
|
+
|
|
64
|
+
**消息格式**:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"action": "UPDATE_STATE",
|
|
69
|
+
"data": {
|
|
70
|
+
"position": [10.5, 0, -5.2],
|
|
71
|
+
"rotation": [0, 0.707, 0, 0.707],
|
|
72
|
+
"animation": "walking",
|
|
73
|
+
"avatarId": "warrior"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**参数说明**:
|
|
79
|
+
|
|
80
|
+
- `position` (array, 可选): 3D位置坐标 `[x, y, z]`
|
|
81
|
+
- `rotation` (array, 可选): 四元数旋转 `[x, y, z, w]`
|
|
82
|
+
- `animation` (string, 可选): 动画名称
|
|
83
|
+
- `avatarId` (string, 可选): 人物ID
|
|
84
|
+
|
|
85
|
+
**注意**: 可以只更新部分字段,例如只更新位置:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"action": "UPDATE_STATE",
|
|
90
|
+
"data": {
|
|
91
|
+
"position": [10.5, 0, -5.2]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
或者只更新头像:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"action": "UPDATE_STATE",
|
|
101
|
+
"data": {
|
|
102
|
+
"avatarId": "mage"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**响应**: 服务器会向房间内其他玩家广播 `STATE_UPDATE` 消息
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### 3. 同步房间状态
|
|
112
|
+
|
|
113
|
+
**动作**: `SYNC_STATE`
|
|
114
|
+
|
|
115
|
+
**描述**: 请求同步当前房间内所有玩家的状态
|
|
116
|
+
|
|
117
|
+
**消息格式**:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"action": "SYNC_STATE",
|
|
122
|
+
"data": {}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**响应**: 服务器会发送 `STATE_SYNC` 消息
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### 4. 心跳检测
|
|
131
|
+
|
|
132
|
+
**动作**: `PING`
|
|
133
|
+
|
|
134
|
+
**描述**: 发送心跳以保持连接活跃
|
|
135
|
+
|
|
136
|
+
**消息格式**:
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"action": "PING",
|
|
141
|
+
"data": {}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**响应**: 服务器会发送 `PONG` 消息
|
|
146
|
+
|
|
147
|
+
### 5. 运维查询
|
|
148
|
+
|
|
149
|
+
**动作**: `OPS_QUERY`
|
|
150
|
+
|
|
151
|
+
**描述**: 运维人员查询系统数据
|
|
152
|
+
|
|
153
|
+
**消息格式**:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"action": "OPS_QUERY",
|
|
158
|
+
"data": {
|
|
159
|
+
"key": "mb:player:player-123"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**参数说明**:
|
|
165
|
+
|
|
166
|
+
- `key` (string, 必需): Redis原生键值
|
|
167
|
+
|
|
168
|
+
**支持的key格式**:
|
|
169
|
+
|
|
170
|
+
- `mb:player:{playerId}`: 查询玩家信息
|
|
171
|
+
- `mb:room:{roomId}`: 查询房间信息
|
|
172
|
+
- `mb:connection:{connectionId}`: 查询连接信息
|
|
173
|
+
- `mb:app_rooms:{appId}`: 查询应用房间列表
|
|
174
|
+
- `mb:room_players:{roomId}`: 查询房间玩家列表
|
|
175
|
+
- `health`: 查询系统健康状态
|
|
176
|
+
- 其他: 直接查询Redis键值
|
|
177
|
+
|
|
178
|
+
**响应**: 服务器会发送 `OPS_RESULT` 或 `OPS_ERROR` 消息
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 服务器到客户端消息
|
|
183
|
+
|
|
184
|
+
### 1. 加入成功
|
|
185
|
+
|
|
186
|
+
**动作**: `JOIN_SUCCESS`
|
|
187
|
+
|
|
188
|
+
**描述**: 玩家成功加入游戏房间
|
|
189
|
+
|
|
190
|
+
**消息格式**:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"action": "JOIN_SUCCESS",
|
|
195
|
+
"data": {
|
|
196
|
+
"roomId": "room_app_1234567890_1",
|
|
197
|
+
"playerId": "player-1",
|
|
198
|
+
"players": [
|
|
199
|
+
{
|
|
200
|
+
"id": "player-1",
|
|
201
|
+
"position": [0, 0, 0],
|
|
202
|
+
"rotation": [0, 0, 0, 1],
|
|
203
|
+
"animation": "idle",
|
|
204
|
+
"avatarId": "default",
|
|
205
|
+
"lastUpdate": 1234567890
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"isRejoin": false
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**参数说明**:
|
|
214
|
+
|
|
215
|
+
- `roomId` (string): 分配的房间ID
|
|
216
|
+
- `playerId` (string): 当前玩家的ID
|
|
217
|
+
- `players` (array): 房间内所有玩家信息
|
|
218
|
+
- `id` (string): 玩家ID
|
|
219
|
+
- `position` (array): 位置坐标
|
|
220
|
+
- `rotation` (array): 旋转四元数
|
|
221
|
+
- `animation` (string): 当前动画
|
|
222
|
+
- `avatarId` (string): AvatarID
|
|
223
|
+
- `lastUpdate` (number): 最后更新时间戳
|
|
224
|
+
- `isRejoin` (boolean): 是否为重新加入(true=重新加入,false=首次加入)
|
|
225
|
+
|
|
226
|
+
**重要说明**:
|
|
227
|
+
|
|
228
|
+
- `playerId` 字段用于标识当前玩家自己的ID
|
|
229
|
+
- 客户端可以通过比较 `playerId` 和 `players` 数组中的 `id` 来区分自己和他人
|
|
230
|
+
- 建议将其他玩家添加到游戏场景中,而自己的数据用于初始化或状态同步
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### 2. 玩家加入
|
|
235
|
+
|
|
236
|
+
**动作**: `PLAYER_JOINED`
|
|
237
|
+
|
|
238
|
+
**描述**: 有新玩家加入当前房间
|
|
239
|
+
|
|
240
|
+
**消息格式**:
|
|
241
|
+
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"action": "PLAYER_JOINED",
|
|
245
|
+
"data": {
|
|
246
|
+
"playerId": "player-2",
|
|
247
|
+
"position": [0, 0, 0],
|
|
248
|
+
"rotation": [0, 0, 0, 1],
|
|
249
|
+
"animation": "idle",
|
|
250
|
+
"avatarId": "default"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
### 3. 玩家离开
|
|
258
|
+
|
|
259
|
+
**动作**: `PLAYER_LEFT`
|
|
260
|
+
|
|
261
|
+
**描述**: 有玩家离开当前房间
|
|
262
|
+
|
|
263
|
+
**消息格式**:
|
|
264
|
+
|
|
265
|
+
```json
|
|
266
|
+
{
|
|
267
|
+
"action": "PLAYER_LEFT",
|
|
268
|
+
"data": {
|
|
269
|
+
"playerId": "player-2"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
### 4. 状态更新
|
|
277
|
+
|
|
278
|
+
**动作**: `STATE_UPDATE`
|
|
279
|
+
|
|
280
|
+
**描述**: 房间内其他玩家的状态更新
|
|
281
|
+
|
|
282
|
+
**消息格式**:
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"action": "STATE_UPDATE",
|
|
287
|
+
"data": {
|
|
288
|
+
"playerId": "player-1",
|
|
289
|
+
"position": [10.5, 0, -5.2],
|
|
290
|
+
"rotation": [0, 0.707, 0, 0.707],
|
|
291
|
+
"animation": "walking",
|
|
292
|
+
"avatarId": "warrior"
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**注意**: 服务器只会发送实际更新的字段
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
### 5. 状态同步
|
|
302
|
+
|
|
303
|
+
**动作**: `STATE_SYNC`
|
|
304
|
+
|
|
305
|
+
**描述**: 房间内所有玩家的完整状态信息
|
|
306
|
+
|
|
307
|
+
**消息格式**:
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"action": "STATE_SYNC",
|
|
312
|
+
"data": {
|
|
313
|
+
"players": [
|
|
314
|
+
{
|
|
315
|
+
"id": "player-1",
|
|
316
|
+
"position": [10.5, 0, -5.2],
|
|
317
|
+
"rotation": [0, 0.707, 0, 0.707],
|
|
318
|
+
"animation": "walking",
|
|
319
|
+
"avatarId": "warrior",
|
|
320
|
+
"lastUpdate": 1234567890
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
### 6. 心跳响应
|
|
330
|
+
|
|
331
|
+
**动作**: `PONG`
|
|
332
|
+
|
|
333
|
+
**描述**: 服务器对心跳的响应
|
|
334
|
+
|
|
335
|
+
**消息格式**:
|
|
336
|
+
|
|
337
|
+
```json
|
|
338
|
+
{
|
|
339
|
+
"action": "PONG",
|
|
340
|
+
"data": {
|
|
341
|
+
"timestamp": 1234567890
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### 6. 运维查询结果
|
|
347
|
+
|
|
348
|
+
**动作**: `OPS_RESULT`
|
|
349
|
+
|
|
350
|
+
**描述**: 运维查询成功响应
|
|
351
|
+
|
|
352
|
+
**消息格式**:
|
|
353
|
+
|
|
354
|
+
```json
|
|
355
|
+
{
|
|
356
|
+
"action": "OPS_RESULT",
|
|
357
|
+
"data": {
|
|
358
|
+
"key": "mb:player:player-123",
|
|
359
|
+
"type": "cache",
|
|
360
|
+
"result": {
|
|
361
|
+
"id": "player-123",
|
|
362
|
+
"connectionId": "conn-456",
|
|
363
|
+
"appId": "app-789",
|
|
364
|
+
"roomId": "room-101",
|
|
365
|
+
"position": [0, 0, 0],
|
|
366
|
+
"rotation": [0, 0, 0, 1],
|
|
367
|
+
"animation": "idle",
|
|
368
|
+
"avatarId": "default",
|
|
369
|
+
"lastUpdate": 1234567890,
|
|
370
|
+
"isOnline": true,
|
|
371
|
+
"isAnonymous": false,
|
|
372
|
+
"createdAt": 1234567890
|
|
373
|
+
},
|
|
374
|
+
"timestamp": 1234567890
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**参数说明**:
|
|
380
|
+
|
|
381
|
+
- `key` (string): 查询的键值
|
|
382
|
+
- `type` (string): 结果类型
|
|
383
|
+
- `result` (object): 查询结果数据
|
|
384
|
+
- `timestamp` (number): 响应时间戳
|
|
385
|
+
|
|
386
|
+
### 7. 运维查询错误
|
|
387
|
+
|
|
388
|
+
**动作**: `OPS_ERROR`
|
|
389
|
+
|
|
390
|
+
**描述**: 运维查询错误响应
|
|
391
|
+
|
|
392
|
+
**消息格式**:
|
|
393
|
+
|
|
394
|
+
```json
|
|
395
|
+
{
|
|
396
|
+
"action": "OPS_ERROR",
|
|
397
|
+
"data": {
|
|
398
|
+
"key": "invalid_key",
|
|
399
|
+
"error": "Query key is required",
|
|
400
|
+
"code": "WS.0011",
|
|
401
|
+
"timestamp": 1234567890
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**参数说明**:
|
|
407
|
+
|
|
408
|
+
- `key` (string): 查询的键值
|
|
409
|
+
- `error` (string): 错误信息
|
|
410
|
+
- `code` (string): 错误代码
|
|
411
|
+
- `timestamp` (number): 响应时间戳
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## 错误处理
|
|
416
|
+
|
|
417
|
+
### 错误消息格式
|
|
418
|
+
|
|
419
|
+
```json
|
|
420
|
+
{
|
|
421
|
+
"action": "ERROR",
|
|
422
|
+
"data": {
|
|
423
|
+
"error_code": "WS.0001",
|
|
424
|
+
"error_msg": "错误描述"
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### 常见错误代码
|
|
430
|
+
|
|
431
|
+
| 错误代码 | 描述 | 解决方案 |
|
|
432
|
+
| --------- | ---------------- | ------------------------------------ |
|
|
433
|
+
| `WS.0001` | 不支持的事件类型 | 检查action字段是否正确 |
|
|
434
|
+
| `WS.0002` | 连接未找到 | 重新建立连接 |
|
|
435
|
+
| `WS.0003` | 无效的JSON消息 | 检查消息格式 |
|
|
436
|
+
| `WS.0004` | 缺少消息动作 | 确保包含action字段 |
|
|
437
|
+
| `WS.0005` | 未知的消息动作 | 使用支持的动作名称 |
|
|
438
|
+
| `WS.0006` | 缺少应用ID | 在JOIN_GAME中提供appId |
|
|
439
|
+
| `WS.0007` | 缺少状态字段 | 在UPDATE_STATE中提供至少一个状态字段 |
|
|
440
|
+
| `WS.0008` | 位置数据格式错误 | 检查position数组格式 |
|
|
441
|
+
| `WS.0009` | 旋转数据格式错误 | 检查rotation四元数格式 |
|
|
442
|
+
| `WS.0010` | 连接未找到 | 重新建立连接或检查连接状态 |
|
|
443
|
+
| `PM.0010` | AvatarID格式错误 | 检查avatarId字符串格式 |
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
## 前端集成示例
|
|
448
|
+
|
|
449
|
+
### JavaScript/TypeScript 示例
|
|
450
|
+
|
|
451
|
+
```javascript
|
|
452
|
+
class GameWebSocket {
|
|
453
|
+
constructor(wsUrl, appId) {
|
|
454
|
+
this.wsUrl = wsUrl
|
|
455
|
+
this.appId = appId
|
|
456
|
+
this.ws = null
|
|
457
|
+
this.players = new Map()
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
connect() {
|
|
461
|
+
this.ws = new WebSocket(this.wsUrl)
|
|
462
|
+
|
|
463
|
+
this.ws.onopen = () => {
|
|
464
|
+
console.log('WebSocket connected')
|
|
465
|
+
this.joinGame()
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
this.ws.onmessage = (event) => {
|
|
469
|
+
const message = JSON.parse(event.data)
|
|
470
|
+
this.handleMessage(message)
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
this.ws.onclose = () => {
|
|
474
|
+
console.log('WebSocket disconnected')
|
|
475
|
+
// 实现重连逻辑
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
this.ws.onerror = (error) => {
|
|
479
|
+
console.error('WebSocket error:', error)
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
joinGame() {
|
|
484
|
+
this.send({
|
|
485
|
+
action: 'JOIN_GAME',
|
|
486
|
+
data: { appId: this.appId }
|
|
487
|
+
})
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
updateState(position, rotation, animation, avatarId) {
|
|
491
|
+
const data = {}
|
|
492
|
+
if (position) data.position = position
|
|
493
|
+
if (rotation) data.rotation = rotation
|
|
494
|
+
if (animation) data.animation = animation
|
|
495
|
+
if (avatarId) data.avatarId = avatarId
|
|
496
|
+
|
|
497
|
+
this.send({
|
|
498
|
+
action: 'UPDATE_STATE',
|
|
499
|
+
data: data
|
|
500
|
+
})
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// 运维查询方法
|
|
504
|
+
queryOps(key) {
|
|
505
|
+
this.send({
|
|
506
|
+
action: 'OPS_QUERY',
|
|
507
|
+
data: {
|
|
508
|
+
key: key
|
|
509
|
+
}
|
|
510
|
+
})
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
sendPing() {
|
|
514
|
+
this.send({
|
|
515
|
+
action: 'PING',
|
|
516
|
+
data: {}
|
|
517
|
+
})
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
send(message) {
|
|
521
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
522
|
+
this.ws.send(JSON.stringify(message))
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
handleMessage(message) {
|
|
527
|
+
switch (message.action) {
|
|
528
|
+
case 'JOIN_SUCCESS':
|
|
529
|
+
this.handleJoinSuccess(message.data)
|
|
530
|
+
break
|
|
531
|
+
case 'PLAYER_JOINED':
|
|
532
|
+
this.handlePlayerJoined(message.data)
|
|
533
|
+
break
|
|
534
|
+
case 'PLAYER_LEFT':
|
|
535
|
+
this.handlePlayerLeft(message.data)
|
|
536
|
+
break
|
|
537
|
+
case 'STATE_UPDATE':
|
|
538
|
+
this.handleStateUpdate(message.data)
|
|
539
|
+
break
|
|
540
|
+
case 'STATE_SYNC':
|
|
541
|
+
this.handleStateSync(message.data)
|
|
542
|
+
break
|
|
543
|
+
case 'PONG':
|
|
544
|
+
this.handlePong(message.data)
|
|
545
|
+
break
|
|
546
|
+
case 'OPS_RESULT':
|
|
547
|
+
this.handleOpsResult(message.data)
|
|
548
|
+
break
|
|
549
|
+
case 'OPS_ERROR':
|
|
550
|
+
this.handleOpsError(message.data)
|
|
551
|
+
break
|
|
552
|
+
case 'ERROR':
|
|
553
|
+
this.handleError(message.data)
|
|
554
|
+
break
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
handleJoinSuccess(data) {
|
|
559
|
+
console.log('Joined room:', data.roomId)
|
|
560
|
+
console.log('My player ID:', data.playerId)
|
|
561
|
+
|
|
562
|
+
// 分离自己和他人数据
|
|
563
|
+
const otherPlayers = data.players.filter((player) => player.id !== data.playerId)
|
|
564
|
+
const myPlayer = data.players.find((player) => player.id === data.playerId)
|
|
565
|
+
|
|
566
|
+
// 添加其他玩家到游戏场景
|
|
567
|
+
otherPlayers.forEach((player) => {
|
|
568
|
+
this.players.set(player.id, player)
|
|
569
|
+
})
|
|
570
|
+
|
|
571
|
+
// 处理自己的玩家数据(如果需要)
|
|
572
|
+
if (myPlayer) {
|
|
573
|
+
console.log('My player data:', myPlayer)
|
|
574
|
+
// 可以在这里设置自己的初始状态或进行其他处理
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
handlePlayerJoined(data) {
|
|
579
|
+
console.log('Player joined:', data.playerId)
|
|
580
|
+
this.players.set(data.playerId, data)
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
handlePlayerLeft(data) {
|
|
584
|
+
console.log('Player left:', data.playerId)
|
|
585
|
+
this.players.delete(data.playerId)
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
handleStateUpdate(data) {
|
|
589
|
+
const player = this.players.get(data.playerId)
|
|
590
|
+
if (player) {
|
|
591
|
+
if (data.position) player.position = data.position
|
|
592
|
+
if (data.rotation) player.rotation = data.rotation
|
|
593
|
+
if (data.animation) player.animation = data.animation
|
|
594
|
+
if (data.avatarId) player.avatarId = data.avatarId
|
|
595
|
+
player.lastUpdate = Date.now()
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
handleStateSync(data) {
|
|
600
|
+
data.players.forEach((player) => {
|
|
601
|
+
this.players.set(player.id, player)
|
|
602
|
+
})
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
handlePong(data) {
|
|
606
|
+
console.log('Pong received:', data.timestamp)
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
handleError(data) {
|
|
610
|
+
console.error('Server error:', data.error_code, data.error_msg)
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// 使用示例
|
|
615
|
+
const gameWs = new GameWebSocket('wss://your-websocket-endpoint', 'your-app-id')
|
|
616
|
+
gameWs.connect()
|
|
617
|
+
|
|
618
|
+
// 定期发送心跳
|
|
619
|
+
setInterval(() => {
|
|
620
|
+
gameWs.sendPing()
|
|
621
|
+
}, 30000)
|
|
622
|
+
|
|
623
|
+
// 更新玩家状态
|
|
624
|
+
gameWs.updateState([10, 0, 5], [0, 0, 0, 1], 'walking', 'warrior')
|
|
625
|
+
|
|
626
|
+
// 只更新头像
|
|
627
|
+
gameWs.updateState(null, null, null, 'mage')
|
|
628
|
+
|
|
629
|
+
// 运维查询示例
|
|
630
|
+
gameWs.queryOps('mb:player:player-123')
|
|
631
|
+
gameWs.queryOps('mb:room:room-456')
|
|
632
|
+
gameWs.queryOps('mb:app_rooms:app-789')
|
|
633
|
+
gameWs.queryOps('health')
|
|
634
|
+
gameWs.queryOps('stats')
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
// 处理运维查询响应
|
|
638
|
+
handleOpsResult(data) {
|
|
639
|
+
console.log('Ops query result:', data);
|
|
640
|
+
console.log('Key:', data.key);
|
|
641
|
+
console.log('Type:', data.type);
|
|
642
|
+
console.log('Result:', data.result);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
handleOpsError(data) {
|
|
646
|
+
console.error('Ops query error:', data);
|
|
647
|
+
console.error('Key:', data.key);
|
|
648
|
+
console.error('Error:', data.error);
|
|
649
|
+
console.error('Code:', data.code);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
## 最佳实践
|
|
657
|
+
|
|
658
|
+
### 1. 连接管理
|
|
659
|
+
- 实现自动重连机制
|
|
660
|
+
- 处理网络中断和恢复
|
|
661
|
+
- 设置合理的连接超时时间
|
|
662
|
+
- 处理连接状态变化(连接、断开、重连)
|
|
663
|
+
- 实现连接状态监控和错误恢复
|
|
664
|
+
|
|
665
|
+
### 2. 状态同步
|
|
666
|
+
- 使用节流机制避免过于频繁的状态更新
|
|
667
|
+
- 实现状态插值和平滑过渡
|
|
668
|
+
- 处理网络延迟和丢包情况
|
|
669
|
+
|
|
670
|
+
### 3. 错误处理
|
|
671
|
+
- 实现完整的错误处理机制
|
|
672
|
+
- 提供用户友好的错误提示
|
|
673
|
+
- 记录错误日志用于调试
|
|
674
|
+
|
|
675
|
+
### 4. 性能优化
|
|
676
|
+
- 只发送必要的状态更新
|
|
677
|
+
- 使用批量更新减少网络请求
|
|
678
|
+
- 实现客户端预测和回滚机制
|
|
679
|
+
|
|
680
|
+
### 5. 数据清理和生命周期管理
|
|
681
|
+
- 服务器会自动清理断开连接的数据
|
|
682
|
+
- 支持只连接但不加入房间的场景
|
|
683
|
+
- 实现优雅的连接断开处理
|
|
684
|
+
- 避免数据泄漏和内存浪费
|
|
685
|
+
|
|
686
|
+
---
|
|
687
|
+
|
|
688
|
+
## 连接生命周期
|
|
689
|
+
|
|
690
|
+
### 连接建立
|
|
691
|
+
1. **WebSocket连接**: 客户端建立WebSocket连接
|
|
692
|
+
2. **身份验证**: 系统验证JWT token(如果提供)或生成匿名ID
|
|
693
|
+
3. **连接记录**: 系统记录连接信息,包括playerId和连接状态
|
|
694
|
+
|
|
695
|
+
### 游戏加入
|
|
696
|
+
1. **发送JOIN_GAME**: 客户端发送加入游戏消息
|
|
697
|
+
2. **房间分配**: 系统分配或创建房间
|
|
698
|
+
3. **玩家创建**: 系统创建玩家数据并关联到房间
|
|
699
|
+
4. **状态同步**: 系统返回房间内所有玩家状态
|
|
700
|
+
|
|
701
|
+
### 游戏进行
|
|
702
|
+
1. **状态更新**: 客户端发送UPDATE_STATE消息
|
|
703
|
+
2. **数据同步**: 服务器广播状态更新给其他玩家
|
|
704
|
+
3. **心跳检测**: 定期发送PING/PONG保持连接活跃
|
|
705
|
+
|
|
706
|
+
### 连接断开
|
|
707
|
+
1. **断开检测**: 系统检测到连接断开
|
|
708
|
+
2. **数据清理**:
|
|
709
|
+
- 如果玩家已加入房间:清理玩家数据、从房间移除、通知其他玩家
|
|
710
|
+
- 如果只连接未加入:只清理连接数据
|
|
711
|
+
3. **资源释放**: 释放相关缓存和内存资源
|
|
712
|
+
|
|
713
|
+
### 重连处理
|
|
714
|
+
1. **连接恢复**: 客户端重新建立连接
|
|
715
|
+
2. **身份识别**: 系统识别玩家身份(通过JWT或匿名ID)
|
|
716
|
+
3. **状态恢复**: 如果玩家之前已加入房间,恢复游戏状态
|
|
717
|
+
4. **无缝体验**: 提供平滑的重连体验
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
## 数据格式说明
|
|
722
|
+
|
|
723
|
+
### 位置坐标
|
|
724
|
+
- 格式: `[x, y, z]`
|
|
725
|
+
- 类型: 数字数组
|
|
726
|
+
- 范围: -1000 到 1000
|
|
727
|
+
|
|
728
|
+
### 旋转四元数
|
|
729
|
+
- 格式: `[x, y, z, w]`
|
|
730
|
+
- 类型: 数字数组
|
|
731
|
+
- 要求: 单位四元数(x² + y² + z² + w² = 1)
|
|
732
|
+
|
|
733
|
+
### 动画名称
|
|
734
|
+
- 格式: 字符串
|
|
735
|
+
- 长度: 最大50个字符
|
|
736
|
+
- 示例: "idle", "walking", "running", "jumping"
|
|
737
|
+
|
|
738
|
+
### 头像ID
|
|
739
|
+
- 格式: 字符串
|
|
740
|
+
- 长度: 最大50个字符
|
|
741
|
+
- 示例: "default", "warrior", "mage", "archer", "healer"
|
|
742
|
+
- 说明: 由前端系统预定义的头像类型,用户可以选择
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## 版本信息
|
|
747
|
+
|
|
748
|
+
- **API版本**: 1.2.0
|
|
749
|
+
- **最后更新**: 2024年12月
|
|
750
|
+
- **兼容性**: 支持现代浏览器WebSocket API
|
|
751
|
+
- **更新内容**:
|
|
752
|
+
- 添加头像ID同步支持
|
|
753
|
+
- 优化连接生命周期管理
|
|
754
|
+
- 改进数据清理机制
|
|
755
|
+
- 增强错误处理
|
|
756
|
+
- 支持只连接不加入房间的场景
|
|
757
|
+
```
|