refactor: reorganize package structure and decouple framework packages (#338)

* refactor: reorganize package structure and decouple framework packages

## Package Structure Reorganization
- Reorganized 55 packages into categorized subdirectories:
  - packages/framework/ - Generic framework (Laya/Cocos compatible)
  - packages/engine/ - ESEngine core modules
  - packages/rendering/ - Rendering modules (WASM dependent)
  - packages/physics/ - Physics modules
  - packages/streaming/ - World streaming
  - packages/network-ext/ - Network extensions
  - packages/editor/ - Editor framework and plugins
  - packages/rust/ - Rust WASM engine
  - packages/tools/ - Build tools and SDK

## Framework Package Decoupling
- Decoupled behavior-tree and blueprint packages from ESEngine dependencies
- Created abstracted interfaces (IBTAssetManager, IBehaviorTreeAssetContent)
- ESEngine-specific code moved to esengine/ subpath exports
- Framework packages now usable with Cocos/Laya without ESEngine

## CI Configuration
- Updated CI to only type-check and lint framework packages
- Added type-check:framework and lint:framework scripts

## Breaking Changes
- Package import paths changed due to directory reorganization
- ESEngine integrations now use subpath imports (e.g., '@esengine/behavior-tree/esengine')

* fix: update es-engine file path after directory reorganization

* docs: update README to focus on framework over engine

* ci: only build framework packages, remove Rust/WASM dependencies

* fix: remove esengine subpath from behavior-tree and blueprint builds

ESEngine integration code will only be available in full engine builds.
Framework packages are now purely engine-agnostic.

* fix: move network-protocols to framework, build both in CI

* fix: update workflow paths from packages/core to packages/framework/core

* fix: exclude esengine folder from type-check in behavior-tree and blueprint

* fix: update network tsconfig references to new paths

* fix: add test:ci:framework to only test framework packages in CI

* fix: only build core and math npm packages in CI

* fix: exclude test files from CodeQL and fix string escaping security issue
This commit is contained in:
YHH
2025-12-26 14:50:35 +08:00
committed by GitHub
parent a84ff902e4
commit 155411e743
1936 changed files with 4147 additions and 11578 deletions

View File

@@ -0,0 +1,214 @@
/**
* @zh 意图收集器
* @en Intent Collector
*
* @zh 收集玩家蓝图执行过程中产生的所有意图
* @en Collects all intents generated during player blueprint execution
*/
import type { IIntent, IntentKeyExtractor } from './IntentTypes';
import { defaultIntentKeyExtractor } from './IntentTypes';
/**
* @zh 意图收集器接口
* @en Intent collector interface
*/
export interface IIntentCollector<T extends IIntent = IIntent> {
/**
* @zh 添加一个意图
* @en Add an intent
*/
addIntent(intent: T): boolean;
/**
* @zh 获取所有收集的意图
* @en Get all collected intents
*/
getIntents(): T[];
/**
* @zh 按类型获取意图
* @en Get intents by type
*/
getIntentsByType(type: string): T[];
/**
* @zh 清除所有意图
* @en Clear all intents
*/
clear(): void;
/**
* @zh 获取意图数量
* @en Get intent count
*/
readonly count: number;
}
/**
* @zh 意图收集器
* @en Intent Collector
*
* @zh 在蓝图执行过程中收集玩家的操作意图,执行完成后由服务器统一处理
* @en Collects player operation intents during blueprint execution, processed by server after execution
*
* @typeParam T - @zh 意图类型,必须继承 IIntent @en Intent type, must extend IIntent
*
* @example
* ```typescript
* // 游戏项目中定义意图类型 | Define intent types in game project
* interface MyGameIntent extends IIntent {
* readonly type: 'unit.move' | 'unit.attack';
* unitId: string;
* }
*
* // 创建收集器时提供键提取器 | Provide key extractor when creating collector
* const collector = new IntentCollector<MyGameIntent>('player1', {
* keyExtractor: (intent) => `${intent.type}:${intent.unitId}`
* });
*
* collector.addIntent({ type: 'unit.move', unitId: 'unit1' });
* ```
*/
export class IntentCollector<T extends IIntent = IIntent> implements IIntentCollector<T> {
/**
* @zh 玩家 ID
* @en Player ID
*/
private readonly _playerId: string;
/**
* @zh 当前 tick
* @en Current tick
*/
private _currentTick: number = 0;
/**
* @zh 收集的意图列表
* @en Collected intents list
*/
private _intents: T[] = [];
/**
* @zh 按类型索引的意图
* @en Intents indexed by type
*/
private _intentsByType: Map<string, T[]> = new Map();
/**
* @zh 已添加的意图键(防止重复)
* @en Added intent keys (prevent duplicates)
*/
private _intentKeys: Set<string> = new Set();
/**
* @zh 意图键提取器
* @en Intent key extractor
*/
private readonly _keyExtractor: IntentKeyExtractor<T>;
/**
* @param playerId - @zh 玩家 ID @en Player ID
* @param options - @zh 配置选项 @en Configuration options
*/
constructor(
playerId: string,
options: {
keyExtractor?: IntentKeyExtractor<T>;
} = {}
) {
this._playerId = playerId;
this._keyExtractor = options.keyExtractor ?? (defaultIntentKeyExtractor as IntentKeyExtractor<T>);
}
/**
* @zh 获取意图数量
* @en Get intent count
*/
get count(): number {
return this._intents.length;
}
/**
* @zh 获取玩家 ID
* @en Get player ID
*/
get playerId(): string {
return this._playerId;
}
/**
* @zh 设置当前 tick
* @en Set current tick
*/
setTick(tick: number): void {
this._currentTick = tick;
}
/**
* @zh 添加一个意图
* @en Add an intent
*
* @param intent - @zh 要添加的意图 @en Intent to add
* @returns @zh 是否添加成功(重复意图返回 false@en Whether added successfully (duplicate returns false)
*/
addIntent(intent: T): boolean {
const key = this._keyExtractor(intent);
if (this._intentKeys.has(key)) {
return false;
}
// 添加元数据 | Add metadata
const intentWithMeta: T = {
...intent,
playerId: this._playerId,
tick: this._currentTick
};
this._intents.push(intentWithMeta);
this._intentKeys.add(key);
// 按类型索引 | Index by type
if (!this._intentsByType.has(intent.type)) {
this._intentsByType.set(intent.type, []);
}
this._intentsByType.get(intent.type)!.push(intentWithMeta);
return true;
}
/**
* @zh 获取所有收集的意图
* @en Get all collected intents
*/
getIntents(): T[] {
return [...this._intents];
}
/**
* @zh 按类型获取意图
* @en Get intents by type
*/
getIntentsByType(type: string): T[] {
return [...(this._intentsByType.get(type) ?? [])];
}
/**
* @zh 检查是否已有指定键的意图
* @en Check if intent with specified key exists
*/
hasIntentKey(key: string): boolean {
return this._intentKeys.has(key);
}
/**
* @zh 清除所有意图
* @en Clear all intents
*/
clear(): void {
this._intents = [];
this._intentsByType.clear();
this._intentKeys.clear();
}
}

View File

@@ -0,0 +1,138 @@
/**
* @zh 意图类型定义(引擎基础接口)
* @en Intent type definitions (engine base interface)
*
* @zh 引擎只提供基础的 IIntent 接口,具体的意图类型由游戏项目定义
* @en Engine only provides base IIntent interface, specific intent types are defined by game projects
*/
// =============================================================================
// 基础意图接口 | Base Intent Interface
// =============================================================================
/**
* @zh 基础意图接口
* @en Base intent interface
*
* @zh 所有游戏意图都应该继承这个接口
* @en All game intents should extend this interface
*
* @example
* ```typescript
* // 游戏项目中定义具体意图 | Define specific intents in game project
* interface UnitMoveIntent extends IIntent {
* readonly type: 'unit.move';
* unitId: string;
* direction: number;
* }
* ```
*/
export interface IIntent {
/**
* @zh 意图类型(唯一标识符)
* @en Intent type (unique identifier)
*/
readonly type: string;
/**
* @zh 发起者玩家 ID由 IntentCollector 自动填充)
* @en Originator player ID (auto-filled by IntentCollector)
*/
playerId?: string;
/**
* @zh 产生时的 tick由 IntentCollector 自动填充)
* @en Tick when generated (auto-filled by IntentCollector)
*/
tick?: number;
}
// =============================================================================
// 意图键提取器 | Intent Key Extractor
// =============================================================================
/**
* @zh 意图键提取器函数类型
* @en Intent key extractor function type
*
* @zh 用于从意图中提取唯一键,防止同一对象重复操作
* @en Used to extract unique key from intent, preventing duplicate operations on same object
*/
export type IntentKeyExtractor<T extends IIntent = IIntent> = (intent: T) => string;
/**
* @zh 默认的意图键提取器(只使用 type
* @en Default intent key extractor (uses type only)
*/
export const defaultIntentKeyExtractor: IntentKeyExtractor = (intent) => intent.type;
// =============================================================================
// 通用结果常量 | Common Result Constants
// =============================================================================
/**
* @zh 操作成功
* @en Operation successful
*/
export const OK = 0;
/**
* @zh 通用错误
* @en Generic error
*/
export const ERR_GENERIC = -1;
/**
* @zh 不是所有者
* @en Not the owner
*/
export const ERR_NOT_OWNER = -2;
/**
* @zh 目标无效
* @en Invalid target
*/
export const ERR_INVALID_TARGET = -3;
/**
* @zh 不在范围内
* @en Not in range
*/
export const ERR_NOT_IN_RANGE = -4;
/**
* @zh 资源不足
* @en Not enough resources
*/
export const ERR_NOT_ENOUGH_RESOURCES = -5;
/**
* @zh 正忙
* @en Currently busy
*/
export const ERR_BUSY = -6;
/**
* @zh 参数无效
* @en Invalid arguments
*/
export const ERR_INVALID_ARGS = -7;
// =============================================================================
// 通用方向常量 | Common Direction Constants
// =============================================================================
export const TOP = 1;
export const TOP_RIGHT = 2;
export const RIGHT = 3;
export const BOTTOM_RIGHT = 4;
export const BOTTOM = 5;
export const BOTTOM_LEFT = 6;
export const LEFT = 7;
export const TOP_LEFT = 8;
/**
* @zh 方向类型
* @en Direction type
*/
export type Direction = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;