Commit a2acc28c authored by nanahira's avatar nanahira

add hide player names

parent 71b4a5d1
Pipeline #43261 failed with stages
in 100 minutes and 52 seconds
......@@ -53,6 +53,7 @@ windbotEndpoint: http://127.0.0.1:2399
windbotMyIp: 127.0.0.1
enableReconnect: 1
reconnectTimeout: 180000
hidePlayerName: 0
enableRandomDuel: 1
randomDuelBlankPassModes:
- S
......
......@@ -117,20 +117,27 @@ export class Client {
private sendQueue = new PQueue({ concurrency: 1 });
async send(data: YGOProStocBase) {
if (this.disconnected) {
return;
async send(data: YGOProStocBase, noDispatch = false) {
if (!noDispatch) {
const dispatched = await this.ctx.dispatch(data, this);
if (!data) {
return;
}
data = dispatched!;
}
const logMsg = data instanceof YGOProStocGameMsg ? data.msg : data;
this.logger.debug(
{
msgName: logMsg?.constructor.name,
client: this.name || this.loggingIp(),
payload: JSON.stringify(logMsg),
},
'Sending message to client',
);
return this.sendQueue.add(async () => {
const logMsg = data instanceof YGOProStocGameMsg ? data.msg : data;
this.logger.debug(
{
msgName: logMsg?.constructor.name,
client: this.name || this.loggingIp(),
payload: JSON.stringify(logMsg),
},
'Sending message to client',
);
if (this.disconnected) {
return;
}
try {
await this._send(Buffer.from(data.toFullPayload()));
} catch (e) {
......
......@@ -125,6 +125,10 @@ export const defaultConfig = {
ENABLE_RECONNECT: '1',
// Reconnect timeout after disconnect. Format: integer string in milliseconds (ms).
RECONNECT_TIMEOUT: '180000',
// Hide player name mode in random duel rooms.
// Format: integer string.
// 0 = disabled, 1 = hide only at Begin stage, 2 = always hide.
HIDE_PLAYER_NAME: '0',
// Enable random duel feature.
// Boolean parse rule (default false): ''/'0'/'false'/'null' => false, otherwise true.
ENABLE_RANDOM_DUEL: '1',
......
......@@ -11,9 +11,11 @@ import { WaitForPlayerProvider } from './wait-for-player-provider';
import { ResourceModule } from './resource';
import { MenuManager } from './menu-manager';
import { ClientKeyProvider } from './client-key-provider';
import { HidePlayerNameProvider } from './hide-player-name-provider';
export const FeatsModule = createAppContext<ContextState>()
.provide(ClientKeyProvider)
.provide(HidePlayerNameProvider)
.provide(MenuManager)
.provide(ClientVersionCheck)
.provide(Welcome)
......
import { NetPlayerType, YGOProStocHsPlayerEnter } from 'ygopro-msg-encode';
import { Context } from '../app';
import { DuelStage, OnRoomGameStart, RoomManager } from '../room';
declare module '../room' {
interface Room {
hidePlayerNames?: boolean;
}
}
export class HidePlayerNameProvider {
private roomManager = this.ctx.get(() => RoomManager);
private hidePlayerNameMode = this.resolveMode();
constructor(private ctx: Context) {
if (!this.enabled) {
return;
}
this.ctx.middleware(YGOProStocHsPlayerEnter, async (msg, client, next) => {
if (!client.roomName) {
return next();
}
const room = this.roomManager.findByName(client.roomName);
if (!room?.hidePlayerNames || !this.shouldHide(room.duelStage)) {
return next();
}
const pos = msg.pos ?? -1;
if (
pos < 0 ||
pos >= NetPlayerType.OBSERVER ||
pos === client.pos ||
!msg.name
) {
return next();
}
msg.name = `Player ${pos + 1}`;
return next();
});
this.ctx.middleware(OnRoomGameStart, async (event, _client, next) => {
if (
this.hidePlayerNameMode !== 1 ||
!event.room.hidePlayerNames ||
event.room.duelRecords.length !== 0
) {
return next();
}
for (const sightPlayer of event.room.allPlayers) {
for (const player of event.room.playingPlayers) {
if (player === sightPlayer) {
continue;
}
await sightPlayer.send(
new YGOProStocHsPlayerEnter().fromPartial({
name: player.name,
pos: player.pos,
}),
true,
);
}
}
return next();
});
}
get enabled() {
return this.hidePlayerNameMode > 0;
}
private shouldHide(stage: DuelStage) {
if (this.hidePlayerNameMode === 2) {
return true;
}
return this.hidePlayerNameMode === 1 && stage === DuelStage.Begin;
}
private resolveMode() {
const mode = this.ctx.config.getInt('HIDE_PLAYER_NAME');
if (mode === 1 || mode === 2) {
return mode;
}
return 0;
}
}
export * from './client-version-check';
export * from './client-key-provider';
export * from './hide-player-name-provider';
export * from './menu-manager';
export * from './welcome';
export * from './random-duel';
......
......@@ -25,6 +25,7 @@ import {
import { CanReconnectCheck } from '../reconnect';
import { WaitForPlayerProvider } from '../wait-for-player-provider';
import { ClientKeyProvider } from '../client-key-provider';
import { HidePlayerNameProvider } from '../hide-player-name-provider';
import { RandomDuelScore } from './score.entity';
import {
formatRemainText,
......@@ -96,6 +97,7 @@ export class RandomDuelProvider {
private roomManager = this.ctx.get(() => RoomManager);
private waitForPlayerProvider = this.ctx.get(() => WaitForPlayerProvider);
private clientKeyProvider = this.ctx.get(() => ClientKeyProvider);
private hidePlayerNameProvider = this.ctx.get(() => HidePlayerNameProvider);
enabled = this.ctx.config.getBoolean('ENABLE_RANDOM_DUEL');
noRematchCheck = this.ctx.config.getBoolean('RANDOM_DUEL_NO_REMATCH_CHECK');
......@@ -239,6 +241,7 @@ export class RandomDuelProvider {
if (found) {
const foundType = found.randomType || type || this.defaultType;
found.randomType = foundType;
found.hidePlayerNames = this.hidePlayerNameProvider.enabled;
found.randomDuelDeprecated = joinState.deprecated;
found.checkChatBadword = true;
found.noHost = true;
......@@ -255,6 +258,7 @@ export class RandomDuelProvider {
}
const room = await this.roomManager.findOrCreateByName(roomName);
room.randomType = randomType;
room.hidePlayerNames = this.hidePlayerNameProvider.enabled;
room.randomDuelDeprecated = joinState.deprecated;
room.checkChatBadword = true;
room.noHost = true;
......
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