Skip to content

Commit

Permalink
type: 减少样板代码,提升关卡编写typing
Browse files Browse the repository at this point in the history
  • Loading branch information
median-dxz committed Jul 4, 2024
1 parent f5d8209 commit 2799020
Show file tree
Hide file tree
Showing 60 changed files with 1,495 additions and 1,819 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

当前更新内容 模组安装与管理(2024.6)

- [ ] https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#the-configdir-template-variable-for-configuration-files
- [ ] 升级sdk的ts版本
- [ ] 验证第五和魂印判断的正确性
- [ ] sdk 中 core 版本兼容性检测, 添加 core 版本字段(必填), 并规范 launcher 的 core 实例和 sdk 使用的 api 之间的关系
- [ ] 需要一次性提供 Launcher Api 版本,Core 版本和自身版本
Expand Down
1 change: 0 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default tsEslint.config(
'**/\\.*rc',
'**/*.config.*',
'packages/core/types/',
'packages/launcher/core-e2e-test/',
'packages/launcher/build-plugins/',
'packages/server/entry/',
'packages/server/mods/',
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,28 @@
"server:run": "pnpm -C ./packages/server run start",
"launcher:dev": "pnpm -C ./packages/launcher run dev",
"core:build": "pnpm --filter \"@sea/core\" run build",
"tsc:build": "tsc --build --verbose",
"workspace:build": "node ./scripts/build-server.js",
"workspace:sync": "node ./scripts/sync.js",
"release": "node ./scripts/release.js",
"prepare": "husky"
},
"devDependencies": {
"@eslint/js": "^9.5.0",
"@eslint/js": "^9.6.0",
"@types/eslint__js": "^8.42.3",
"@types/node": "^20.14.7",
"@vitest/coverage-v8": "2.0.0-beta.12",
"concurrently": "^8.2.2",
"eslint": "^9.5.0",
"eslint": "^9.6.0",
"eslint-plugin-react-hooks": "5.1.0-rc-8971381549-20240625",
"eslint-plugin-react-refresh": "^0.4.7",
"globals": "^15.6.0",
"globals": "^15.8.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.7",
"prettier": "^3.3.2",
"rimraf": "^5.0.7",
"typescript": "^5.5.2",
"typescript": "^5.5.3",
"typescript-eslint": "8.0.0-alpha.34",
"vite": "^5.3.1",
"vite": "^5.3.2",
"vitest": "2.0.0-beta.12"
},
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/battle/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type { ILevelBattle, ILevelRunner } from './level/types.js';
export type { LevelBattle, LevelRunner } from './level/types.js';
export type { Trigger } from './manager.js';
export type { RoundData } from './provider.js';
export type { Matcher, MoveHandler, MoveStrategy } from './strategy.js';
Expand Down
12 changes: 6 additions & 6 deletions packages/core/battle/level/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { delay } from '../../common/utils.js';
import { engine } from '../../internal/index.js';
import { spet } from '../../pet-helper/index.js';
import { manager } from '../manager.js';
import type { ILevelRunner } from './types.js';
import type { LevelRunner } from './types.js';

