Commit 71b4a5d1 authored by nanahira's avatar nanahira

rework random duel fleefree

parent 93745262
......@@ -222,6 +222,7 @@ export class Client {
deck?: YGOProDeck;
@ClientRoomField()
startDeck?: YGOProDeck;
fleeFree = false;
async sendTypeChange() {
return this.send(
......
......@@ -70,6 +70,14 @@ export const TRANSLATIONS = {
random_ban_reason_AFK: 'AFK',
random_ban_reason_abuse: 'Abusing',
random_ban_reason_zombie: 'Zombie',
random_score_part1: 'Record of ',
random_score_part2: ': ',
random_score_part3: '% WIN, ',
random_score_part4_combo: '% RAGE QUIT, WIN COMBO ',
random_score_part5_combo: ' !',
random_score_part4: '%',
random_score_blank: " didn't have enough duel record.",
random_score_not_enough: " didn't have enough duel record.",
unwelcome_warn_part1: 'If you keep doing ',
unwelcome_warn_part2: ', your opponent may leave you.',
unwelcome_tip_part1: 'Your opponent did ',
......@@ -160,6 +168,14 @@ export const TRANSLATIONS = {
random_ban_reason_AFK: '挂机',
random_ban_reason_abuse: '发言违规',
random_ban_reason_zombie: '挂房间',
random_score_part1: '',
random_score_part2: '的战绩:胜率',
random_score_part3: '%,逃跑率',
random_score_part4_combo: '%,',
random_score_part5_combo: '连胜中!',
random_score_part4: '%',
random_score_blank: '的战绩:正在统计中',
random_score_not_enough: '的战绩:正在统计中',
unwelcome_warn_part1: '如果您经常',
unwelcome_warn_part2: ',您的对手可能会离你而去。',
unwelcome_tip_part1: '因为您的对手有',
......
......@@ -27,7 +27,6 @@ import { WaitForPlayerProvider } from '../wait-for-player-provider';
import { ClientKeyProvider } from '../client-key-provider';
import { RandomDuelScore } from './score.entity';
import {
buildFleeFreeKey,
formatRemainText,
RandomDuelPunishReason,
renderReasonText,
......@@ -73,13 +72,6 @@ class RandomDuelDisciplineCache {
expireAt = 0;
}
class RandomDuelFleeFreeCache {
@CacheKey()
key!: string;
enabled = false;
}
declare module '../../room' {
interface Room {
randomType?: string;
......@@ -150,6 +142,9 @@ export class RandomDuelProvider {
await this.setAbuseCount(this.getClientKey(client), 0);
}
await this.updateOpponentRelation(event.room, client);
if (event.room.randomType === 'M') {
await this.sendMatchScoreTips(event.room, client);
}
return next();
});
......@@ -186,7 +181,7 @@ export class RandomDuelProvider {
if (
room.turnCount >= RANDOM_DUEL_EARLY_SURRENDER_TURN ||
(room.randomType === 'M' && this.recordMatchScoresEnabled) ||
(await this.isFleeFree(room.name, this.getClientKey(client)))
client.fleeFree
) {
return next();
}
......@@ -428,7 +423,7 @@ export class RandomDuelProvider {
event.bySystem ||
event.oldPos >= NetPlayerType.OBSERVER ||
room.duelStage === DuelStage.Begin ||
(await this.isFleeFree(room.name, this.getClientKey(client)))
client.fleeFree
) {
return;
}
......@@ -505,7 +500,7 @@ export class RandomDuelProvider {
if (player.pos >= NetPlayerType.OBSERVER || player.isInternal) {
return;
}
await this.setFleeFree(room.name, this.getClientKey(player), true);
player.fleeFree = true;
await player.sendChat(
'#{unwelcome_tip_part1}#{random_ban_reason_abuse}#{unwelcome_tip_part2}',
ChatColor.BABYBLUE,
......@@ -683,35 +678,61 @@ export class RandomDuelProvider {
await this.setDiscipline(clientKey, discipline);
}
private async isFleeFree(roomName: string, clientKey: string) {
if (!roomName || !clientKey) {
return false;
private async sendMatchScoreTips(room: Room, client: Client) {
if (!this.recordMatchScoresEnabled) {
return;
}
const key = buildFleeFreeKey(roomName, clientKey);
const data = await this.ctx.aragami.get(RandomDuelFleeFreeCache, key);
return !!data?.enabled;
}
private async setFleeFree(
roomName: string,
clientKey: string,
enabled: boolean,
) {
if (!roomName || !clientKey) {
const players = room.playingPlayers.filter(
(player) => player.pos < NetPlayerType.OBSERVER,
);
if (!players.length) {
return;
}
const key = buildFleeFreeKey(roomName, clientKey);
await this.ctx.aragami.set(
RandomDuelFleeFreeCache,
{
key,
enabled: !!enabled,
},
{
key,
ttl: RANDOM_DUEL_TTL,
},
const clientScoreText = await this.getScoreDisplay(
this.getClientKey(client),
client.name,
);
for (const player of players) {
if (clientScoreText) {
await player.sendChat(clientScoreText, ChatColor.GREEN);
}
if (player === client) {
continue;
}
const playerScoreText = await this.getScoreDisplay(
this.getClientKey(player),
player.name,
);
if (playerScoreText) {
await client.sendChat(playerScoreText, ChatColor.GREEN);
}
}
}
private async getScoreDisplay(name: string, displayName: string) {
const repo = this.ctx.database?.getRepository(RandomDuelScore);
if (!repo || !name) {
return '';
}
const score = await repo.findOneBy({ name });
if (!score) {
return `${displayName} #{random_score_blank}`;
}
const total = score.winCount + score.loseCount;
if (score.winCount < 2 && total < 3) {
return `${displayName} #{random_score_not_enough}`;
}
const safeTotal = total > 0 ? total : 1;
const winRate = Math.ceil((score.winCount / safeTotal) * 100);
const fleeRate = Math.ceil((score.fleeCount / safeTotal) * 100);
if (score.winCombo >= 2) {
return `#{random_score_part1}${displayName} #{random_score_part2} ${winRate}#{random_score_part3} ${fleeRate}#{random_score_part4_combo}${score.winCombo}#{random_score_part5_combo}`;
}
return `#{random_score_part1}${displayName} #{random_score_part2} ${winRate}#{random_score_part3} ${fleeRate}#{random_score_part4}`;
}
private get recordMatchScoresEnabled() {
......
......@@ -36,6 +36,3 @@ export const formatRemainText = (expireAt: number) => {
}
return `${remainMinutes}m`;
};
export const buildFleeFreeKey = (roomName: string, ip: string) =>
`${roomName}:${ip}`;
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