feat(network): 基于 TSRPC 的网络同步模块 (#318)
- network-protocols: 共享协议包,使用 TSRPC CLI 生成完整类型验证 - network: 浏览器客户端,提供 NetworkPlugin、NetworkService 和同步系统 - network-server: Node.js 服务端,提供 GameServer 和房间管理
This commit is contained in:
34
packages/network-protocols/src/index.ts
Normal file
34
packages/network-protocols/src/index.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @esengine/network-protocols
|
||||
*
|
||||
* 基于 TSRPC 的共享网络协议
|
||||
* TSRPC-based shared network protocols
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// Service Protocol | 服务协议
|
||||
// ============================================================================
|
||||
|
||||
export { serviceProto } from './shared/protocols/serviceProto';
|
||||
export type { ServiceType } from './shared/protocols/serviceProto';
|
||||
|
||||
// ============================================================================
|
||||
// Types | 类型定义
|
||||
// ============================================================================
|
||||
|
||||
export type { Vec2, IEntityState, IPlayerInput } from './shared/protocols/types';
|
||||
|
||||
// ============================================================================
|
||||
// API Protocols | API 协议
|
||||
// ============================================================================
|
||||
|
||||
export type { ReqJoin, ResJoin } from './shared/protocols/PtlJoin';
|
||||
|
||||
// ============================================================================
|
||||
// Message Protocols | 消息协议
|
||||
// ============================================================================
|
||||
|
||||
export type { MsgSync } from './shared/protocols/MsgSync';
|
||||
export type { MsgInput } from './shared/protocols/MsgInput';
|
||||
export type { MsgSpawn } from './shared/protocols/MsgSpawn';
|
||||
export type { MsgDespawn } from './shared/protocols/MsgDespawn';
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* 销毁实体消息
|
||||
* Despawn entity message
|
||||
*/
|
||||
|
||||
export interface MsgDespawn {
|
||||
/** 网络 ID | Network ID */
|
||||
netId: number;
|
||||
}
|
||||
11
packages/network-protocols/src/shared/protocols/MsgInput.ts
Normal file
11
packages/network-protocols/src/shared/protocols/MsgInput.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* 输入消息
|
||||
* Input message
|
||||
*/
|
||||
|
||||
import type { IPlayerInput } from './types';
|
||||
|
||||
export interface MsgInput {
|
||||
/** 玩家输入 | Player input */
|
||||
input: IPlayerInput;
|
||||
}
|
||||
19
packages/network-protocols/src/shared/protocols/MsgSpawn.ts
Normal file
19
packages/network-protocols/src/shared/protocols/MsgSpawn.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 生成实体消息
|
||||
* Spawn entity message
|
||||
*/
|
||||
|
||||
import type { Vec2 } from './types';
|
||||
|
||||
export interface MsgSpawn {
|
||||
/** 网络 ID | Network ID */
|
||||
netId: number;
|
||||
/** 所有者客户端 ID | Owner client ID */
|
||||
ownerId: number;
|
||||
/** 预制体类型 | Prefab type */
|
||||
prefab: string;
|
||||
/** 初始位置 | Initial position */
|
||||
pos: Vec2;
|
||||
/** 初始旋转 | Initial rotation */
|
||||
rot: number;
|
||||
}
|
||||
13
packages/network-protocols/src/shared/protocols/MsgSync.ts
Normal file
13
packages/network-protocols/src/shared/protocols/MsgSync.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 状态同步消息
|
||||
* State sync message
|
||||
*/
|
||||
|
||||
import type { IEntityState } from './types';
|
||||
|
||||
export interface MsgSync {
|
||||
/** 服务器时间戳 | Server timestamp */
|
||||
time: number;
|
||||
/** 实体状态列表 | Entity state list */
|
||||
entities: IEntityState[];
|
||||
}
|
||||
28
packages/network-protocols/src/shared/protocols/PtlJoin.ts
Normal file
28
packages/network-protocols/src/shared/protocols/PtlJoin.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 加入房间 API
|
||||
* Join room API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 加入请求
|
||||
* Join request
|
||||
*/
|
||||
export interface ReqJoin {
|
||||
/** 玩家名称 | Player name */
|
||||
playerName: string;
|
||||
/** 房间 ID(可选,不传则自动匹配)| Room ID (optional, auto-match if not provided) */
|
||||
roomId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入响应
|
||||
* Join response
|
||||
*/
|
||||
export interface ResJoin {
|
||||
/** 分配的客户端 ID | Assigned client ID */
|
||||
clientId: number;
|
||||
/** 房间 ID | Room ID */
|
||||
roomId: string;
|
||||
/** 房间当前玩家数 | Current player count in room */
|
||||
playerCount: number;
|
||||
}
|
||||
268
packages/network-protocols/src/shared/protocols/serviceProto.ts
Normal file
268
packages/network-protocols/src/shared/protocols/serviceProto.ts
Normal file
@@ -0,0 +1,268 @@
|
||||
import { ServiceProto } from 'tsrpc-proto';
|
||||
import { MsgDespawn } from './MsgDespawn';
|
||||
import { MsgInput } from './MsgInput';
|
||||
import { MsgSpawn } from './MsgSpawn';
|
||||
import { MsgSync } from './MsgSync';
|
||||
import { ReqJoin, ResJoin } from './PtlJoin';
|
||||
|
||||
export interface ServiceType {
|
||||
api: {
|
||||
"Join": {
|
||||
req: ReqJoin,
|
||||
res: ResJoin
|
||||
}
|
||||
},
|
||||
msg: {
|
||||
"Despawn": MsgDespawn,
|
||||
"Input": MsgInput,
|
||||
"Spawn": MsgSpawn,
|
||||
"Sync": MsgSync
|
||||
}
|
||||
}
|
||||
|
||||
export const serviceProto: ServiceProto<ServiceType> = {
|
||||
"services": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Despawn",
|
||||
"type": "msg"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Input",
|
||||
"type": "msg"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Spawn",
|
||||
"type": "msg"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Sync",
|
||||
"type": "msg"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Join",
|
||||
"type": "api"
|
||||
}
|
||||
],
|
||||
"types": {
|
||||
"MsgDespawn/MsgDespawn": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "netId",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"MsgInput/MsgInput": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "input",
|
||||
"type": {
|
||||
"type": "Reference",
|
||||
"target": "types/IPlayerInput"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"types/IPlayerInput": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "frame",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "moveDir",
|
||||
"type": {
|
||||
"type": "Reference",
|
||||
"target": "types/Vec2"
|
||||
},
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "actions",
|
||||
"type": {
|
||||
"type": "Array",
|
||||
"elementType": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"types/Vec2": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "x",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "y",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"MsgSpawn/MsgSpawn": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "netId",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "ownerId",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "prefab",
|
||||
"type": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "pos",
|
||||
"type": {
|
||||
"type": "Reference",
|
||||
"target": "types/Vec2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "rot",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"MsgSync/MsgSync": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "time",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "entities",
|
||||
"type": {
|
||||
"type": "Array",
|
||||
"elementType": {
|
||||
"type": "Reference",
|
||||
"target": "types/IEntityState"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"types/IEntityState": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "netId",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "pos",
|
||||
"type": {
|
||||
"type": "Reference",
|
||||
"target": "types/Vec2"
|
||||
},
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "rot",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
},
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"PtlJoin/ReqJoin": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "playerName",
|
||||
"type": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "roomId",
|
||||
"type": {
|
||||
"type": "String"
|
||||
},
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"PtlJoin/ResJoin": {
|
||||
"type": "Interface",
|
||||
"properties": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "clientId",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "roomId",
|
||||
"type": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "playerCount",
|
||||
"type": {
|
||||
"type": "Number"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
39
packages/network-protocols/src/shared/protocols/types.ts
Normal file
39
packages/network-protocols/src/shared/protocols/types.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 共享类型定义
|
||||
* Shared type definitions
|
||||
*/
|
||||
|
||||
/**
|
||||
* 二维向量
|
||||
* 2D Vector
|
||||
*/
|
||||
export interface Vec2 {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体状态
|
||||
* Entity state
|
||||
*/
|
||||
export interface IEntityState {
|
||||
/** 网络 ID | Network ID */
|
||||
netId: number;
|
||||
/** 位置 | Position */
|
||||
pos?: Vec2;
|
||||
/** 旋转角度(弧度)| Rotation (radians) */
|
||||
rot?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家输入
|
||||
* Player input
|
||||
*/
|
||||
export interface IPlayerInput {
|
||||
/** 帧号 | Frame number */
|
||||
frame: number;
|
||||
/** 移动方向 | Move direction */
|
||||
moveDir?: Vec2;
|
||||
/** 动作列表 | Action list */
|
||||
actions?: string[];
|
||||
}
|
||||
Reference in New Issue
Block a user