export const LevelAction = {
BATTLE: 'battle' as const,
Expand All @@ -11,15 +11,15 @@ export const LevelAction = {
};

class LevelManager {
private runner: ILevelRunner | null = null;
private runner: LevelRunner | null = null;
lock: Promise<void> | null = null;

get running() {
return this.runner != null;
}

/** 获取当前正在运行的Runner */
getRunner(): ILevelRunner | null {
getRunner(): LevelRunner | null {
return this.runner;
}

Expand All @@ -36,7 +36,7 @@ class LevelManager {
}
}

run(runner: ILevelRunner) {
run(runner: LevelRunner) {
if (this.running) throw new Error('你必须先停止当前Runner的运行!');

this.runner = runner;
Expand Down Expand Up @@ -68,10 +68,10 @@ class LevelManager {
logger('进入对战');
try {
if (!this.runner) throw new Error('关卡已停止运行');
if (!runner.actions.battle) throw new Error('未找指定battle动作');

await manager.takeover(() => {
void runner.actions.battle!.call(runner);
if (!runner.actions['battle']) throw new Error('未指定战斗动作');
void runner.actions['battle'].call(runner);
}, strategy);

logger('对战完成');
Expand Down
17 changes: 7 additions & 10 deletions packages/core/battle/level/types.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
import type { AnyFunction } from 'index.js';
import type { AnyFunction } from '../../common/utils.js';
import type { MoveStrategy } from '../strategy.js';

/** 关卡状态机, 由LevelManager来运行 */
export interface ILevelRunner<TData extends object = object> {
/** 关卡的动态数据 */
data: TData;

/** 关卡能做出的动作 */
actions: Record<string, (<T extends TData, R extends ILevelRunner<T>>(this: R) => Promise<void>) | undefined>;

export interface LevelRunner {
/** 更新关卡动态数据 */
update(): Promise<void>;

/** 获取下一个动作 */
next(): string;

/** 选择对战模型 */
selectLevelBattle?(): ILevelBattle;
selectLevelBattle?(): LevelBattle;

logger: AnyFunction;

/** 关卡能做出的动作 */
actions: Record<string, (() => Promise<void> | void) | undefined> & ThisType<LevelRunner>;
}

/** 对战模型 */
export interface ILevelBattle {
export interface LevelBattle {
/** 行动策略 */
strategy: MoveStrategy;
/** 精灵列表 */
Expand Down
2 changes: 1 addition & 1 deletion packages/core/pet-helper/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { CaughtPet, spet } from './pet.js';
export { PetLocation } from './PetLocation.js';
export { SEAPetStore } from './PetStore.js';
export { CaughtPet, spet } from './pet.js';
7 changes: 6 additions & 1 deletion packages/core/test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@
"baseUrl": ".",
"noEmit": true
},
"include": ["./**/*.ts", "../types"]
"include": ["./**/*.ts", "../types"],
"references": [
{
"path": "../"
}
]
}
9 changes: 3 additions & 6 deletions packages/core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
{
"extends": "../../tsconfig.json",
"extends": "../../tsconfig.common.json",
"compilerOptions": {
"module": "NodeNext",
"target": "es2022",
"module": "nodenext",
"outDir": "dist",
"rootDir": ".",
"baseUrl": ".",
"tsBuildInfoFile": "../../.tsbuildinfo/core.tsbuildinfo",
"declaration": true,
"inlineSourceMap": true,
"declarationMap": true,
"incremental": true,
"composite": true,
"lib": ["ESNext", "DOM"]
// "skipLibCheck": false,
"types": []
},
"include": [
"./types",
Expand Down
28 changes: 0 additions & 28 deletions packages/launcher/core-e2e-test/tsconfig.json

This file was deleted.

14 changes: 0 additions & 14 deletions packages/launcher/core-e2e-test/tsconfig.node.json

This file was deleted.

4 changes: 2 additions & 2 deletions packages/launcher/src/builtin/petFragment/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { PetFragmentLevelDifficulty as Difficulty, ILevelBattle, PetFragmentLevel } from '@sea/core';
import type { PetFragmentLevelDifficulty as Difficulty, LevelBattle, PetFragmentLevel } from '@sea/core';

export interface PetFragmentOption {
id: number;
difficulty: Difficulty;
sweep: boolean;
battle: ILevelBattle[];
battle: LevelBattle[];
}

export type PetFragmentOptionRaw = Omit<PetFragmentOption, 'battle'> & { battle: string[] };
Expand Down
126 changes: 60 additions & 66 deletions packages/launcher/src/builtin/realm/LevelCourageTower.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,73 @@
import type { AnyFunction, ILevelBattle } from '@sea/core';
import type { AnyFunction, LevelBattle } from '@sea/core';
import type { LevelData } from '@sea/mod-type';

import { LevelAction, socket } from '@sea/core';
import type { LevelMeta, LevelData as SEALevelData, TaskRunner } from '@sea/mod-type';
import { task } from '@sea/mod-type';

export interface LevelData extends SEALevelData {
export interface Data extends LevelData {
stimulation: boolean;
rewardReceived: boolean;
}

export interface LevelOption {
stimulation: boolean;
sweep: boolean;
}

export default (logger: AnyFunction, battle: (name: string) => ILevelBattle) => {
class LevelCourageTower implements TaskRunner<LevelData> {
data: LevelData = {
remainingTimes: 0,
progress: 0,
rewardReceived: false,
stimulation: false
};

static readonly meta: LevelMeta = {
export default (logger: AnyFunction, battle: (name: string) => LevelBattle) =>
task({
meta: {
name: '勇者之塔',
maxTimes: 5,
id: 'LevelCourageTower'
};

get meta() {
return LevelCourageTower.meta;
}

get name() {
return LevelCourageTower.meta.name;
}

logger = logger;

constructor(public option: LevelOption) {}

async update() {
const bits = (await socket.bitSet(636, 1000577)).map(Boolean);
const buf = await socket.sendByQueue(42397, [117]);
const realmInfo = new DataView(buf!);

this.data.stimulation = bits[0];
this.data.rewardReceived = bits[1];
this.data.remainingTimes = this.meta.maxTimes - realmInfo.getUint32(8);
}

next(): string {
if (!this.data.rewardReceived) {
if (this.data.remainingTimes > 0) {
return LevelAction.BATTLE;
} else {
return LevelAction.AWARD;
}
},
configSchema: {
stimulation: {
name: '勇者之塔双倍',
type: 'checkbox',
default: false
},
sweep: {
name: '勇者之塔扫荡',
type: 'checkbox',
default: false
}
return LevelAction.STOP;
}
},
runner: (meta, options) => ({
logger,
data: {
remainingTimes: 0,
progress: 0,
rewardReceived: false,
stimulation: false
} as Data,
async update() {
const bits = (await socket.bitSet(636, 1000577)).map(Boolean);
const buf = await socket.sendByQueue(42397, [117]);
const realmInfo = new DataView(buf!);

selectLevelBattle() {
return battle('LevelCourageTower');
}

readonly actions: Record<string, () => Promise<void>> = {
battle: async () => {
await socket.sendByQueue(CommandID.FIGHT_H5_PVE_BOSS, [117, 30, 1]);
this.data.stimulation = bits[0];
this.data.rewardReceived = bits[1];
this.data.remainingTimes = meta.maxTimes - realmInfo.getUint32(8);
},

award: async () => {
await socket.sendByQueue(42395, [117, 4, 0, 0]);
next() {
if (!this.data.rewardReceived) {
if (this.data.remainingTimes > 0) {
return options.sweep ? 'sweep' : LevelAction.BATTLE;
} else {
return LevelAction.AWARD;
}
}
return LevelAction.STOP;
},
selectLevelBattle() {
return battle('LevelCourageTower');
},
actions: {
async battle() {
await socket.sendByQueue(CommandID.FIGHT_H5_PVE_BOSS, [117, 30, 1]);
},
async award() {
await socket.sendByQueue(42395, [117, 4, 0, 0]);
},
async sweep() {
// TODO
}
}
};
}

return LevelCourageTower;
};
})
});
Loading

0 comments on commit 2799020

Please sign in to comment.