Commit c33d8afa authored by nanahira's avatar nanahira

sort some room fields

parent 0899179e
# 项目情况
本项目是 SRVPro(YGOPro 服务器)项目的下一代项目。
## 项目规范
- 非必要不要在 Room 和 Client 里面加字段或者方法。如果可以的话请使用定义 interface 进行依赖合并。
- 进行协议设计需要核对 ygopro 和 srvpro 的 coffee 和 cpp 的实现。
- 尽量定义新的模块实现功能,而不是在之前的方法上进行修改。
## 参考项目
可以参考电脑的下面的项目,用来参考
- ygopro-msg-encode(js 协议库): ~/ygo/ygopro-msg-encode
- koishipro-core.js(wasm 层): ~/ygo/koishipro-core.js
- ocgcore(YGOPro ocgcore 内核): ~/ygo/ygopro/ocgcore
- ygopro(YGOPro 主程序服务端): ~/ygo/ygopro/gframe
- srvpro(本项目的上一代): ~/ygo/ygopro/srvpro-koishi
- yuzuthread(多线程执行器): ~/test/yuzuthread
- typed-reflector(反射器): ~/test/koishi-related/typed-reflector
- nfkit(工具库,事件触发器,IoC): ~/test/nfkit
export * from './client';
export * from './room';
import { Awaitable, ProtoMiddlewareDispatcher } from 'nfkit'; import { Awaitable, MayBeArray, ProtoMiddlewareDispatcher } from 'nfkit';
import { Context } from '../app'; import { Context } from '../app';
import BetterLock from 'better-lock'; import BetterLock from 'better-lock';
import { import {
...@@ -90,6 +90,7 @@ import { isUpdateMessage } from '../utility/is-update-message'; ...@@ -90,6 +90,7 @@ import { isUpdateMessage } from '../utility/is-update-message';
import { getMessageIdentifier } from '../utility/get-message-identifier'; import { getMessageIdentifier } from '../utility/get-message-identifier';
import { canIncreaseTime } from '../utility/can-increase-time'; import { canIncreaseTime } from '../utility/can-increase-time';
import { TimerState } from './timer-state'; import { TimerState } from './timer-state';
import { makeArray } from 'aragami/dist/src/utility/utility';
const { OcgcoreScriptConstants } = _OcgcoreConstants; const { OcgcoreScriptConstants } = _OcgcoreConstants;
...@@ -1194,10 +1195,10 @@ export class Room { ...@@ -1194,10 +1195,10 @@ export class Room {
this.phase = undefined; this.phase = undefined;
this.resetDuelTimerState(); this.resetDuelTimerState();
await this.handleGameMsg(watcherMsg.msg); await this.dispatchGameMsg(watcherMsg.msg);
await this.ctx.dispatch( await this.ctx.dispatch(
new OnRoomDuelStart(this), new OnRoomDuelStart(this),
this.getOperatingPlayer(this.turnIngamePos), this.gatIngameOperatingPlayer(this.turnIngamePos),
); );
await Promise.all([ await Promise.all([
...@@ -1232,7 +1233,7 @@ export class Room { ...@@ -1232,7 +1233,7 @@ export class Room {
this.phase = phase; this.phase = phase;
} }
getOperatingPlayer(ingameDuelPos: number): Client | undefined { gatIngameOperatingPlayer(ingameDuelPos: number): Client | undefined {
const players = this.getIngameDuelPosPlayers(ingameDuelPos); const players = this.getIngameDuelPosPlayers(ingameDuelPos);
if (!this.isTag) { if (!this.isTag) {
return players[0]; return players[0];
...@@ -1257,7 +1258,10 @@ export class Room { ...@@ -1257,7 +1258,10 @@ export class Room {
return players[0]; return players[0];
} }
private async refreshLocations(refresh: RequireQueryLocation) { private async refreshLocations(
refresh: RequireQueryLocation,
options: { queryFlag?: number; sendToClient?: MayBeArray<Client> } = {},
) {
if (!this.ocgcore) { if (!this.ocgcore) {
return; return;
} }
...@@ -1266,16 +1270,16 @@ export class Room { ...@@ -1266,16 +1270,16 @@ export class Room {
const { cards } = await this.ocgcore.queryFieldCard({ const { cards } = await this.ocgcore.queryFieldCard({
player: refresh.player, player: refresh.player,
location, location,
queryFlag: getZoneQueryFlag(location), queryFlag: options.queryFlag ?? getZoneQueryFlag(location),
useCache: 1, useCache: 1,
}); });
await this.handleGameMsg( await this.dispatchGameMsg(
new YGOProMsgUpdateData().fromPartial({ new YGOProMsgUpdateData().fromPartial({
player: refresh.player, player: refresh.player,
location, location,
cards: cards ?? [], cards: cards ?? [],
}), }),
true, { sendToClient: options.sendToClient, route: true },
); );
} }
} }
...@@ -1296,7 +1300,7 @@ export class Room { ...@@ -1296,7 +1300,7 @@ export class Room {
OcgcoreCommonConstants.QUERY_POSITION, OcgcoreCommonConstants.QUERY_POSITION,
useCache: 0, useCache: 0,
}); });
await this.handleGameMsg( await this.dispatchGameMsg(
new YGOProMsgUpdateCard().fromPartial({ new YGOProMsgUpdateCard().fromPartial({
controller: refresh.player, controller: refresh.player,
location, location,
...@@ -1325,7 +1329,7 @@ export class Room { ...@@ -1325,7 +1329,7 @@ export class Room {
} }
private async sendWaitingToNonOperator(ingameDuelPos: number) { private async sendWaitingToNonOperator(ingameDuelPos: number) {
const operatingPlayer = this.getOperatingPlayer(ingameDuelPos); const operatingPlayer = this.gatIngameOperatingPlayer(ingameDuelPos);
const noOps = this.playingPlayers.filter((p) => p !== operatingPlayer); const noOps = this.playingPlayers.filter((p) => p !== operatingPlayer);
await Promise.all( await Promise.all(
noOps.map((p) => noOps.map((p) =>
...@@ -1338,7 +1342,10 @@ export class Room { ...@@ -1338,7 +1342,10 @@ export class Room {
); );
} }
private async routeGameMsg(message: YGOProMsgBase) { private async routeGameMsg(
message: YGOProMsgBase,
options: { sendToClient?: MayBeArray<Client> } = {},
) {
if (!message) { if (!message) {
return; return;
} }
...@@ -1351,6 +1358,9 @@ export class Room { ...@@ -1351,6 +1358,9 @@ export class Room {
const sendTargets = message.getSendTargets(); const sendTargets = message.getSendTargets();
const sendGameMsg = (c: Client, msg: YGOProMsgBase) => const sendGameMsg = (c: Client, msg: YGOProMsgBase) =>
c.send(new YGOProStocGameMsg().fromPartial({ msg })); c.send(new YGOProStocGameMsg().fromPartial({ msg }));
const sendToClients = options.sendToClient
? new Set(makeArray(options.sendToClient))
: undefined;
await Promise.all( await Promise.all(
sendTargets.map(async (pos) => { sendTargets.map(async (pos) => {
if (pos === NetPlayerType.OBSERVER) { if (pos === NetPlayerType.OBSERVER) {
...@@ -1361,10 +1371,13 @@ export class Room { ...@@ -1361,10 +1371,13 @@ export class Room {
} else { } else {
const players = this.getIngameDuelPosPlayers(pos); const players = this.getIngameDuelPosPlayers(pos);
await Promise.all( await Promise.all(
players.map((c) => { players.map(async (c) => {
if (sendToClients && !sendToClients.has(c)) {
return;
}
const duelPos = this.getIngameDuelPos(c); const duelPos = this.getIngameDuelPos(c);
const playerView = message.playerView(duelPos); const playerView = message.playerView(duelPos);
const operatingPlayer = this.getOperatingPlayer(duelPos); const operatingPlayer = this.gatIngameOperatingPlayer(duelPos);
return sendGameMsg( return sendGameMsg(
c, c,
c === operatingPlayer ? playerView : playerView.teammateView(), c === operatingPlayer ? playerView : playerView.teammateView(),
...@@ -1407,16 +1420,23 @@ export class Room { ...@@ -1407,16 +1420,23 @@ export class Room {
} }
} }
private async handleGameMsg(message: YGOProMsgBase, route = false) { async dispatchGameMsg(
const msg1 = await this.localGameMsgDispatcher.dispatch(message); message: YGOProMsgBase,
const msg2 = await this.ctx.dispatch( options: { sendToClient?: MayBeArray<Client>; route?: boolean } = {},
msg1, ) {
this.getOperatingPlayer(this.turnIngamePos), if (!options.sendToClient) {
message = await this.localGameMsgDispatcher.dispatch(message);
message = await this.ctx.dispatch(
message,
this.gatIngameOperatingPlayer(this.turnIngamePos),
); );
if (route) {
await this.routeGameMsg(msg2);
} }
return msg2; if (options.route) {
await this.routeGameMsg(message, {
sendToClient: options.sendToClient,
});
}
return message;
} }
localGameMsgDispatcher = new ProtoMiddlewareDispatcher({ localGameMsgDispatcher = new ProtoMiddlewareDispatcher({
...@@ -1455,7 +1475,7 @@ export class Room { ...@@ -1455,7 +1475,7 @@ export class Room {
}) })
.middleware(YGOProMsgRetry, async (message, next) => { .middleware(YGOProMsgRetry, async (message, next) => {
if (this.responsePos != null) { if (this.responsePos != null) {
const op = this.getOperatingPlayer( const op = this.gatIngameOperatingPlayer(
this.getIngameDuelPosByDuelPos(this.responsePos), this.getIngameDuelPosByDuelPos(this.responsePos),
); );
await op.send( await op.send(
...@@ -1495,7 +1515,7 @@ export class Room { ...@@ -1495,7 +1515,7 @@ export class Room {
continue; continue;
} }
const handled = await this.handleGameMsg(message); const handled = await this.dispatchGameMsg(message);
if (handled instanceof YGOProMsgWin) { if (handled instanceof YGOProMsgWin) {
return this.win(handled); return this.win(handled);
} }
...@@ -1524,7 +1544,9 @@ export class Room { ...@@ -1524,7 +1544,9 @@ export class Room {
} }
if ( if (
client !== client !==
this.getOperatingPlayer(this.getIngameDuelPosByDuelPos(this.responsePos)) this.gatIngameOperatingPlayer(
this.getIngameDuelPosByDuelPos(this.responsePos),
)
) { ) {
return; return;
} }
...@@ -1557,7 +1579,7 @@ export class Room { ...@@ -1557,7 +1579,7 @@ export class Room {
if ( if (
this.responsePos == null || this.responsePos == null ||
client !== client !==
this.getOperatingPlayer( this.gatIngameOperatingPlayer(
this.getIngameDuelPosByDuelPos(this.responsePos), this.getIngameDuelPosByDuelPos(this.responsePos),
) || ) ||
!this.ocgcore !this.ocgcore
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment