From dd9a4f7dbb7636f1dbcc58cff48c0d18eccf9785 Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 00:18:59 +0900 Subject: [PATCH 01/15] executed `npx eslint src --fix` --- src/IIrcClient.ts | 10 +- src/Lobby.ts | 282 +++---- src/Modes.ts | 366 ++++----- src/Player.ts | 4 +- src/TypedConfig.ts | 52 +- src/cli/LogServer.ts | 2 +- src/cli/OahrBase.ts | 24 +- src/cli/OahrCli.ts | 162 ++-- src/cli/OahrHeadless.ts | 10 +- src/cli/index.ts | 26 +- src/discord/BotCommand.ts | 68 +- src/discord/DiscordAppender.ts | 124 +-- src/discord/DiscordBot.ts | 238 +++--- src/discord/OahrDiscord.ts | 92 +-- src/discord/index.ts | 56 +- src/dummies/DummyHistoryFetcher.ts | 36 +- src/dummies/DummyIrcClient.ts | 168 ++-- src/dummies/DummyLobbyPlugin.ts | 2 +- src/dummies/FakeBeatmapFetcher.ts | 272 +++---- src/libs/ChatLimiter.ts | 92 +-- src/libs/OptionValidator.ts | 62 +- src/libs/TypedEvent.ts | 2 +- src/parsers/CommandParser.ts | 78 +- src/parsers/MpSettingsParser.ts | 24 +- src/parsers/StatParser.ts | 4 +- src/plugins/AfkKicker.ts | 262 +++---- src/plugins/AutoHostSelector.ts | 136 ++-- src/plugins/AutoStartTimer.ts | 28 +- src/plugins/CacheCleaner.ts | 140 ++-- src/plugins/HistoryLoader.ts | 14 +- src/plugins/HostSkipper.ts | 50 +- src/plugins/InOutLogger.ts | 38 +- src/plugins/LobbyKeeper.ts | 124 +-- src/plugins/LobbyPlugin.ts | 10 +- src/plugins/LobbyTerminator.ts | 26 +- src/plugins/MapChecker.ts | 228 +++--- src/plugins/MapRecaster.ts | 8 +- src/plugins/MatchAborter.ts | 34 +- src/plugins/MatchStarter.ts | 66 +- src/plugins/MiscLoader.ts | 52 +- src/plugins/ProfileFecher.ts | 12 +- src/plugins/VoteCounter.ts | 2 +- src/plugins/WordCounter.ts | 20 +- src/tests/AfkKickerTest.ts | 356 ++++----- src/tests/AutoHostSelectorTest.ts | 1152 ++++++++++++++-------------- src/tests/AutoStartTimerTest.ts | 66 +- src/tests/BeatmapRepositoryTest.ts | 626 +++++++-------- src/tests/CommandParserTest.ts | 460 +++++------ src/tests/DummyIrcClientTest.ts | 50 +- src/tests/HistoryRepositryTest.ts | 228 +++--- src/tests/HostSkipperTest.ts | 320 ++++---- src/tests/InOutLoggerTest.ts | 18 +- src/tests/IntegratedPluginsTest.ts | 18 +- src/tests/LobbyKeeperTest.ts | 336 ++++---- src/tests/LobbyTerminatorTest.ts | 6 +- src/tests/LobbyTest.ts | 290 +++---- src/tests/MapCheckerTest.ts | 428 +++++------ src/tests/MapRecasterTest.ts | 20 +- src/tests/MatchAborterTest.ts | 60 +- src/tests/MatchStarterTest.ts | 122 +-- src/tests/MpSettingsParserTest.ts | 378 ++++----- src/tests/StatParserTest.ts | 52 +- src/tests/TestUtils.ts | 40 +- src/tests/TypedConfigTest.ts | 164 ++-- src/tests/WordCounterTest.ts | 108 +-- src/tests/cases/MpSettingsCases.ts | 264 +++---- src/trials/AppendersTrial.ts | 120 +-- src/trials/BanchoIrcTrial.ts | 10 +- src/trials/DiscordTrial.ts | 160 ++-- src/trials/HistryTrial.ts | 30 +- src/trials/IrcTrial.ts | 8 +- src/trials/LobbynameTrial.ts | 12 +- src/trials/TypedEventTrials.ts | 12 +- src/trials/WebApiTrial.ts | 28 +- src/trials/WebServerTrial.ts | 66 +- src/trials/index.ts | 2 +- src/web/LogServer.ts | 40 +- src/web/OahrWeb.ts | 10 +- src/web/statics/main.js | 150 ++-- src/webapi/BeatmapRepository.ts | 246 +++--- src/webapi/Beatmapsets.ts | 194 ++--- src/webapi/HistoryFetcher.ts | 2 +- src/webapi/HistoryRepository.ts | 60 +- src/webapi/HistoryTypes.ts | 132 ++-- src/webapi/ProfileRepository.ts | 200 ++--- src/webapi/WebApiClient.ts | 126 +-- 86 files changed, 5338 insertions(+), 5338 deletions(-) diff --git a/src/IIrcClient.ts b/src/IIrcClient.ts index 62c6ae71..4fb494e8 100644 --- a/src/IIrcClient.ts +++ b/src/IIrcClient.ts @@ -2,8 +2,8 @@ import * as irc from './libs/irc'; import { IsStatResponse } from './parsers/StatParser'; import { EventEmitter } from 'events'; import log4js from 'log4js'; -const ircLogger = log4js.getLogger("irc"); -const pmLogger = log4js.getLogger("PMLogger"); +const ircLogger = log4js.getLogger('irc'); +const pmLogger = log4js.getLogger('PMLogger'); // テスト用に使用する部分をインターフェースとして定義する // typescriptのインターフェースはダックタイピング可能なので、 @@ -25,7 +25,7 @@ export function logIrcEvent(client: IIrcClient) { }); client.on('registered', function (message) { const args = message.args as string[] | undefined; - ircLogger.debug('@reg %s', args?.join(", ")); + ircLogger.debug('@reg %s', args?.join(', ')); }); client.on('message', function (from, to, message) { ircLogger.debug('@msg %s => %s: %s', from, to, message); @@ -51,13 +51,13 @@ export function logIrcEvent(client: IIrcClient) { client.on('action', function (from, to, text, message) { ircLogger.debug('@action %s => %s: %s', from, to, text); }); - client.on("selfMessage", (target: string, toSend) => { + client.on('selfMessage', (target: string, toSend) => { ircLogger.debug('@sent bot => %s: %s', target, toSend); }); } export function logPrivateMessage(client: IIrcClient) { - client.on("message", (from, to, message) => { + client.on('message', (from, to, message) => { if (to == client.nick) { if (IsStatResponse(message)) { pmLogger.trace(`pm ${from} -> ${message}`); diff --git a/src/Lobby.ts b/src/Lobby.ts index 27b57500..600320c3 100644 --- a/src/Lobby.ts +++ b/src/Lobby.ts @@ -39,7 +39,7 @@ export class Lobby { lobbyId: string | undefined; channel: string | undefined; status: LobbyStatus; - mapTitle: string = ""; + mapTitle: string = ''; mapId: number = 0; host: Player | null = null; hostPending: Player | null = null; @@ -51,7 +51,7 @@ export class Lobby { listRefStart: number = 0; plugins: LobbyPlugin[] = []; coolTimes: { [key: string]: number } = {}; - deferredMessages: { [key: string]: DeferredAction } = {} + deferredMessages: { [key: string]: DeferredAction } = {}; settingParser: MpSettingsParser; statParser: StatParser; logger: log4js.Logger; @@ -86,18 +86,18 @@ export class Lobby { constructor(ircClient: IIrcClient, option: Partial = {}) { if (ircClient.conn == null) { - throw new Error("clientが未接続です"); + throw new Error('clientが未接続です'); } - this.option = getConfig("Lobby", option) as LobbyOption; + this.option = getConfig('Lobby', option) as LobbyOption; this.status = LobbyStatus.Standby; this.settingParser = new MpSettingsParser(); this.statParser = new StatParser(); this.ircClient = ircClient; - this.logger = log4js.getLogger("lobby"); - this.logger.addContext("channel", "lobby"); - this.chatlogger = log4js.getLogger("chat"); - this.chatlogger.addContext("channel", "lobby"); + this.logger = log4js.getLogger('lobby'); + this.logger.addContext('channel', 'lobby'); + this.chatlogger = log4js.getLogger('chat'); + this.chatlogger.addContext('channel', 'lobby'); this.historyRepository = new HistoryRepository(0); this.transferHostTimeout = new DeferredAction(() => this.onTimeoutedTransferHost()); this.registerEvents(); @@ -120,7 +120,7 @@ export class Lobby { }, registered: async () => { if (this.status == LobbyStatus.Entered && this.channel) { - this.logger.warn("network reconnection detected!"); + this.logger.warn('network reconnection detected!'); await this.LoadMpSettingsAsync(); } }, @@ -136,31 +136,31 @@ export class Lobby { this.CancelAllDeferredMessages(); this.historyRepository.lobbyClosed = true; - this.logger.info("part"); + this.logger.info('part'); this.status = LobbyStatus.Left; this.destroy(); } }, selfMessage: (target: string, toSend: any) => { if (target == this.channel) { - const r = toSend.replace(/\[http\S+\s([^\]]+)\]/g, "[http... $1]"); - this.chatlogger.info("bot:%s", r); + const r = toSend.replace(/\[http\S+\s([^\]]+)\]/g, '[http... $1]'); + this.chatlogger.info('bot:%s', r); } } }; - for (let key in this.events) { + for (const key in this.events) { this.ircClient.on(key, this.events[key]); } this.events.join = (channel: string, who: string) => { - this.logger.trace("raised join event"); + this.logger.trace('raised join event'); if (who == this.ircClient.nick && this.status != LobbyStatus.Entered) { this.RaiseJoinedLobby(channel); } }; - this.ircClient.once("join", this.events.join); + this.ircClient.once('join', this.events.join); } destroy() { @@ -169,7 +169,7 @@ export class Lobby { } private removeEvents() { - for (let key in this.events) { + for (const key in this.events) { this.ircClient.off(key, this.events[key] as any); } } @@ -179,7 +179,7 @@ export class Lobby { */ get playersFinished(): number { let i = 0; - for (let p of this.players) { + for (const p of this.players) { if (p.mpstatus == MpStatuses.Finished) i++; } return i; @@ -190,7 +190,7 @@ export class Lobby { */ get playersInGame(): number { let i = 0; - for (let p of this.players) { + for (const p of this.players) { if (p.mpstatus == MpStatuses.Finished || p.mpstatus == MpStatuses.Playing) i++; } return i; @@ -201,7 +201,7 @@ export class Lobby { */ CountPlayersStatus(): { inGame: number, playing: number, finished: number, inlobby: number, total: number } { const r = { inGame: 0, playing: 0, finished: 0, inlobby: 0, total: this.players.size }; - for (let p of this.players) { + for (const p of this.players) { switch (p.mpstatus) { case MpStatuses.InLobby: r.inlobby++; @@ -256,7 +256,7 @@ export class Lobby { // username のプレイヤーがゲームに参加しているか調べる Includes(username: string): boolean { const ename = escapeUserName(username); - let p = this.playersMap.get(ename); + const p = this.playersMap.get(ename); if (p === undefined) return false; return this.players.has(p); } @@ -270,20 +270,20 @@ export class Lobby { if (a.player == user) { resolve(); } else { - reject("Another player became host."); + reject('Another player became host.'); } }); const d2 = this.PlayerLeft.on((a: { player: Player }) => { if (a.player == user) { dispose(); - reject("Pending host left the lobby."); + reject('Pending host left the lobby.'); } }); const t1 = setTimeout(() => { dispose(); - reject("!mp host command timed out."); + reject('!mp host command timed out.'); }, this.option.transferhost_timeout_ms); @@ -291,7 +291,7 @@ export class Lobby { d1.dispose(); d2.dispose(); clearTimeout(t1); - } + }; }); } @@ -301,14 +301,14 @@ export class Lobby { this.hostPending = user; this.transferHostTimeout.start(this.option.transferhost_timeout_ms); if (user.id != 0) { - this.SendMessage("!mp host #" + user.id); + this.SendMessage('!mp host #' + user.id); } else { - this.SendMessage("!mp host " + user.name); + this.SendMessage('!mp host ' + user.name); } } onTimeoutedTransferHost(): void { - this.logger.warn("!mp host timeout"); + this.logger.warn('!mp host timeout'); if (this.hostPending) { if (this.players.has(this.hostPending)) { this.LoadMpSettingsAsync(); @@ -319,14 +319,14 @@ export class Lobby { AbortMatch(): void { if (this.isMatching) { - this.SendMessage("!mp abort"); + this.SendMessage('!mp abort'); } } SendMessage(message: string): void { if (this.channel != undefined) { this.ircClient.say(this.channel, message); - this.ircClient.emit("sentMessage", this.channel, message); + this.ircClient.emit('sentMessage', this.channel, message); this.SentMessage.emit({ message }); //this.chatlogger.trace("%s:%s", "bot", message); } @@ -334,9 +334,9 @@ export class Lobby { SendPrivateMessage(message: string, target: string): void { this.ircClient.say(target, message); - this.ircClient.emit("sentPrivateMessage", target, message); + this.ircClient.emit('sentPrivateMessage', target, message); this.SentMessage.emit({ message }); - this.chatlogger.info("%s:%s", "botbot->" + target, message); + this.chatlogger.info('%s:%s', 'botbot->' + target, message); } SendMessageWithCoolTime(message: string | (() => string), tag: string, cooltimeMs: number): boolean { @@ -347,7 +347,7 @@ export class Lobby { } } this.coolTimes[tag] = now; - if (typeof message == "function") { + if (typeof message == 'function') { message = message(); } this.SendMessage(message); @@ -362,7 +362,7 @@ export class Lobby { } } this.coolTimes[tag] = now; - if (typeof message == "function") { + if (typeof message == 'function') { message = message(); } this.SendPrivateMessage(message, target); @@ -379,7 +379,7 @@ export class Lobby { } DeferMessage(message: string, tag: string, delayMs: number, resetTimer: boolean = false): void { - if (message == "") { + if (message == '') { this.CancelDeferredMessage(tag); return; } @@ -398,7 +398,7 @@ export class Lobby { } CancelAllDeferredMessages(): void { - for (let tag in this.deferredMessages) { + for (const tag in this.deferredMessages) { this.deferredMessages[tag].cancel(); } } @@ -406,7 +406,7 @@ export class Lobby { async RequestStatAsync(player: Player, byPm: boolean, timeout: number = this.option.stat_timeout_ms): Promise { return new Promise((resolve, reject) => { const tm = setTimeout(() => { - reject("stat timeout"); + reject('stat timeout'); }, timeout); const d = this.ParsedStat.on(({ result }) => { if (escapeUserName(result.name) == player.escaped_name) { @@ -415,7 +415,7 @@ export class Lobby { resolve(result); } }); - this.ircClient.say(byPm || this.channel == null ? "BanchoBot" : this.channel, "!stat " + player.escaped_name); + this.ircClient.say(byPm || this.channel == null ? 'BanchoBot' : this.channel, '!stat ' + player.escaped_name); }); } @@ -432,7 +432,7 @@ export class Lobby { // #region message handling private handleMessage(from: string, to: string, message: string): void { - if (from == "BanchoBot") { + if (from == 'BanchoBot') { this.handleBanchoResponse(message); } else { const p = this.GetPlayer(from); @@ -442,20 +442,20 @@ export class Lobby { } this.PlayerChated.emit({ player: p, message }); if (IsStatResponse(message)) { - this.chatlogger.trace("%s:%s", p.name, message); + this.chatlogger.trace('%s:%s', p.name, message); } else { - this.chatlogger.info("%s:%s", p.name, message); + this.chatlogger.info('%s:%s', p.name, message); } } } } private handleAction(from: string, to: string, message: string): void { - this.chatlogger.info("*%s:%s", from, message); + this.chatlogger.info('*%s:%s', from, message); } private handlePrivateMessage(from: string, message: string): void { - if (from == "BanchoBot") { + if (from == 'BanchoBot') { if (IsStatResponse(message)) { if (this.statParser.feedLine(message)) { this.RaiseParsedStat(true); @@ -464,7 +464,7 @@ export class Lobby { } else { const user = this.GetPlayer(from); if (!user) return; - if ((message == "!info" || message == "!help") && this.players.has(user)) { + if ((message == '!info' || message == '!help') && this.players.has(user)) { this.sendInfoMessagePM(user); } } @@ -508,11 +508,11 @@ export class Lobby { break; case BanchoResponseType.AddedReferee: this.GetOrMakePlayer(c.params[0]).setRole(Roles.Referee); - this.logger.trace("AddedReferee : %s", c.params[0]); + this.logger.trace('AddedReferee : %s', c.params[0]); break; case BanchoResponseType.RemovedReferee: this.GetOrMakePlayer(c.params[0]).removeRole(Roles.Referee); - this.logger.trace("RemovedReferee : %s", c.params[0]); + this.logger.trace('RemovedReferee : %s', c.params[0]); break; case BanchoResponseType.ListRefs: this.listRefStart = Date.now(); @@ -522,15 +522,15 @@ export class Lobby { break; case BanchoResponseType.TeamChanged: this.GetOrMakePlayer(c.params[0]).team = c.params[1]; - this.logger.trace("team changed : %s, %s", c.params[0], Teams[c.params[1]]); + this.logger.trace('team changed : %s, %s', c.params[0], Teams[c.params[1]]); break; case BanchoResponseType.BeatmapChanged: case BanchoResponseType.MpBeatmapChanged: if (this.mapId != c.params[0]) { this.mapId = c.params[0]; this.mapTitle = c.params[1]; - const changer = this.host ? `(by ${c.type == BanchoResponseType.BeatmapChanged ? this.host.name : "bot"})` : ""; - this.logger.info("beatmap changed%s : %s %s", changer, "https://osu.ppy.sh/b/" + this.mapId, this.mapTitle); + const changer = this.host ? `(by ${c.type == BanchoResponseType.BeatmapChanged ? this.host.name : 'bot'})` : ''; + this.logger.info('beatmap changed%s : %s %s', changer, 'https://osu.ppy.sh/b/' + this.mapId, this.mapTitle); } break; case BanchoResponseType.Settings: @@ -544,7 +544,7 @@ export class Lobby { } break; case BanchoResponseType.ClearedHost: - this.logger.info("cleared host"); + this.logger.info('cleared host'); this.isClearedHost = true; if (this.host != null) { this.host.removeRole(Roles.Host); @@ -554,7 +554,7 @@ export class Lobby { break; case BanchoResponseType.Unhandled: if (this.checkListRef(message)) break; - this.logger.debug("unhandled bancho response : %s", message); + this.logger.debug('unhandled bancho response : %s', message); break; } this.ReceivedBanchoResponse.emit({ message, response: c }); @@ -565,24 +565,24 @@ export class Lobby { if (Date.now() < this.listRefStart + this.option.listref_duration_ms) { const p = this.GetOrMakePlayer(message); p.setRole(Roles.Referee); - this.logger.trace("AddedReferee : %s", p.escaped_name); + this.logger.trace('AddedReferee : %s', p.escaped_name); return true; } else { this.listRefStart = 0; - this.logger.trace("check list ref ended"); + this.logger.trace('check list ref ended'); } } return false; } RaiseReceivedChatCommand(player: Player, message: string): void { - this.logger.trace("custom command %s:%s", player.name, message); - if (player.isReferee && message.startsWith("!mp")) return; + this.logger.trace('custom command %s:%s', player.name, message); + if (player.isReferee && message.startsWith('!mp')) return; const { command, param } = parser.ParseChatCommand(message); - if (command == "!info" || command == "!help") { + if (command == '!info' || command == '!help') { this.showInfoMessage(); } - if (command == "!version" || command == "!v") { + if (command == '!version' || command == '!v') { this.showVersionMessage(); } this.ReceivedChatCommand.emit({ player, command, param }); @@ -616,7 +616,7 @@ export class Lobby { const from = player.slot; player.slot = slot; - this.logger.trace("slot moved : %s, %d", username, slot); + this.logger.trace('slot moved : %s, %d', username, slot); this.PlayerMoved.emit({ player, from, to: slot }); } @@ -630,7 +630,7 @@ export class Lobby { } RaiseMatchStarted(): void { - this.logger.info("match started"); + this.logger.info('match started'); this.isMatching = true; this.players.forEach(p => p.mpstatus = MpStatuses.Playing); this.MatchStarted.emit({ mapId: this.mapId, mapTitle: this.mapTitle }); @@ -642,13 +642,13 @@ export class Lobby { const sc = this.CountPlayersStatus(); this.PlayerFinished.emit({ player, score, isPassed, playersFinished: sc.finished, playersInGame: sc.inGame }); if (!this.players.has(player)) { - this.logger.warn("未参加のプレイヤーがゲームを終えた: %s", username); + this.logger.warn('未参加のプレイヤーがゲームを終えた: %s', username); this.LoadMpSettingsAsync(); } } RaiseMatchFinished(): void { - let count = this.players.size; + const count = this.players.size; this.logger.info(`match finished (${count} players)`); this.isMatching = false; this.players.forEach(p => p.mpstatus = MpStatuses.InLobby); @@ -657,14 +657,14 @@ export class Lobby { RaiseAbortedMatch(): void { const sc = this.CountPlayersStatus(); - this.logger.info("match aborted %d / %d", sc.finished, sc.inGame); + this.logger.info('match aborted %d / %d', sc.finished, sc.inGame); this.isMatching = false; this.players.forEach(p => p.mpstatus = MpStatuses.InLobby); this.AbortedMatch.emit({ playersFinished: sc.finished, playersInGame: sc.inGame }); } RaiseNetError(err: Error): void { - this.logger.error("error occured : " + err.message); + this.logger.error('error occured : ' + err.message); this.logger.error(err.stack); this.NetError.emit(err); } @@ -672,26 +672,26 @@ export class Lobby { RaiseJoinedLobby(channel: string): void { this.players.clear(); this.channel = channel; - this.lobbyId = channel.replace("#mp_", ""); + this.lobbyId = channel.replace('#mp_', ''); this.historyRepository.setLobbyId(this.lobbyId); this.status = LobbyStatus.Entered; - this.logger.addContext("channel", this.lobbyId); - this.chatlogger.addContext("channel", this.lobbyId); - for (let p of this.plugins) { - p.logger.addContext("channel", this.lobbyId); + this.logger.addContext('channel', this.lobbyId); + this.chatlogger.addContext('channel', this.lobbyId); + for (const p of this.plugins) { + p.logger.addContext('channel', this.lobbyId); } this.assignCreatorRole(); - this.JoinedLobby.emit({ channel: this.channel, creator: this.GetOrMakePlayer(this.ircClient.nick) }) + this.JoinedLobby.emit({ channel: this.channel, creator: this.GetOrMakePlayer(this.ircClient.nick) }); this.startInfoMessageAnnouncement(); } RaiseParsedSettings(): void { if (!this.settingParser.isParsing && this.settingParser.result != null) { - this.logger.info("parsed mp settings"); + this.logger.info('parsed mp settings'); const result = this.settingParser.result; const r = this.margeMpSettingsResult(result); if (r.hostChanged || r.playersIn.length != 0 || r.playersOut.length != 0) { - this.logger.info("applied mp settings"); + this.logger.info('applied mp settings'); this.FixedSettings.emit({ result, ...r }); } this.ParsedSettings.emit({ result, ...r }); @@ -703,7 +703,7 @@ export class Lobby { const p = this.GetPlayer(this.statParser.result.name); if (p != null) { p.laststat = this.statParser.result; - this.logger.info("parsed stat %s -> %s", p.name, StatStatuses[p.laststat.status]); + this.logger.info('parsed stat %s -> %s', p.name, StatStatuses[p.laststat.status]); this.ParsedStat.emit({ result: this.statParser.result, player: p, isPm }); } } @@ -713,7 +713,7 @@ export class Lobby { * pluginに読み込み作業が完了したことを通知する */ RaisePluginsLoaded(): void { - for (let p of this.plugins) { + for (const p of this.plugins) { p.OnLoaded(); } } @@ -721,7 +721,7 @@ export class Lobby { OnUserNotFound(): void { if (this.hostPending != null) { const p = this.hostPending; - this.logger.warn("occured OnUserNotFound : " + p.name); + this.logger.warn('occured OnUserNotFound : ' + p.name); this.hostPending = null; } } @@ -731,20 +731,20 @@ export class Lobby { // #region lobby management MakeLobbyAsync(title: string): Promise { - if (title === "") { - throw new Error("title is empty"); + if (title === '') { + throw new Error('title is empty'); } if (this.status != LobbyStatus.Standby) { - throw new Error("A lobby has already been made."); + throw new Error('A lobby has already been made.'); } this.status = LobbyStatus.Making; - this.logger.trace("start makeLobby"); + this.logger.trace('start makeLobby'); return new Promise(resolve => { - if (this.ircClient.hostMask != "") { + if (this.ircClient.hostMask != '') { this.makeLobbyAsyncCore(title).then(v => resolve(v)); } else { - this.logger.trace("waiting registered"); - this.ircClient.once("registered", () => { + this.logger.trace('waiting registered'); + this.ircClient.once('registered', () => { this.makeLobbyAsyncCore(title).then(v => resolve(v)); }); } @@ -755,46 +755,46 @@ export class Lobby { return new Promise((resolve, reject) => { this.JoinedLobby.once(a => { this.lobbyName = title; - this.logger.trace("completed makeLobby"); + this.logger.trace('completed makeLobby'); if (this.lobbyId) { resolve(this.lobbyId); } else { - reject("missing lobby id"); + reject('missing lobby id'); } }); - const trg = "BanchoBot"; - const msg = "!mp make " + title; + const trg = 'BanchoBot'; + const msg = '!mp make ' + title; this.ircClient.say(trg, msg); - this.ircClient.emit("sentMessage", trg, msg); + this.ircClient.emit('sentMessage', trg, msg); }); } EnterLobbyAsync(channel: string): Promise { - this.logger.trace("start EnterLobby"); + this.logger.trace('start EnterLobby'); return new Promise((resolve, reject) => { - let ch = parser.EnsureMpChannelId(channel); - if (ch == "") { - this.logger.error("invalid channel: %s", channel); - reject("invalid channel"); + const ch = parser.EnsureMpChannelId(channel); + if (ch == '') { + this.logger.error('invalid channel: %s', channel); + reject('invalid channel'); return; } - let joinhandler = () => { + const joinhandler = () => { this.ircClient.off('error', errhandler); - this.lobbyName = "__"; - this.logger.trace("completed EnterLobby"); + this.lobbyName = '__'; + this.logger.trace('completed EnterLobby'); if (this.lobbyId) { resolve(this.lobbyId); } else { this.destroy(); - reject("missing lobby id"); + reject('missing lobby id'); } }; - let errhandler = (message: any) => { + const errhandler = (message: any) => { this.ircClient.off('join', joinhandler); this.destroy(); reject(`${message.args[2]}`); - } + }; this.ircClient.once('error', errhandler); this.ircClient.once('join', joinhandler); this.ircClient.join(ch); @@ -802,17 +802,17 @@ export class Lobby { } CloseLobbyAsync(): Promise { - this.logger.trace("start CloseLobby"); + this.logger.trace('start CloseLobby'); if (this.status != LobbyStatus.Entered) { - this.logger.error("無効な呼び出し:CloseLobbyAsync"); - throw new Error("閉じるロビーがありません。"); + this.logger.error('無効な呼び出し:CloseLobbyAsync'); + throw new Error('閉じるロビーがありません。'); } return new Promise((resolve, reject) => { - this.ircClient.once("part", (channel: string, nick: string) => { + this.ircClient.once('part', (channel: string, nick: string) => { resolve(); }); if (this.channel != undefined) { - this.SendMessage("!mp close"); + this.SendMessage('!mp close'); this.status = LobbyStatus.Leaving; } else { reject(); @@ -821,17 +821,17 @@ export class Lobby { } QuitLobbyAsync(): Promise { - this.logger.trace("start QuitLobby"); + this.logger.trace('start QuitLobby'); if (this.status != LobbyStatus.Entered) { - this.logger.error("無効な呼び出し:QuitLobbyAsync"); - throw new Error("閉じるロビーがありません。"); + this.logger.error('無効な呼び出し:QuitLobbyAsync'); + throw new Error('閉じるロビーがありません。'); } return new Promise((resolve, reject) => { - this.ircClient.once("part", (channel: string, nick: string) => { + this.ircClient.once('part', (channel: string, nick: string) => { resolve(); }); if (this.channel != undefined) { - this.ircClient.part(this.channel, "part", () => { }); + this.ircClient.part(this.channel, 'part', () => { }); this.status = LobbyStatus.Leaving; } else { reject(); @@ -841,20 +841,20 @@ export class Lobby { LoadMpSettingsAsync(): Promise { if (this.status != LobbyStatus.Entered) { - return Promise.reject("invalid lobby status @LoadMpSettingsAsync"); + return Promise.reject('invalid lobby status @LoadMpSettingsAsync'); } - if (this.SendMessageWithCoolTime("!mp settings", "mpsettings", 15000)) { - this.logger.trace("start loadLobbySettings"); + if (this.SendMessageWithCoolTime('!mp settings', 'mpsettings', 15000)) { + this.logger.trace('start loadLobbySettings'); const p = new Promise(resolve => { this.FixedSettings.once(() => { - this.SendMessage("!mp listrefs"); - this.logger.trace("completed loadLobbySettings"); + this.SendMessage('!mp listrefs'); + this.logger.trace('completed loadLobbySettings'); resolve(); }); }); return p; } else { - this.logger.trace("load mp settings skiped by cool time"); + this.logger.trace('load mp settings skiped by cool time'); return Promise.resolve(); } } @@ -870,15 +870,15 @@ export class Lobby { if (asHost) { this.setAsHost(player); } - if (16 < this.players.size) { - this.logger.warn("joined 17th players: %s", player.name); - this.UnexpectedAction.emit(new Error("unexpected join")); + if (this.players.size > 16) { + this.logger.warn('joined 17th players: %s', player.name); + this.UnexpectedAction.emit(new Error('unexpected join')); return false; } return true; } else { - this.logger.warn("参加済みのプレイヤーが再度参加した: %s", player.name); - this.UnexpectedAction.emit(new Error("unexpected join")); + this.logger.warn('参加済みのプレイヤーが再度参加した: %s', player.name); + this.UnexpectedAction.emit(new Error('unexpected join')); return false; } } @@ -894,13 +894,13 @@ export class Lobby { this.host = null; } if (this.hostPending == player) { - this.logger.warn("pending中にユーザーが離脱した pending host: %s", player.name); + this.logger.warn('pending中にユーザーが離脱した pending host: %s', player.name); this.hostPending = null; } return true; } else { - this.logger.warn("未参加のプレイヤーが退出した: %s", player.name); - this.UnexpectedAction.emit(new Error("unexpected left")); + this.logger.warn('未参加のプレイヤーが退出した: %s', player.name); + this.UnexpectedAction.emit(new Error('unexpected left')); return false; } } @@ -908,7 +908,7 @@ export class Lobby { private setAsHost(player: Player): boolean { if (!this.players.has(player)) { this.transferHostTimeout.cancel(); - this.logger.warn("未参加のプレイヤーがホストになった: %s", player.name); + this.logger.warn('未参加のプレイヤーがホストになった: %s', player.name); return false; } @@ -916,7 +916,7 @@ export class Lobby { this.transferHostTimeout.cancel(); this.hostPending = null; } else if (this.hostPending != null) { - this.logger.warn("pending中に別のユーザーがホストになった pending: %s, host: %s", this.hostPending.name, player.name); + this.logger.warn('pending中に別のユーザーがホストになった pending: %s, host: %s', this.hostPending.name, player.name); } // pending == null は有効 if (this.host != null) { @@ -941,7 +941,7 @@ export class Lobby { const playersOut: Player[] = []; let hostChanged = false; - for (let p of this.players) { + for (const p of this.players) { if (!mpPlayers.includes(p)) { const slot = p.slot; this.removePlayer(p); @@ -950,8 +950,8 @@ export class Lobby { } } - for (let r of result.players) { - let p = this.GetOrMakePlayer(r.name); + for (const r of result.players) { + const p = this.GetOrMakePlayer(r.name); if (!this.players.has(p)) { this.addPlayer(p, r.slot, r.team); playersIn.push(p); @@ -976,59 +976,59 @@ export class Lobby { let s = `=== lobby status === lobby id : ${this.lobbyId}, name : ${this.lobbyName}, status : ${LobbyStatus[this.status]} players : ${this.players.size}, inGame : ${pc.inGame} (playing : ${pc.playing}) - refs : ${Array.from(this.playersMap.values()).filter(v => v.isReferee).map(v => v.name).join(",")} + refs : ${Array.from(this.playersMap.values()).filter(v => v.isReferee).map(v => v.name).join(',')} timer : ${this.isStartTimerActive}, clearedhost : ${this.isClearedHost} - host : ${this.host ? this.host.name : "null"}, pending : ${this.hostPending ? this.hostPending.name : "null"}` + host : ${this.host ? this.host.name : 'null'}, pending : ${this.hostPending ? this.hostPending.name : 'null'}` ; - for (let p of this.plugins) { + for (const p of this.plugins) { const ps = p.GetPluginStatus(); - if (ps != "") { - s += "\n" + ps; + if (ps != '') { + s += '\n' + ps; } } return s; } private showInfoMessage(): void { - this.SendMessageWithCoolTime(this.getInfoMessage(), "infomessage", this.option.info_message_cooltime_ms); + this.SendMessageWithCoolTime(this.getInfoMessage(), 'infomessage', this.option.info_message_cooltime_ms); } private showVersionMessage(): void { const version = this.tryGetVersion(); - this.SendMessageWithCoolTime(`osu! Auto Host Rotation Bot v. ${version}`, "versionmessage", this.option.info_message_cooltime_ms); + this.SendMessageWithCoolTime(`osu! Auto Host Rotation Bot v. ${version}`, 'versionmessage', this.option.info_message_cooltime_ms); } private sendInfoMessagePM(player: Player): void { - this.SendPrivateMessageWithCoolTime(this.getInfoMessage(), player.escaped_name, "infomessage", this.option.info_message_cooltime_ms) + this.SendPrivateMessageWithCoolTime(this.getInfoMessage(), player.escaped_name, 'infomessage', this.option.info_message_cooltime_ms); } private getInfoMessage(): string { const version = this.tryGetVersion(); - return this.option.info_message.replace("${version}", version); + return this.option.info_message.replace('${version}', version); } private tryGetVersion(): string { if (process.env.npm_package_version) return process.env.npm_package_version; try { - return require("../package.json").version ?? "0.0.0"; + return require('../package.json').version ?? '0.0.0'; } catch { - return "0.0.0"; + return '0.0.0'; } } // ircでログインしたユーザーに権限を与える private assignCreatorRole(): void { if (!this.ircClient.nick) { - this.ircClient.once("registered", () => { + this.ircClient.once('registered', () => { this.assignCreatorRole(); }); } else { - var c = this.GetOrMakePlayer(this.ircClient.nick); + const c = this.GetOrMakePlayer(this.ircClient.nick); c.setRole(Roles.Authorized); c.setRole(Roles.Referee); c.setRole(Roles.Creator); - this.logger.info("assigned %s creators role", this.ircClient.nick); + this.logger.info('assigned %s creators role', this.ircClient.nick); } } @@ -1036,7 +1036,7 @@ export class Lobby { // ensure time is stop this.stopInfoMessageAnnouncement(); if (this.option.info_message_announcement_interval_ms > 3 * 60 * 1000) { - this.logger.trace("started InfoMessageAnnouncement. interval = " + this.option.info_message_announcement_interval_ms); + this.logger.trace('started InfoMessageAnnouncement. interval = ' + this.option.info_message_announcement_interval_ms); this.infoMessageAnnouncementTimeId = setInterval(() => { this.showInfoMessage(); if (this.status != LobbyStatus.Entered) { @@ -1048,7 +1048,7 @@ export class Lobby { private stopInfoMessageAnnouncement(): void { if (this.infoMessageAnnouncementTimeId != null) { - this.logger.trace("stopped InfoMessageAnnouncement."); + this.logger.trace('stopped InfoMessageAnnouncement.'); clearInterval(this.infoMessageAnnouncementTimeId); this.infoMessageAnnouncementTimeId = null; } diff --git a/src/Modes.ts b/src/Modes.ts index 4cd58163..0a4ced0e 100644 --- a/src/Modes.ts +++ b/src/Modes.ts @@ -5,244 +5,244 @@ */ class Mode { - readonly value: string; // !mp set などで利用する数値/文字列 - readonly name: string; // わかりやすい文字列表現 - readonly aliases: Set; // osu内での表記ゆれに対応する - readonly type: string = ""; - - protected constructor(value: string, name: string, aliases: string[] = []) { - this.value = value; - this.name = name; - this.aliases = new Set(aliases.concat(value, name).map(v => Mode.normalize(v))); - } - - /** + readonly value: string; // !mp set などで利用する数値/文字列 + readonly name: string; // わかりやすい文字列表現 + readonly aliases: Set; // osu内での表記ゆれに対応する + readonly type: string = ''; + + protected constructor(value: string, name: string, aliases: string[] = []) { + this.value = value; + this.name = name; + this.aliases = new Set(aliases.concat(value, name).map(v => Mode.normalize(v))); + } + + /** * value,name,aliases と一致するか比較する * @param normalizedValue 検査対象文字列、 前提:標準化済みの文字列を使用すること * @returns */ - protected _match(normalizedValue: string): boolean { - return this.aliases.has(normalizedValue); - } + protected _match(normalizedValue: string): boolean { + return this.aliases.has(normalizedValue); + } - match(value: string): boolean { - return this.aliases.has(Mode.normalize(value)); - } + match(value: string): boolean { + return this.aliases.has(Mode.normalize(value)); + } - /** + /** * 比較しやすい表現に変換する * スペースとハイフンを取り除き、小文字にする * @param v * @returns */ - protected static normalize(v: string): string { - return v.replace(/[ -]/g, "").toLowerCase(); + protected static normalize(v: string): string { + return v.replace(/[ -]/g, '').toLowerCase(); + } + + protected static _from(value: string, values: T[], defaultMode: T, throwsIfFailed: boolean, tag: string): T { + const nv = Mode.normalize(value); + for (const m of values) { + if (m._match(nv)) { + return m; + } } - - protected static _from(value: string, values: T[], defaultMode: T, throwsIfFailed: boolean, tag: string): T { - const nv = Mode.normalize(value); - for (const m of values) { - if (m._match(nv)) { - return m; - } - } - if (throwsIfFailed) { - throw new Error(`Failed to parse ${value}`); - } else { - return defaultMode; - } - + if (throwsIfFailed) { + throw new Error(`Failed to parse ${value}`); + } else { + return defaultMode; } - toString() { - return this.name; - } + } + + toString() { + return this.name; + } } export class ScoreMode extends Mode { - static readonly Values: ScoreMode[] = []; + static readonly Values: ScoreMode[] = []; - static readonly Score = new ScoreMode(0, "Score"); - static readonly Accuracy = new ScoreMode(1, "Accuracy"); - static readonly Combo = new ScoreMode(2, "Combo"); - static readonly ScoreV2 = new ScoreMode(3, "ScoreV2"); + static readonly Score = new ScoreMode(0, 'Score'); + static readonly Accuracy = new ScoreMode(1, 'Accuracy'); + static readonly Combo = new ScoreMode(2, 'Combo'); + static readonly ScoreV2 = new ScoreMode(3, 'ScoreV2'); - readonly type: "ScoreMode" = "ScoreMode"; + readonly type: 'ScoreMode' = 'ScoreMode'; - protected constructor(value: string | number, name: string, aliases: string[] = []) { - super(value.toString(), name, aliases); - ScoreMode.Values.push(this); - } + protected constructor(value: string | number, name: string, aliases: string[] = []) { + super(value.toString(), name, aliases); + ScoreMode.Values.push(this); + } - static from(value: string, throwsIfFailed: boolean = false) { - return Mode._from(value, ScoreMode.Values, ScoreMode.Score, throwsIfFailed, "ScoreMode"); - } + static from(value: string, throwsIfFailed: boolean = false) { + return Mode._from(value, ScoreMode.Values, ScoreMode.Score, throwsIfFailed, 'ScoreMode'); + } } export class TeamMode extends Mode { - static readonly Values: TeamMode[] = []; + static readonly Values: TeamMode[] = []; - static readonly HeadToHead = new TeamMode(0, "HeadToHead"); // historyのhead-to-headはnormalizeで対応済み - static readonly TagCoop = new TeamMode(1, "TagCoop"); - static readonly TeamVs = new TeamMode(2, "TeamVs"); - static readonly TagTeamVs = new TeamMode(3, "TagTeamVs"); + static readonly HeadToHead = new TeamMode(0, 'HeadToHead'); // historyのhead-to-headはnormalizeで対応済み + static readonly TagCoop = new TeamMode(1, 'TagCoop'); + static readonly TeamVs = new TeamMode(2, 'TeamVs'); + static readonly TagTeamVs = new TeamMode(3, 'TagTeamVs'); - readonly type: "TeamMode" = "TeamMode"; + readonly type: 'TeamMode' = 'TeamMode'; - protected constructor(value: string | number, name: string, aliases: string[] = []) { - super(value.toString(), name, aliases); - TeamMode.Values.push(this); - } + protected constructor(value: string | number, name: string, aliases: string[] = []) { + super(value.toString(), name, aliases); + TeamMode.Values.push(this); + } - static from(value: string, throwsIfFailed: boolean = false) { - return Mode._from(value, TeamMode.Values, TeamMode.HeadToHead, throwsIfFailed, "TeamMode"); - } + static from(value: string, throwsIfFailed: boolean = false) { + return Mode._from(value, TeamMode.Values, TeamMode.HeadToHead, throwsIfFailed, 'TeamMode'); + } - isTeamMatch(): boolean { - return this == TeamMode.TeamVs || this == TeamMode.TagTeamVs; - } + isTeamMatch(): boolean { + return this == TeamMode.TeamVs || this == TeamMode.TagTeamVs; + } } export class PlayMode extends Mode { - static readonly Values: PlayMode[] = []; - - static readonly Osu = new PlayMode(0, "Osu", "osu!"); - static readonly Taiko = new PlayMode(1, "Taiko", "osu!taiko"); - static readonly CatchTheBeat = new PlayMode(2, "CatchTheBeat", "osu!catch", ["fruits", "catch", "fruit"]); - static readonly OsuMania = new PlayMode(3, "OsuMania", "osu!mania", ["mania"]); - - readonly type: "PlayMode" = "PlayMode"; - readonly id: number; - readonly officialName: string; - - protected constructor(value: string | number, name: string, officialName: string, aliases: string[] = []) { - super(value.toString(), name, aliases); - this.id = typeof value == "number" ? value : parseInt(value); - this.officialName = officialName; - PlayMode.Values.push(this); - } - - static from(value: string, throwsIfFailed: boolean = false) { - return Mode._from(value, PlayMode.Values, PlayMode.Osu, throwsIfFailed, "PlayMode"); - } + static readonly Values: PlayMode[] = []; + + static readonly Osu = new PlayMode(0, 'Osu', 'osu!'); + static readonly Taiko = new PlayMode(1, 'Taiko', 'osu!taiko'); + static readonly CatchTheBeat = new PlayMode(2, 'CatchTheBeat', 'osu!catch', ['fruits', 'catch', 'fruit']); + static readonly OsuMania = new PlayMode(3, 'OsuMania', 'osu!mania', ['mania']); + + readonly type: 'PlayMode' = 'PlayMode'; + readonly id: number; + readonly officialName: string; + + protected constructor(value: string | number, name: string, officialName: string, aliases: string[] = []) { + super(value.toString(), name, aliases); + this.id = typeof value == 'number' ? value : parseInt(value); + this.officialName = officialName; + PlayMode.Values.push(this); + } + + static from(value: string, throwsIfFailed: boolean = false) { + return Mode._from(value, PlayMode.Values, PlayMode.Osu, throwsIfFailed, 'PlayMode'); + } } export class Team extends Mode { - static readonly Values: Team[] = []; + static readonly Values: Team[] = []; - static readonly None = new Team("none", "None"); - static readonly Red = new Team("red", "Red"); - static readonly Blue = new Team("blue", "Blue"); + static readonly None = new Team('none', 'None'); + static readonly Red = new Team('red', 'Red'); + static readonly Blue = new Team('blue', 'Blue'); - readonly type: "Team" = "Team"; + readonly type: 'Team' = 'Team'; - protected constructor(value: string | number, name: string, aliases: string[] = []) { - super(value.toString(), name, aliases); - Team.Values.push(this); - } + protected constructor(value: string | number, name: string, aliases: string[] = []) { + super(value.toString(), name, aliases); + Team.Values.push(this); + } - static from(value: string, throwsIfFailed: boolean = false) { - return Mode._from(value, Team.Values, Team.Red, throwsIfFailed, "Team"); - } + static from(value: string, throwsIfFailed: boolean = false) { + return Mode._from(value, Team.Values, Team.Red, throwsIfFailed, 'Team'); + } } export class Mod extends Mode { - static readonly Values: Mod[] = []; - - static readonly None = new Mod("none", "None", true); - static readonly Freemod = new Mod("Freemod", "Freemod", true); - static readonly NoFail = new Mod("nf", "NoFail", false); - static readonly Easy = new Mod("ez", "Easy", false); - static readonly Hidden = new Mod("hd", "Hidden", false); - static readonly HardRock = new Mod("hr", "HardRock", false); - static readonly SuddenDeath = new Mod("sd", "SuddenDeath", false); - static readonly DoubleTime = new Mod("dt", "DoubleTime", true, ["double"]); - static readonly Nightcore = new Mod("nc", "Nightcore", true); - static readonly Relax = new Mod("relax", "Relax", false, ["RX"]); - static readonly HalfTime = new Mod("ht", "HalfTime", true); - static readonly Flashlight = new Mod("fl", "Flashlight", false); - static readonly SpunOut = new Mod("so", "SpunOut", false); - static readonly Relax2 = new Mod("ap", "Relax2", false, ["auto pilot"]); - static readonly FadeIn = new Mod("fi", "FadeIn", false); - static readonly Random = new Mod("rd", "Random", true); - static readonly KeyCoop = new Mod("co-op", "KeyCoop", false); - static readonly Mirror = new Mod("mr", "Mirror", false); - static readonly Key1 = new Mod("1k", "Key1", false); - static readonly Key2 = new Mod("2k", "Key2", false); - static readonly Key3 = new Mod("3k", "Key3", false); - static readonly Key4 = new Mod("4k", "Key4", false); - static readonly Key5 = new Mod("5k", "Key5", false); - static readonly Key6 = new Mod("6k", "Key6", false); - static readonly Key7 = new Mod("7k", "Key7", false); - static readonly Key8 = new Mod("8k", "Key8", false); - static readonly Key9 = new Mod("9k", "Key9", false); - - readonly isGlobalMod: boolean; - readonly type: "Mod" = "Mod"; - - protected constructor(value: string | number, name: string, isGlobalMod: boolean, aliases: string[] = []) { - super(value.toString(), name, aliases); - Mod.Values.push(this); - this.isGlobalMod = isGlobalMod; + static readonly Values: Mod[] = []; + + static readonly None = new Mod('none', 'None', true); + static readonly Freemod = new Mod('Freemod', 'Freemod', true); + static readonly NoFail = new Mod('nf', 'NoFail', false); + static readonly Easy = new Mod('ez', 'Easy', false); + static readonly Hidden = new Mod('hd', 'Hidden', false); + static readonly HardRock = new Mod('hr', 'HardRock', false); + static readonly SuddenDeath = new Mod('sd', 'SuddenDeath', false); + static readonly DoubleTime = new Mod('dt', 'DoubleTime', true, ['double']); + static readonly Nightcore = new Mod('nc', 'Nightcore', true); + static readonly Relax = new Mod('relax', 'Relax', false, ['RX']); + static readonly HalfTime = new Mod('ht', 'HalfTime', true); + static readonly Flashlight = new Mod('fl', 'Flashlight', false); + static readonly SpunOut = new Mod('so', 'SpunOut', false); + static readonly Relax2 = new Mod('ap', 'Relax2', false, ['auto pilot']); + static readonly FadeIn = new Mod('fi', 'FadeIn', false); + static readonly Random = new Mod('rd', 'Random', true); + static readonly KeyCoop = new Mod('co-op', 'KeyCoop', false); + static readonly Mirror = new Mod('mr', 'Mirror', false); + static readonly Key1 = new Mod('1k', 'Key1', false); + static readonly Key2 = new Mod('2k', 'Key2', false); + static readonly Key3 = new Mod('3k', 'Key3', false); + static readonly Key4 = new Mod('4k', 'Key4', false); + static readonly Key5 = new Mod('5k', 'Key5', false); + static readonly Key6 = new Mod('6k', 'Key6', false); + static readonly Key7 = new Mod('7k', 'Key7', false); + static readonly Key8 = new Mod('8k', 'Key8', false); + static readonly Key9 = new Mod('9k', 'Key9', false); + + readonly isGlobalMod: boolean; + readonly type: 'Mod' = 'Mod'; + + protected constructor(value: string | number, name: string, isGlobalMod: boolean, aliases: string[] = []) { + super(value.toString(), name, aliases); + Mod.Values.push(this); + this.isGlobalMod = isGlobalMod; + } + + static from(value: string, throwsIfFailed: boolean = false) { + return Mode._from(value, Mod.Values, Mod.None, throwsIfFailed, 'Mod'); + } + + static parseMods(str: string): Mod[] { + const arrMods = str.match(/[a-zA-Z0-9\-]+/g)?.map(v => Mod.from(v)); + if (arrMods) { + const setMods = new Set(arrMods); + return Mod.removeInvalidCombinations(setMods); + } else { + return []; } + } - static from(value: string, throwsIfFailed: boolean = false) { - return Mode._from(value, Mod.Values, Mod.None, throwsIfFailed, "Mod"); - } + static removeInvalidCombinations(mods: Mod[] | Set): Mod[] { + const set = mods instanceof Set ? mods : new Set(mods); - static parseMods(str: string): Mod[] { - const arrMods = str.match(/[a-zA-Z0-9\-]+/g)?.map(v => Mod.from(v)); - if (arrMods) { - const setMods = new Set(arrMods); - return Mod.removeInvalidCombinations(setMods); - } else { - return []; + if (set.has(Mod.Freemod)) { + for (const m of set) { + if (!m.isGlobalMod) { + set.delete(m); } + } } - static removeInvalidCombinations(mods: Mod[] | Set): Mod[] { - const set = mods instanceof Set ? mods : new Set(mods); - - if (set.has(Mod.Freemod)) { - for (const m of set) { - if (!m.isGlobalMod) { - set.delete(m); - } - } - } - - if (set.has(Mod.Easy)) { - set.delete(Mod.HardRock); - } + if (set.has(Mod.Easy)) { + set.delete(Mod.HardRock); + } - if (set.has(Mod.NoFail)) { - set.delete(Mod.SuddenDeath); - set.delete(Mod.Relax); - set.delete(Mod.Relax2); - } + if (set.has(Mod.NoFail)) { + set.delete(Mod.SuddenDeath); + set.delete(Mod.Relax); + set.delete(Mod.Relax2); + } - if (set.has(Mod.HalfTime)) { - set.delete(Mod.DoubleTime); - set.delete(Mod.Nightcore); - } + if (set.has(Mod.HalfTime)) { + set.delete(Mod.DoubleTime); + set.delete(Mod.Nightcore); + } - if (set.has(Mod.SuddenDeath)) { - set.delete(Mod.Relax); - set.delete(Mod.Relax2); - } + if (set.has(Mod.SuddenDeath)) { + set.delete(Mod.Relax); + set.delete(Mod.Relax2); + } - if (set.has(Mod.Nightcore)) { - set.add(Mod.DoubleTime); - } + if (set.has(Mod.Nightcore)) { + set.add(Mod.DoubleTime); + } - if (set.has(Mod.Relax)) { - set.delete(Mod.Relax2); - } + if (set.has(Mod.Relax)) { + set.delete(Mod.Relax2); + } - set.delete(Mod.None); + set.delete(Mod.None); - return [...set]; - } + return [...set]; + } } /* memo diff --git a/src/Player.ts b/src/Player.ts index cb2316cd..48f060d4 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -80,7 +80,7 @@ export function escapeUserName(name: string): string { * @param username */ export function disguiseUserName(username: string): string { - return username[0] + "\u{200B}" + username.substring(1); + return username[0] + '\u{200B}' + username.substring(1); } /** @@ -88,5 +88,5 @@ export function disguiseUserName(username: string): string { * @param disguisedName */ export function revealUserName(disguisedName: string): string { - return disguisedName.replace(/\u200B/g, ""); + return disguisedName.replace(/\u200B/g, ''); } diff --git a/src/TypedConfig.ts b/src/TypedConfig.ts index a6ea023e..e0df8a5e 100644 --- a/src/TypedConfig.ts +++ b/src/TypedConfig.ts @@ -2,12 +2,12 @@ import config from 'config'; import { IClientOpts } from './libs/irc'; import log4js from 'log4js'; -const configLogger = log4js.getLogger("config"); +const configLogger = log4js.getLogger('config'); export const CONFIG_OPTION = { USE_ENV: false, PRINT_LOADED_ENV_CONFIG: true, -} +}; export interface IAhrConfig { irc: IIrcConfig; @@ -20,19 +20,19 @@ export interface IIrcConfig { } export function getIrcConfig(): IIrcConfig { - const d = config.get("irc"); - const e = loadEnvConfig("irc", d, [ - { key: "server", nullable: false, type: "string" }, - { key: "nick", nullable: false, type: "string" }, - { key: "port", nullable: false, type: "number" }, - { key: "password", nullable: false, type: "string" } + const d = config.get('irc'); + const e = loadEnvConfig('irc', d, [ + { key: 'server', nullable: false, type: 'string' }, + { key: 'nick', nullable: false, type: 'string' }, + { key: 'port', nullable: false, type: 'number' }, + { key: 'password', nullable: false, type: 'string' } ]); const c = { ...d, ...e }; c.opt = { ...c.opt }; - if (typeof e.port === "number") { + if (typeof e.port === 'number') { c.opt.port = e.port; } - if (typeof e.password === "string") { + if (typeof e.password === 'string') { c.opt.password = e.password; } return c; @@ -65,12 +65,12 @@ export type ConfigTypeHint = { export type EnvConfigs = { [key: string]: boolean | number | string | object | null }; export function generateDefaultOptionTypeHint(option: any): ConfigTypeHint[] { - let r = []; + const r = []; for (const key in option) { if (option[key] === null || option[key] === undefined) { - r.push({ key, nullable: true, type: "number" }); + r.push({ key, nullable: true, type: 'number' }); } else if (Array.isArray(option[key])) { - r.push({ key, nullable: false, type: "array" }); + r.push({ key, nullable: false, type: 'array' }); } else { r.push({ key, nullable: false, type: typeof option[key] }); } @@ -83,37 +83,37 @@ function genEnvKey(category: string, key: string): string { } export function loadEnvConfigWithTypeHint(category: string, hints: ConfigTypeHint[], env: { [key: string]: string | undefined }): EnvConfigs { - let r: EnvConfigs = {}; + const r: EnvConfigs = {}; for (const hint of hints) { const envKey = genEnvKey(category, hint.key); - let envVar = env[envKey]; - if (hint.nullable && (envVar === "null")) { + const envVar = env[envKey]; + if (hint.nullable && (envVar === 'null')) { r[hint.key] = null; } else if (envVar !== undefined) { switch (hint.type) { - case "boolean": - let bool = envVar.toLowerCase(); - if (bool === "true") { + case 'boolean': + const bool = envVar.toLowerCase(); + if (bool === 'true') { r[hint.key] = true; - } else if (bool === "false") { + } else if (bool === 'false') { r[hint.key] = false; } else { throw new Error(`env:${envKey} type mismatched. ${hint.key} must be true/false but "${envVar}"`); } break; - case "number": - let num = parseFloat(envVar); + case 'number': + const num = parseFloat(envVar); if (!Number.isNaN(num)) { r[hint.key] = num; } else { throw new Error(`env:${envKey} type mismatched. ${hint.key} must be number but "${envVar}"`); } break; - case "string": + case 'string': r[hint.key] = envVar; break; - case "array": - let arr = JSON.parse(envVar); + case 'array': + const arr = JSON.parse(envVar); if (isStringArray(arr)) { r[hint.key] = arr; } else { @@ -135,7 +135,7 @@ export function loadEnvConfigWithTypeHint(category: string, hints: ConfigTypeHin function isStringArray(arr: any) { if (!Array.isArray(arr)) return false; - return arr.every(v => typeof v === "string"); + return arr.every(v => typeof v === 'string'); } export function loadEnvConfig(category: string, template: any, hints?: ConfigTypeHint[]) { diff --git a/src/cli/LogServer.ts b/src/cli/LogServer.ts index f91ac358..76b26af6 100644 --- a/src/cli/LogServer.ts +++ b/src/cli/LogServer.ts @@ -5,6 +5,6 @@ export interface LogServerOption { port: number; } -const options = config.get("LogServer"); +const options = config.get('LogServer'); startLogServer(options.port); diff --git a/src/cli/OahrBase.ts b/src/cli/OahrBase.ts index 96cf8a42..033c58dd 100644 --- a/src/cli/OahrBase.ts +++ b/src/cli/OahrBase.ts @@ -19,14 +19,14 @@ import { MiscLoader } from '../plugins/MiscLoader'; import { parser } from '../parsers/CommandParser'; import { CacheCleaner } from '../plugins/CacheCleaner'; -const logger = log4js.getLogger("cli"); +const logger = log4js.getLogger('cli'); export interface OahrCliOption { invite_users: string[]; // ロビー作成時に招待するプレイヤー, 自分を招待する場合など password: string; // デフォルトのパスワード, 空文字でパスワードなし。 } -const OahrCliDefaultOption = config.get("OahrCli"); +const OahrCliDefaultOption = config.get('OahrCli'); export class OahrBase { client: IIrcClient; @@ -70,7 +70,7 @@ export class OahrBase { } get isRegistered(): boolean { - return this.client.hostMask != ""; + return this.client.hostMask != ''; } displayInfo(): void { @@ -80,9 +80,9 @@ export class OahrBase { ensureRegisteredAsync(): Promise { return new Promise((resolve, reject) => { if (!this.isRegistered) { - logger.trace("waiting for registration from bancho"); - this.client.once("registered", () => { - logger.trace("registerd"); + logger.trace('waiting for registration from bancho'); + this.client.once('registered', () => { + logger.trace('registerd'); resolve(); }); } else { @@ -92,13 +92,13 @@ export class OahrBase { } async makeLobbyAsync(name: string): Promise { - name = name.replace(/[^ -/:-@\[-~0-9a-zA-Z]/g, ""); + name = name.replace(/[^ -/:-@\[-~0-9a-zA-Z]/g, ''); if (!this.isRegistered) await this.ensureRegisteredAsync(); - logger.info("Making lobby, name : " + name); + logger.info('Making lobby, name : ' + name); await this.lobby.MakeLobbyAsync(name); - this.lobby.SendMessage("!mp password " + this.option.password); - for (let p of this.option.invite_users) { - this.lobby.SendMessage("!mp invite " + p); + this.lobby.SendMessage('!mp password ' + this.option.password); + for (const p of this.option.invite_users) { + this.lobby.SendMessage('!mp invite ' + p); } logger.info(`Made lobby : ${this.lobby.channel}`); } @@ -106,7 +106,7 @@ export class OahrBase { async enterLobbyAsync(id: string): Promise { if (!this.isRegistered) await this.ensureRegisteredAsync(); const channel = parser.EnsureMpChannelId(id); - logger.info("Entering lobby, channel : %s", channel); + logger.info('Entering lobby, channel : %s', channel); await this.lobby.EnterLobbyAsync(channel); await this.lobby.LoadMpSettingsAsync(); diff --git a/src/cli/OahrCli.ts b/src/cli/OahrCli.ts index 467f5e2b..bb3d5af0 100644 --- a/src/cli/OahrCli.ts +++ b/src/cli/OahrCli.ts @@ -6,7 +6,7 @@ import log4js from 'log4js'; import { parser } from '../parsers/CommandParser'; import { OahrBase } from './OahrBase'; -const logger = log4js.getLogger("cli"); +const logger = log4js.getLogger('cli'); const mainMenuCommandsMessage = ` MainMenu Commands @@ -46,101 +46,101 @@ export class OahrCli extends OahrBase { private scenes = { mainMenu: { - name: "", - prompt: "> ", + name: '', + prompt: '> ', action: async (line: string) => { - let l = parser.SplitCliCommand(line); + const l = parser.SplitCliCommand(line); switch (l.command) { - case "m": - case "make": - if (l.arg == "") { - logger.info("make command needs lobby name. ex:make testlobby"); + case 'm': + case 'make': + if (l.arg == '') { + logger.info('make command needs lobby name. ex:make testlobby'); return; } try { await this.makeLobbyAsync(l.arg); this.transitionToLobbyMenu(); } catch (e) { - logger.info("faiiled to make lobby : %s", e); + logger.info('faiiled to make lobby : %s', e); this.scene = this.scenes.exited; } break; - case "e": - case "enter": + case 'e': + case 'enter': try { - if (l.arg == "") { - logger.info("enter command needs lobby id. ex:enter 123456"); + if (l.arg == '') { + logger.info('enter command needs lobby id. ex:enter 123456'); return; } await this.enterLobbyAsync(l.arg); this.transitionToLobbyMenu(); } catch (e) { - logger.info("invalid channel : %s", e); + logger.info('invalid channel : %s', e); this.scene = this.scenes.exited; } break; - case "q": - case "quit": - case "exit": + case 'q': + case 'quit': + case 'exit': this.scene = this.scenes.exited; break; - case "h": - case "help": - case "command": - case "commands": - case "/?": - case "-?": - case "?": + case 'h': + case 'help': + case 'command': + case 'commands': + case '/?': + case '-?': + case '?': console.log(mainMenuCommandsMessage); break; - case "": + case '': break; default: - logger.info("invalid command : %s", line); + logger.info('invalid command : %s', line); break; } }, completer: (line: string): readline.CompleterResult => { - const completions = ["make", "enter", "quit", "exit", "help"]; + const completions = ['make', 'enter', 'quit', 'exit', 'help']; const hits = completions.filter(v => v.startsWith(line)); - return [hits.length ? hits : ["make", "enter", "quit", "help"], line]; + return [hits.length ? hits : ['make', 'enter', 'quit', 'help'], line]; } }, lobbyMenu: { - name: "lobbyMenu", - prompt: "> ", + name: 'lobbyMenu', + prompt: '> ', action: async (line: string) => { - let l = parser.SplitCliCommand(line); + const l = parser.SplitCliCommand(line); if (this.lobby.status == LobbyStatus.Left || this.client.conn == null) { this.scene = this.scenes.exited; return; } switch (l.command) { - case "s": - case "say": - if ((l.arg.startsWith("!") && !l.arg.startsWith("!mp ")) || l.arg.startsWith("*")) { - this.lobby.RaiseReceivedChatCommand(this.lobby.GetOrMakePlayer(this.client.nick), l.arg) + case 's': + case 'say': + if ((l.arg.startsWith('!') && !l.arg.startsWith('!mp ')) || l.arg.startsWith('*')) { + this.lobby.RaiseReceivedChatCommand(this.lobby.GetOrMakePlayer(this.client.nick), l.arg); } else { this.lobby.SendMessage(l.arg); } break; - case "i": - case "info": + case 'i': + case 'info': this.displayInfo(); break; - case "reorder": + case 'reorder': this.selector.Reorder(l.arg); break; - case "regulation": + case 'regulation': if (!l.arg) { console.log(this.checker.getRegulationDescription()); } else { - this.checker.processOwnerCommand("*regulation", l.arg); // TODO check + this.checker.processOwnerCommand('*regulation', l.arg); // TODO check } break; - case "c": - case "close": - if (l.arg == "now") { + case 'c': + case 'close': + if (l.arg == 'now') { // close now await this.lobby.CloseLobbyAsync(); this.scene = this.scenes.exited; @@ -152,52 +152,52 @@ export class OahrCli extends OahrBase { this.terminator.CloseLobby(); } break; - case "q": - case "quit": - logger.info("quit"); + case 'q': + case 'quit': + logger.info('quit'); this.scene = this.scenes.exited; break; - case "h": - case "help": - case "command": - case "commands": - case "/?": - case "-?": - case "?": + case 'h': + case 'help': + case 'command': + case 'commands': + case '/?': + case '-?': + case '?': console.log(lobbyMenuCommandsMessage); break; - case "check_order": + case 'check_order': this.lobby.historyRepository.calcCurrentOrderAsName().then(r => { - logger.info("history order = " + r.join(", ")); - logger.info("current order = " + this.selector.hostQueue.map(p => p.name).join(", ")); + logger.info('history order = ' + r.join(', ')); + logger.info('current order = ' + this.selector.hostQueue.map(p => p.name).join(', ')); }); break; - case "": + case '': break; default: - if (l.command.startsWith("!mp")) { - this.lobby.SendMessage("!mp " + l.arg); - } else if (l.command.startsWith("!") || l.command.startsWith("*")) { - this.lobby.RaiseReceivedChatCommand(this.lobby.GetOrMakePlayer(this.client.nick), l.command + " " + l.arg) + if (l.command.startsWith('!mp')) { + this.lobby.SendMessage('!mp ' + l.arg); + } else if (l.command.startsWith('!') || l.command.startsWith('*')) { + this.lobby.RaiseReceivedChatCommand(this.lobby.GetOrMakePlayer(this.client.nick), l.command + ' ' + l.arg); } else { - console.log("invalid command : %s", line); + console.log('invalid command : %s', line); } break; } }, completer: (line: string): readline.CompleterResult => { - const completions = ["say", "info", "reorder", "regulation", "close", "quit", "help"]; + const completions = ['say', 'info', 'reorder', 'regulation', 'close', 'quit', 'help']; const hits = completions.filter(v => v.startsWith(line)); return [hits.length ? hits : completions, line]; } }, exited: { - name: "exited", - prompt: "ended", + name: 'exited', + prompt: 'ended', action: async (line: string) => { }, completer: (line: string): readline.CompleterResult => { - return [["exit"], line]; + return [['exit'], line]; } } }; @@ -220,40 +220,40 @@ export class OahrCli extends OahrBase { } }); } - let r = rl as readline.Interface; + const r = rl as readline.Interface; - logger.trace("waiting for registration from bancho"); - console.log("Connecting to Osu Bancho ..."); - this.client.once("registered", () => { - console.log("Connected :D"); - console.log("\n=== Welcome to osu-ahr ==="); + logger.trace('waiting for registration from bancho'); + console.log('Connecting to Osu Bancho ...'); + this.client.once('registered', () => { + console.log('Connected :D'); + console.log('\n=== Welcome to osu-ahr ==='); console.log(mainMenuCommandsMessage); r.setPrompt(this.prompt); r.prompt(); }); - r.on("line", line => { - logger.trace("scene:%s, line:%s", this.scene.name, line); + r.on('line', line => { + logger.trace('scene:%s, line:%s', this.scene.name, line); this.scene.action(line).then(() => { if (!this.exited) { r.setPrompt(this.prompt); r.prompt(); } else { - logger.trace("closing interface"); + logger.trace('closing interface'); r.close(); } }); }); - r.on("close", () => { + r.on('close', () => { if (this.client != null) { - logger.info("readline closed"); + logger.info('readline closed'); if (this.client.conn != null && !this.client.conn.requestedDisconnect) { - this.client.disconnect("goodby", () => { - logger.info("ircClient disconnected"); + this.client.disconnect('goodby', () => { + logger.info('ircClient disconnected'); process.exit(0); }); } else { - logger.info("exit"); + logger.info('exit'); process.exit(0); } } @@ -262,7 +262,7 @@ export class OahrCli extends OahrBase { transitionToLobbyMenu() { this.scene = this.scenes.lobbyMenu; - this.scene.prompt = (this.lobby.channel || "") + " > "; + this.scene.prompt = (this.lobby.channel || '') + ' > '; console.log(lobbyMenuCommandsMessage); } } diff --git a/src/cli/OahrHeadless.ts b/src/cli/OahrHeadless.ts index 767e8547..60f437d4 100644 --- a/src/cli/OahrHeadless.ts +++ b/src/cli/OahrHeadless.ts @@ -2,14 +2,14 @@ import { IIrcClient } from '../IIrcClient'; import log4js from 'log4js'; import { OahrBase } from './OahrBase'; -const logger = log4js.getLogger("cli"); +const logger = log4js.getLogger('cli'); export class OahrHeadless extends OahrBase { constructor(client: IIrcClient) { super(client); - client.once("part", () => { - logger.info("detected part event. closing..."); + client.once('part', () => { + logger.info('detected part event. closing...'); process.exit(0); }); } @@ -17,10 +17,10 @@ export class OahrHeadless extends OahrBase { start(command: string, arg: string): void { try { switch (command) { - case "m": + case 'm': this.makeLobbyAsync(arg); break; - case "e": + case 'e': this.enterLobbyAsync(arg); break; default: diff --git a/src/cli/index.ts b/src/cli/index.ts index 3fe31488..af84f3fe 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -6,31 +6,31 @@ import { CONFIG_OPTION, getIrcConfig } from '../TypedConfig'; import log4js from 'log4js'; import { logPrivateMessage } from '../IIrcClient'; import { applySpeedLimit } from '../libs/ChatLimiter'; -const logger = log4js.getLogger("cli"); +const logger = log4js.getLogger('cli'); -console.log("starting up..."); +console.log('starting up...'); const config_path = (process.env.NODE_ENV === 'production') - ? "./config/log_cli_prod.json" - : "./config/log_cli_dev.json"; + ? './config/log_cli_prod.json' + : './config/log_cli_dev.json'; log4js.configure(config_path); try { CONFIG_OPTION.USE_ENV = true; const c = getIrcConfig(); - if (c.nick == "your account id" || c.opt.password == "you can get password from 'https://osu.ppy.sh/p/irc'") { - logger.error("you must enter your account name and irc password in the config file. "); - logger.error("you can get the password from 'https://osu.ppy.sh/p/irc' "); - logger.error("Copy config/default.json to config/local.json, and enter your id and irc password."); + if (c.nick == 'your account id' || c.opt.password == 'you can get password from \'https://osu.ppy.sh/p/irc\'') { + logger.error('you must enter your account name and irc password in the config file. '); + logger.error('you can get the password from \'https://osu.ppy.sh/p/irc\' '); + logger.error('Copy config/default.json to config/local.json, and enter your id and irc password.'); process.exit(1); } - let client = new irc.Client(c.server, c.nick, c.opt); - client.on("error", err => { - if (err.command == "err_passwdmismatch") { + const client = new irc.Client(c.server, c.nick, c.opt); + client.on('error', err => { + if (err.command == 'err_passwdmismatch') { logger.error('%s: %s', err.command, err.args.join(' ')); - logger.error("check your account id and password."); + logger.error('check your account id and password.'); process.exit(1); } }); @@ -43,7 +43,7 @@ try { if (process.argv.length > 2) { const command = process.argv[2]; const oahr = new OahrHeadless(client); - const arg = process.argv.slice(3).join(" "); + const arg = process.argv.slice(3).join(' '); oahr.start(command, arg); } else { const oahr = new OahrCli(client); diff --git a/src/discord/BotCommand.ts b/src/discord/BotCommand.ts index 86d3b5d4..0543d80c 100644 --- a/src/discord/BotCommand.ts +++ b/src/discord/BotCommand.ts @@ -3,110 +3,110 @@ import { ApplicationCommandData } from 'discord.js'; // coded by https://autocode.com/tools/discord/command-builder/ export const BotCommands: ApplicationCommandData[] = [ { - name: "make", - description: "Make a tournament lobby", + name: 'make', + description: 'Make a tournament lobby', defaultPermission: false, options: [ { type: 3, - name: "lobby_name", - description: "Initial lobby Name e.g. \"4.00-5.99 auto host rotation\"", + name: 'lobby_name', + description: 'Initial lobby Name e.g. "4.00-5.99 auto host rotation"', required: true } ] }, { - name: "enter", - description: "Enter the lobby.", + name: 'enter', + description: 'Enter the lobby.', defaultPermission: false, options: [ { type: 4, - name: "lobby_id", - description: " Tournament lobby ID", + name: 'lobby_id', + description: ' Tournament lobby ID', required: false } ] }, { - name: "info", - description: "Shows the status of the lobby.", + name: 'info', + description: 'Shows the status of the lobby.', defaultPermission: false, options: [ { type: 4, - name: "lobby_id", - description: " Tournament lobby ID", + name: 'lobby_id', + description: ' Tournament lobby ID', required: false } ] }, { - name: "say", - description: "send a message", + name: 'say', + description: 'send a message', defaultPermission: false, options: [ { type: 3, - name: "message", - description: "message", + name: 'message', + description: 'message', required: true }, { type: 4, - name: "lobby_id", - description: " Tournament lobby ID", + name: 'lobby_id', + description: ' Tournament lobby ID', required: false } ] }, { - name: "config", - description: "configure ahrbot", + name: 'config', + description: 'configure ahrbot', defaultPermission: false, options: [ { type: 3, - name: "section", - description: "specify config section", + name: 'section', + description: 'specify config section', required: true }, { type: 3, - name: "name", - description: "option name", + name: 'name', + description: 'option name', required: true }, { type: 3, - name: "value", - description: "new value", + name: 'value', + description: 'new value', required: true } ] }, { - name: "close", - description: "Close the lobby", + name: 'close', + description: 'Close the lobby', defaultPermission: false, options: [ { type: 4, - name: "lobby_id", - description: " Tournament lobby ID", + name: 'lobby_id', + description: ' Tournament lobby ID', required: false } ] }, { - name: "quit", - description: "Quit managing the lobby", + name: 'quit', + description: 'Quit managing the lobby', defaultPermission: false, options: [ { type: 4, - name: "lobby_id", - description: "Tournament lobby ID", + name: 'lobby_id', + description: 'Tournament lobby ID', required: false } ] diff --git a/src/discord/DiscordAppender.ts b/src/discord/DiscordAppender.ts index 576affdd..bda30d91 100644 --- a/src/discord/DiscordAppender.ts +++ b/src/discord/DiscordAppender.ts @@ -4,90 +4,90 @@ import { OahrDiscord } from './OahrDiscord'; let discordClient: Client | undefined; let ahrs: { [index: string]: OahrDiscord }; -const logger = log4js.getLogger("discord"); +const logger = log4js.getLogger('discord'); export function setContext(client: Client, ahrs_: { [index: string]: OahrDiscord }) { - discordClient = client; - ahrs = ahrs_; + discordClient = client; + ahrs = ahrs_; } const COLOR_MAP: { [key: string]: ColorResolvable } = { - 'white': "WHITE", 'grey': "GREY", 'black': "DARK_BUT_NOT_BLACK", - 'blue': "BLUE", 'cyan': "AQUA", 'green': "GREEN", - 'magenta': "LUMINOUS_VIVID_PINK", 'red': "RED", 'yellow': "YELLOW" + 'white': 'WHITE', 'grey': 'GREY', 'black': 'DARK_BUT_NOT_BLACK', + 'blue': 'BLUE', 'cyan': 'AQUA', 'green': 'GREEN', + 'magenta': 'LUMINOUS_VIVID_PINK', 'red': 'RED', 'yellow': 'YELLOW' }; export function configure(config: any, layouts: any) { - let layout = layouts.colouredLayout; - if (config.layout) { - layout = layouts.layout(config.layout.type, config.layout); - } + let layout = layouts.colouredLayout; + if (config.layout) { + layout = layouts.layout(config.layout.type, config.layout); + } - //create a new appender instance - /* loggingEvent sample + //create a new appender instance + /* loggingEvent sample categoryName:'default' context:{channel: 'mp_123'} data:(1) ['aaa'] level:Level {level: 20000, levelStr: 'INFO', colour: 'green'} pid:18048 startTime:Sat Aug 28 2021 22:30:41 GMT+0900 */ - return async (loggingEvent: log4js.LoggingEvent) => { - if (discordClient) { - try { - let ch = getDiscordChannel(loggingEvent.context); - if (ch) { - let msg = layout(loggingEvent, config.timezoneOffset); - let content = createContent(loggingEvent, msg); - await ch.send(content); - } - } catch (e: any) { - logger.error(e.message); - const ahr = ahrs[loggingEvent.context.channelId]; - if (ahr) { - ahr.stopTransferLog(); - } - } + return async (loggingEvent: log4js.LoggingEvent) => { + if (discordClient) { + try { + const ch = getDiscordChannel(loggingEvent.context); + if (ch) { + const msg = layout(loggingEvent, config.timezoneOffset); + const content = createContent(loggingEvent, msg); + await ch.send(content); + } + } catch (e: any) { + logger.error(e.message); + const ahr = ahrs[loggingEvent.context.channelId]; + if (ahr) { + ahr.stopTransferLog(); } - }; + } + } + }; } function getDiscordChannel(context: any): TextBasedChannel | undefined { - if (discordClient && context && context.transfer && context.guildId && context.channelId) { - let guild = discordClient.guilds.cache.get(context.guildId); - let ch = guild?.channels.cache.get(context.channelId) - if (ch && ch.isText()) { - return ch; - } + if (discordClient && context && context.transfer && context.guildId && context.channelId) { + const guild = discordClient.guilds.cache.get(context.guildId); + const ch = guild?.channels.cache.get(context.channelId); + if (ch && ch.isText()) { + return ch; } - return undefined; + } + return undefined; } function createContent(ev: log4js.LoggingEvent, msg: string): string | MessageOptions { - let color = COLOR_MAP[ev.level.colour] ?? "DEFAULT"; - switch (ev.categoryName) { - case "chat": - if (ev.data.length == 3) { - return `> **${ev.data[1]}**: ${ev.data[2]}`; - } else { - return "> " + msg; - } - case "inout": - let min = msg.match(/\+\x1b\[32m (.+?) \x1B\[0m/); - let mout = msg.match(/\-\x1b\[31m (.+?) \x1B\[0m/); - if (min || mout) { - let msg = ""; - if (min) { - msg += "**in** " + min[1] + " "; - } - if (mout) { - msg += "**out** " + mout[1]; - } - return { embeds: [new MessageEmbed().setColor(color).setDescription(msg)] }; - } - break; - } - if (log4js.levels.WARN.level <= ev.level.level) { + const color = COLOR_MAP[ev.level.colour] ?? 'DEFAULT'; + switch (ev.categoryName) { + case 'chat': + if (ev.data.length == 3) { + return `> **${ev.data[1]}**: ${ev.data[2]}`; + } else { + return '> ' + msg; + } + case 'inout': + const min = msg.match(/\+\x1b\[32m (.+?) \x1B\[0m/); + const mout = msg.match(/\-\x1b\[31m (.+?) \x1B\[0m/); + if (min || mout) { + let msg = ''; + if (min) { + msg += '**in** ' + min[1] + ' '; + } + if (mout) { + msg += '**out** ' + mout[1]; + } return { embeds: [new MessageEmbed().setColor(color).setDescription(msg)] }; - } - return "`" + ev.categoryName + "` " + msg; + } + break; + } + if (log4js.levels.WARN.level <= ev.level.level) { + return { embeds: [new MessageEmbed().setColor(color).setDescription(msg)] }; + } + return '`' + ev.categoryName + '` ' + msg; } diff --git a/src/discord/DiscordBot.ts b/src/discord/DiscordBot.ts index c31f05a8..6797b3a5 100644 --- a/src/discord/DiscordBot.ts +++ b/src/discord/DiscordBot.ts @@ -5,24 +5,24 @@ * */ - import log4js from 'log4js'; - import { Client, Permissions, Guild, GuildChannel, ThreadChannel, CommandInteraction, ApplicationCommandData, ApplicationCommandPermissionData, CreateRoleOptions, MessageEmbed, MessageActionRow, MessageButton, DiscordAPIError, Message, Role, TextChannel, GuildMember, ButtonInteraction } from 'discord.js'; - import config from 'config'; +import log4js from 'log4js'; +import { Client, Permissions, Guild, GuildChannel, ThreadChannel, CommandInteraction, ApplicationCommandData, ApplicationCommandPermissionData, CreateRoleOptions, MessageEmbed, MessageActionRow, MessageButton, DiscordAPIError, Message, Role, TextChannel, GuildMember, ButtonInteraction } from 'discord.js'; +import config from 'config'; - import { IIrcClient } from '../IIrcClient'; - import { LobbyStatus } from '../Lobby'; - import { Player } from '../Player'; - import { OahrDiscord } from './OahrDiscord'; - import { setContext } from './DiscordAppender'; - import { BotCommands } from './BotCommand'; - import { BanchoResponse, BanchoResponseType } from '../parsers/CommandParser'; +import { IIrcClient } from '../IIrcClient'; +import { LobbyStatus } from '../Lobby'; +import { Player } from '../Player'; +import { OahrDiscord } from './OahrDiscord'; +import { setContext } from './DiscordAppender'; +import { BotCommands } from './BotCommand'; +import { BanchoResponse, BanchoResponseType } from '../parsers/CommandParser'; -const logger = log4js.getLogger("discord"); +const logger = log4js.getLogger('discord'); const ADMIN_ROLE: CreateRoleOptions = { - name: "ahr-admin", - color: "ORANGE", - reason: "ahr-bot administrator" + name: 'ahr-admin', + color: 'ORANGE', + reason: 'ahr-bot administrator' }; export interface DiscordBotConfig { @@ -43,31 +43,31 @@ export class DiscordBot { constructor(client: IIrcClient, discordClient: Client) { this.ircClient = client; this.discordClient = discordClient; - this.cfg = config.get("Discord"); + this.cfg = config.get('Discord'); this.ahrs = {}; - this.sharedObjects = {} + this.sharedObjects = {}; } async start() { this.discordClient.once('ready', async cl => { - for (let g of cl.guilds.cache.values()) { + for (const g of cl.guilds.cache.values()) { await this.registerCommandsAndRoles(g); } setContext(cl, this.ahrs); - logger.info("discord bot is ready."); + logger.info('discord bot is ready.'); logger.info(`invite link => ${this.generateInviteLink()}`); }); - this.discordClient.on("guildCreate", async guild => { - console.log("guildCreate " + guild.name); + this.discordClient.on('guildCreate', async guild => { + console.log('guildCreate ' + guild.name); await this.registerCommandsAndRoles(guild); }); - this.discordClient.on("interactionCreate", async interaction => { + this.discordClient.on('interactionCreate', async interaction => { if (!interaction.inGuild()) return; if (!this.checkMemberHasAhrAdminRole(interaction.member as GuildMember)) { if (interaction.isButton()) { - await interaction.reply({content:"looking for a menu for you", ephemeral:true}); + await interaction.reply({content:'looking for a menu for you', ephemeral:true}); } return; } @@ -85,14 +85,14 @@ export class DiscordBot { try { await this.discordClient.login(this.cfg.token); } catch (e: any) { - if (e?.code == "TOKEN_INVALID" && e.message) { + if (e?.code == 'TOKEN_INVALID' && e.message) { logger.error(e.message); - if (this.cfg.token == "") { - logger.error(`your token is Empty`); + if (this.cfg.token == '') { + logger.error('your token is Empty'); } else { logger.error(`your token is invalid. "${this.cfg.token}"`); } - logger.error("Check the setup guide -> https://github.com/Meowhal/osu-ahr#discord-integration"); + logger.error('Check the setup guide -> https://github.com/Meowhal/osu-ahr#discord-integration'); } else { logger.error(e); @@ -107,8 +107,8 @@ export class DiscordBot { } async registerCommandsAndRoles(guild: Guild) { - let results = await guild.commands.set(BotCommands); - let roleId = await this.registerRole(guild); + const results = await guild.commands.set(BotCommands); + const roleId = await this.registerRole(guild); const permissions: ApplicationCommandPermissionData[] = [ { id: roleId, @@ -132,24 +132,24 @@ export class DiscordBot { async handleCommandInteraction(interaction: GuildCommandInteraction) { switch (interaction.commandName) { - case "make": + case 'make': await this.make(interaction); break; - case "enter": + case 'enter': await this.enter(interaction); break; - case "info": + case 'info': await this.info(interaction); break; - case "say": + case 'say': await this.say(interaction); break; - case "config": + case 'config': break; - case "close": + case 'close': await this.close(interaction); break; - case "quit": + case 'quit': await this.quit(interaction); break; } @@ -158,53 +158,53 @@ export class DiscordBot { async make(interaction: GuildCommandInteraction) { await interaction.deferReply(); if (!interaction.guild) { - logger.error("interaction.guild must not be null"); - await interaction.editReply("😫 interaction.guild must not be null"); + logger.error('interaction.guild must not be null'); + await interaction.editReply('😫 interaction.guild must not be null'); return; } - let name = interaction.options.getString("lobby_name", true); + const name = interaction.options.getString('lobby_name', true); let ahr; try { ahr = new OahrDiscord(this.ircClient, this.sharedObjects); await ahr.makeLobbyAsync(name); } catch (e: any) { - logger.error("couldn't make a tournament lobby. " + e); - await interaction.editReply("😫 couldn't make a tournament lobby. " + e.message); + logger.error('couldn\'t make a tournament lobby. ' + e); + await interaction.editReply('😫 couldn\'t make a tournament lobby. ' + e.message); ahr?.lobby.destroy(); return; } try { - let lobbyNumber = ahr.lobby.lobbyId ?? "new_lobby"; + const lobbyNumber = ahr.lobby.lobbyId ?? 'new_lobby'; this.registeAhr(ahr, interaction); await this.updateMatchSummary(ahr); await interaction.editReply(`😀 Created the lobby [Lobby History](https://osu.ppy.sh/mp/${lobbyNumber})`); } catch (e: any) { - logger.error("couldn't make a discord channel. " + e); - await interaction.editReply("couldn't make a discord channel. " + e.message); + logger.error('couldn\'t make a discord channel. ' + e); + await interaction.editReply('couldn\'t make a discord channel. ' + e.message); } } async enter(interaction: GuildCommandInteraction) { await interaction.deferReply(); - let lobbyNumber = this.resolveLobbyId(interaction, true); - let lobbyId = "#mp_" + lobbyNumber; + const lobbyNumber = this.resolveLobbyId(interaction, true); + const lobbyId = '#mp_' + lobbyNumber; if (!lobbyNumber) { - await interaction.editReply("error lobby_id required."); + await interaction.editReply('error lobby_id required.'); return; } if (!interaction.guild) { - logger.error("interaction.guild must not be null"); - await interaction.editReply("😫 interaction.guild must not be null"); + logger.error('interaction.guild must not be null'); + await interaction.editReply('😫 interaction.guild must not be null'); return; } if (this.ahrs[lobbyId]) { - this.ahrs[lobbyId].lobby.logger.warn(`bot has already entered the lobby`); - await interaction.editReply("bot has already entered the lobby."); + this.ahrs[lobbyId].lobby.logger.warn('bot has already entered the lobby'); + await interaction.editReply('bot has already entered the lobby.'); return; } @@ -214,8 +214,8 @@ export class DiscordBot { ahr = new OahrDiscord(this.ircClient, this.sharedObjects); await ahr.enterLobbyAsync(lobbyId); } catch (e) { - logger.error("couldn't enter the tournament lobby. " + e); - await interaction.editReply("😫 couldn't enter the tournament lobby. " + e); + logger.error('couldn\'t enter the tournament lobby. ' + e); + await interaction.editReply('😫 couldn\'t enter the tournament lobby. ' + e); ahr?.lobby.destroy(); return; } @@ -224,153 +224,153 @@ export class DiscordBot { this.registeAhr(ahr, interaction); // ロビー用チャンネルからenterコマンドを引数無しで呼び出している場合はそのチャンネルでログ転送を開始する const ch = interaction.guild?.channels.cache.get(interaction.channelId); - if (ch && lobbyId == ("#" + ch.name)) { + if (ch && lobbyId == ('#' + ch.name)) { ahr.startTransferLog(ch.id); } await this.updateMatchSummary(ahr); await interaction.editReply(`😀 Entered the lobby [Lobby History](https://osu.ppy.sh/mp/${lobbyNumber})`); } catch (e) { - logger.error("couldn't make a discord channel. " + e); - await interaction.editReply("😫 couldn't make a discord channel. " + e); + logger.error('couldn\'t make a discord channel. ' + e); + await interaction.editReply('😫 couldn\'t make a discord channel. ' + e); } } async info(interaction: GuildCommandInteraction) { await interaction.deferReply(); - let lobbyId = this.resolveLobbyId(interaction); + const lobbyId = this.resolveLobbyId(interaction); if (!lobbyId) { - await interaction.editReply("error lobby_id required."); + await interaction.editReply('error lobby_id required.'); return; } if (!interaction.guild) { - logger.error("interaction.guild must not be null"); - await interaction.editReply("😫 interaction.guild must not be null"); + logger.error('interaction.guild must not be null'); + await interaction.editReply('😫 interaction.guild must not be null'); return; } - let ahr = this.ahrs[lobbyId]; + const ahr = this.ahrs[lobbyId]; if (!ahr) { - await interaction.editReply("Invalid lobby specified"); + await interaction.editReply('Invalid lobby specified'); return; } try { await interaction.editReply({ embeds: [ahr.createDetailInfoEmbed()] }); } catch (e: any) { - logger.error("@discordbot.info " + e); - await interaction.editReply("😫 error! " + e.message); + logger.error('@discordbot.info ' + e); + await interaction.editReply('😫 error! ' + e.message); } } async say(interaction: GuildCommandInteraction) { await interaction.deferReply(); - let lobbyId = this.resolveLobbyId(interaction); + const lobbyId = this.resolveLobbyId(interaction); if (!lobbyId) { - await interaction.editReply("error lobby_id required."); + await interaction.editReply('error lobby_id required.'); return; } - let ahr = this.ahrs[lobbyId]; + const ahr = this.ahrs[lobbyId]; if (!ahr) { - await interaction.editReply("Invalid lobby specified"); + await interaction.editReply('Invalid lobby specified'); return; } - let msg = interaction.options.getString("message", true); - if ((msg.startsWith("!") && !msg.startsWith("!mp ")) || msg.startsWith("*")) { + const msg = interaction.options.getString('message', true); + if ((msg.startsWith('!') && !msg.startsWith('!mp ')) || msg.startsWith('*')) { ahr.lobby.RaiseReceivedChatCommand(ahr.lobby.GetOrMakePlayer(ahr.client.nick), msg); - await interaction.editReply("executed: " + msg); + await interaction.editReply('executed: ' + msg); } else { ahr.lobby.SendMessage(msg); - await interaction.editReply("sent: " + msg); + await interaction.editReply('sent: ' + msg); } } async close(interaction: GuildCommandInteraction) { await interaction.deferReply(); - let lobbyId = this.resolveLobbyId(interaction); + const lobbyId = this.resolveLobbyId(interaction); if (!lobbyId) { - await interaction.editReply("error lobby_id required."); + await interaction.editReply('error lobby_id required.'); return; } - let ahr = this.ahrs[lobbyId]; + const ahr = this.ahrs[lobbyId]; if (!ahr) { - await interaction.editReply("Invalid lobby specified"); + await interaction.editReply('Invalid lobby specified'); return; } try { await ahr.lobby.CloseLobbyAsync(); - await interaction.editReply("Closed the lobby"); + await interaction.editReply('Closed the lobby'); } catch (e) { - logger.error("@discordbot.close " + e); - await interaction.editReply("😫 error! " + e); + logger.error('@discordbot.close ' + e); + await interaction.editReply('😫 error! ' + e); } } async quit(interaction: GuildCommandInteraction) { await interaction.deferReply(); - let lobbyId = this.resolveLobbyId(interaction); + const lobbyId = this.resolveLobbyId(interaction); if (!lobbyId) { - await interaction.editReply("error lobby_id required."); + await interaction.editReply('error lobby_id required.'); return; } - let ahr = this.ahrs[lobbyId]; + const ahr = this.ahrs[lobbyId]; if (!ahr) { - await interaction.editReply("Invalid lobby specified"); + await interaction.editReply('Invalid lobby specified'); return; } try { await ahr.lobby.QuitLobbyAsync(); - await interaction.editReply("Stopped managing the lobby"); + await interaction.editReply('Stopped managing the lobby'); } catch (e) { - logger.error("@discordbot.quit " + e); - await interaction.editReply("😫 error! " + e); + logger.error('@discordbot.quit ' + e); + await interaction.editReply('😫 error! ' + e); } } - async handleButtonInteraction(interaction: ButtonInteraction<"present">, command: string, lobbyNumber: string) { + async handleButtonInteraction(interaction: ButtonInteraction<'present'>, command: string, lobbyNumber: string) { if (!interaction.guild) return; - const lobbyId = "#mp_" + lobbyNumber; - let ahr = this.ahrs[lobbyId]; + const lobbyId = '#mp_' + lobbyNumber; + const ahr = this.ahrs[lobbyId]; if (!ahr) { await interaction.reply({content:`${lobbyId} - the lobby has already been unmanaged.`, ephemeral:true}); - }; + } try { switch (command) { - case "menu": + case 'menu': const menu = ahr.createControllButtons(); await interaction.reply({content:`${lobbyId} - menu`, components:[menu], ephemeral:true}); return; - case "close": + case 'close': await ahr.lobby.CloseLobbyAsync(); await interaction.reply({content:`${lobbyId} - closed`, ephemeral:true}); break; - case "startLog": + case 'startLog': await this.getOrCreateMatchChannel(interaction.guild, lobbyNumber); await interaction.reply({content:`${lobbyId} - start transfer`, ephemeral:true}); this.startTransferLog(ahr, interaction.guild); break; - case "stopLog": + case 'stopLog': ahr.stopTransferLog(); await interaction.reply({content:`${lobbyId} - stop transfer`, ephemeral:true}); break; } await this.updateMatchSummary(ahr); } catch (e) { - logger.error("@handleButtonInteraction " + e); + logger.error('@handleButtonInteraction ' + e); } } async getOrCreateMatchChannel(guild: Guild, lobbyNumber: string): Promise { - const lobbyId = "mp_" + lobbyNumber; + const lobbyId = 'mp_' + lobbyNumber; const dc = guild.channels.cache.find(c => c.name == lobbyId); if (dc) return dc as TextChannel; const role = guild.roles.cache.find(r => r.name == ADMIN_ROLE.name); return await guild.channels.create(lobbyId, { - type: "GUILD_TEXT", + type: 'GUILD_TEXT', topic: `created by ${this.discordClient.user?.username}. [history](https://osu.ppy.sh/community/matches/${lobbyNumber})`, permissionOverwrites: [ { @@ -378,11 +378,11 @@ export class DiscordBot { deny: [Permissions.FLAGS.VIEW_CHANNEL, Permissions.FLAGS.SEND_MESSAGES] }, { - id: role ?? "", + id: role ?? '', allow: [Permissions.FLAGS.VIEW_CHANNEL, Permissions.FLAGS.SEND_MESSAGES] }, { - id: this.discordClient.user?.id ?? "", + id: this.discordClient.user?.id ?? '', allow: [Permissions.FLAGS.VIEW_CHANNEL, Permissions.FLAGS.SEND_MESSAGES] } ] @@ -390,11 +390,11 @@ export class DiscordBot { } async getOrCreateMatchesChannel(guild: Guild): Promise { - const dc = guild.channels.cache.find(c => c.name.toLowerCase() == "matches"); + const dc = guild.channels.cache.find(c => c.name.toLowerCase() == 'matches'); if (dc) return dc as TextChannel; const role = guild.roles.cache.find(r => r.name == ADMIN_ROLE.name); - return await guild.channels.create("matches", { - type: "GUILD_TEXT", + return await guild.channels.create('matches', { + type: 'GUILD_TEXT', topic: `created by ${this.discordClient.user?.username}.`, permissionOverwrites: [ { @@ -402,11 +402,11 @@ export class DiscordBot { deny: [Permissions.FLAGS.VIEW_CHANNEL, Permissions.FLAGS.SEND_MESSAGES] }, { - id: role ?? "", + id: role ?? '', allow: [Permissions.FLAGS.VIEW_CHANNEL] }, { - id: this.discordClient.user?.id ?? "", + id: this.discordClient.user?.id ?? '', allow: [Permissions.FLAGS.VIEW_CHANNEL, Permissions.FLAGS.SEND_MESSAGES] } ] @@ -415,9 +415,9 @@ export class DiscordBot { registeAhr(ahr: OahrDiscord, interaction: GuildCommandInteraction) { if (!ahr.lobby.channel) { - throw new Error("lobbyId not defined"); + throw new Error('lobbyId not defined'); } - let lid = ahr.lobby.channel; + const lid = ahr.lobby.channel; const updateHandler = (a: { message: string, response: BanchoResponse, }) => { switch (a.response.type) { case BanchoResponseType.BeatmapChanged: @@ -428,7 +428,7 @@ export class DiscordBot { this.updateMatchSummary(ahr); break; } - } + }; ahr.lobby.ReceivedBanchoResponse.on(updateHandler); ahr.lobby.LeftChannel.once(() => { delete this.ahrs[lid]; @@ -443,7 +443,7 @@ export class DiscordBot { } async startTransferLog(ahr: OahrDiscord, guild: Guild) { - const dc = await this.getOrCreateMatchChannel(guild, ahr.lobby.lobbyId ?? ""); + const dc = await this.getOrCreateMatchChannel(guild, ahr.lobby.lobbyId ?? ''); ahr.startTransferLog(dc.id); this.ahrs[ahr.discordChannelId] = ahr; } @@ -459,7 +459,7 @@ export class DiscordBot { resolveLobbyId(interaction: CommandInteraction, asNumber: boolean = false): string | undefined { if (!interaction.inGuild()) return; - let op = interaction.options.getInteger("lobby_id", false); + const op = interaction.options.getInteger('lobby_id', false); if (op) { if (asNumber) { return op.toString(); @@ -468,7 +468,7 @@ export class DiscordBot { } } - let ahr = this.ahrs[interaction.channelId]; + const ahr = this.ahrs[interaction.channelId]; if (ahr && ahr.lobby.channel) { if (asNumber) { return ahr.lobby.lobbyId; @@ -477,14 +477,14 @@ export class DiscordBot { } } - let gc = interaction.guild?.channels.cache.get(interaction.channelId); + const gc = interaction.guild?.channels.cache.get(interaction.channelId); - let m = gc?.name.match(/mp_(\d+)/); + const m = gc?.name.match(/mp_(\d+)/); if (m) { if (asNumber) { return m[1]; } else { - return "#" + m[0]; + return '#' + m[0]; } } @@ -504,16 +504,16 @@ export class DiscordBot { createLinkButton(lobbyNumber: string) { return new MessageActionRow().addComponents( - new MessageButton().setStyle("LINK").setLabel("Lobby Histroy").setURL(`https://osu.ppy.sh/community/matches/${lobbyNumber}`), - new MessageButton().setStyle("LINK").setLabel("Channel").setURL(``) - ) + new MessageButton().setStyle('LINK').setLabel('Lobby Histroy').setURL(`https://osu.ppy.sh/community/matches/${lobbyNumber}`), + new MessageButton().setStyle('LINK').setLabel('Channel').setURL('') + ); } async updateMatchSummary(ahr: OahrDiscord) { if (!ahr.updateSummaryMessage) return; try { const guild = this.discordClient.guilds.cache.find(f => f.id == ahr.guildId); - if (guild == undefined) throw new Error("guild not found"); + if (guild == undefined) throw new Error('guild not found'); const channel = await this.getOrCreateMatchesChannel(guild); const embed = ahr.createSummaryInfoEmbed(); const btns = ahr.createMenuButton(); @@ -526,7 +526,7 @@ export class DiscordBot { ahr.matchSummaryMessageId = message.id; } catch (e: any) { if (e instanceof DiscordAPIError) { - if (e.message == "Missing Permissions") { + if (e.message == 'Missing Permissions') { logger.error(`Missing Permissions. Invite this bot again. invite link => ${this.generateInviteLink()}`); return; } @@ -538,12 +538,12 @@ export class DiscordBot { async findMatchSummaryMessage(channel: TextChannel, ahr: OahrDiscord) { let message: Message | undefined; - if (ahr.matchSummaryMessageId != "") { + if (ahr.matchSummaryMessageId != '') { message = await channel.messages.fetch(ahr.matchSummaryMessageId); } if (message) return message; const msgs = await channel.messages.fetch({ limit: 10 }); - const recent = msgs.find(f => (f.embeds && f.embeds.length > 0 && f.embeds[0].title == `#mp_${ahr.lobby.lobbyId ?? ""}`)); + const recent = msgs.find(f => (f.embeds && f.embeds.length > 0 && f.embeds[0].title == `#mp_${ahr.lobby.lobbyId ?? ''}`)); if (recent) return recent; } diff --git a/src/discord/OahrDiscord.ts b/src/discord/OahrDiscord.ts index dba78a27..393cdd99 100644 --- a/src/discord/OahrDiscord.ts +++ b/src/discord/OahrDiscord.ts @@ -7,29 +7,29 @@ import { OahrSharedObjects } from './DiscordBot'; import { MessageActionRow, MessageButton, MessageEmbed } from 'discord.js'; import { MessageButtonStyles } from 'discord.js/typings/enums'; -const logger = log4js.getLogger("discord"); +const logger = log4js.getLogger('discord'); const LOBBY_STAT = { match: { - text: "match", + text: 'match', color: 0x33ff33 }, idle: { - text: "idle", + text: 'idle', color: 0x00ccff }, closed: { - text: "closed", + text: 'closed', color: 0x800000 } -} +}; export class OahrDiscord extends OahrBase { - guildId: string = ""; - discordChannelId: string = ""; + guildId: string = ''; + discordChannelId: string = ''; transferLog: boolean = false; updateSummaryMessage: boolean = true; - matchSummaryMessageId: string = ""; + matchSummaryMessageId: string = ''; constructor(client: IIrcClient, sh: OahrSharedObjects) { super(client); @@ -38,21 +38,21 @@ export class OahrDiscord extends OahrBase { setGuildId(guildId: string) { this.guildId = guildId; for (const l of this.getLoggers()) { - l.addContext("guildId", guildId); + l.addContext('guildId', guildId); } } startTransferLog(discordChannelId: string) { for (const l of this.getLoggers()) { - l.addContext("channelId", discordChannelId); - l.addContext("transfer", true); + l.addContext('channelId', discordChannelId); + l.addContext('transfer', true); } this.transferLog = true; } stopTransferLog() { for (const l of this.getLoggers()) { - l.addContext("transfer", false); + l.addContext('transfer', false); } this.transferLog = false; } @@ -63,37 +63,37 @@ export class OahrDiscord extends OahrBase { createDetailInfoEmbed() { const lobby = this.lobby; - const lid = lobby.lobbyId ?? ""; - const name = lobby.lobbyName ?? ""; - const host = lobby.host?.name ?? "none"; + const lid = lobby.lobbyId ?? ''; + const name = lobby.lobbyName ?? ''; + const host = lobby.host?.name ?? 'none'; - const embed = new MessageEmbed().setColor("BLURPLE").setTitle("Lobby Information - " + name).setURL(`https://osu.ppy.sh/community/matches/${lid}`); - embed.addField("lobby", `id:${lid}, status:${LobbyStatus[lobby.status]}, host:${host}, players:${lobby.players.size}, name:${name}`,); - const refs = Array.from(lobby.playersMap.values()).filter(v => v.isReferee).map(v => v.name).join(","); + const embed = new MessageEmbed().setColor('BLURPLE').setTitle('Lobby Information - ' + name).setURL(`https://osu.ppy.sh/community/matches/${lid}`); + embed.addField('lobby', `id:${lid}, status:${LobbyStatus[lobby.status]}, host:${host}, players:${lobby.players.size}, name:${name}`,); + const refs = Array.from(lobby.playersMap.values()).filter(v => v.isReferee).map(v => v.name).join(','); if (refs) { - embed.addField("referee", refs, false); + embed.addField('referee', refs, false); } const ho = this.getPlayerOrders(); - if (ho != "") { - embed.addField("host order", ho, false); + if (ho != '') { + embed.addField('host order', ho, false); } embed.addField(`map - ${lobby.mapTitle}`, `https://osu.ppy.sh/b/${lobby.mapId}`, false); - embed.addField("selector", `changer:${this.selector.mapChanger?.name ?? "none"}, rflag:${this.selector.needsRotate ? "true" : "false"}`, false); + embed.addField('selector', `changer:${this.selector.mapChanger?.name ?? 'none'}, rflag:${this.selector.needsRotate ? 'true' : 'false'}`, false); const denylist = this.selector.getDeniedPlayerNames(); if (denylist.length != 0) { - embed.addField("denylist", `${denylist.join(", ")}`); + embed.addField('denylist', `${denylist.join(', ')}`); } - embed.addField("history", `${this.history.repository.hasError ? "stopped" : "active"}, latest:${this.history.repository?.latestEventId.toString() ?? "0"}, loaded:${this.history.repository?.events.length.toString() ?? "0"}`, false); - embed.addField("regulation", this.checker.getRegulationDescription(), false); + embed.addField('history', `${this.history.repository.hasError ? 'stopped' : 'active'}, latest:${this.history.repository?.latestEventId.toString() ?? '0'}, loaded:${this.history.repository?.events.length.toString() ?? '0'}`, false); + embed.addField('regulation', this.checker.getRegulationDescription(), false); const keeps = this.keeper.getDescription(); - if (keeps != "") { - embed.addField("keeps", keeps, false); + if (keeps != '') { + embed.addField('keeps', keeps, false); } return embed; @@ -102,23 +102,23 @@ export class OahrDiscord extends OahrBase { createSummaryInfoEmbed() { const lobby = this.lobby; const stat = lobby.status == LobbyStatus.Left ? LOBBY_STAT.closed : lobby.isMatching ? LOBBY_STAT.match : LOBBY_STAT.idle; - const lid = lobby.lobbyId ?? ""; - const name = lobby.lobbyName ?? ""; - const host = lobby.host?.name ?? "none"; + const lid = lobby.lobbyId ?? ''; + const name = lobby.lobbyName ?? ''; + const host = lobby.host?.name ?? 'none'; const embed = new MessageEmbed().setColor(stat.color).setTitle(`#mp_${lid}`).setURL(`https://osu.ppy.sh/community/matches/${lid}`); - embed.addField("title", name, true); - embed.addField("status", stat.text, true); - embed.addField("host", host, true); - embed.addField("regulation", this.checker.getRegulationDescription(), true); + embed.addField('title', name, true); + embed.addField('status', stat.text, true); + embed.addField('host', host, true); + embed.addField('regulation', this.checker.getRegulationDescription(), true); embed.addField(`map - ${lobby.mapTitle}`, `https://osu.ppy.sh/b/${lobby.mapId}`, false); const ho = this.getPlayerOrders(); - if (ho != "") { - embed.addField("host order", ho, false); + if (ho != '') { + embed.addField('host order', ho, false); } const keeps = this.keeper.getDescription(); - if (keeps != "") { - embed.addField("keeps", keeps, false); + if (keeps != '') { + embed.addField('keeps', keeps, false); } embed.setTimestamp(); return embed; @@ -126,20 +126,20 @@ export class OahrDiscord extends OahrBase { createMenuButton() { const cid = this.lobby.channel; // #mp_xxxx - if (cid == undefined) throw new Error("invalid ahr lobby state. channel is undefined"); - return new MessageActionRow().addComponents(new MessageButton().setLabel("Menu").setStyle(MessageButtonStyles.PRIMARY).setCustomId("menu," + cid)); + if (cid == undefined) throw new Error('invalid ahr lobby state. channel is undefined'); + return new MessageActionRow().addComponents(new MessageButton().setLabel('Menu').setStyle(MessageButtonStyles.PRIMARY).setCustomId('menu,' + cid)); } createControllButtons() { const cid = this.lobby.channel; // #mp_xxxx - if (cid == undefined) throw new Error("invalid ahr lobby state. channel is undefined"); + if (cid == undefined) throw new Error('invalid ahr lobby state. channel is undefined'); const btn1 = new MessageButton(); - const btn2 = new MessageButton().setLabel("close").setStyle(MessageButtonStyles.DANGER).setCustomId("close," + cid); // close,#mp_xxxx + const btn2 = new MessageButton().setLabel('close').setStyle(MessageButtonStyles.DANGER).setCustomId('close,' + cid); // close,#mp_xxxx if (this.transferLog) { - btn1.setLabel("Stop transfer").setStyle(MessageButtonStyles.SECONDARY).setCustomId("stopLog," + cid); // stopLog,#mp_xxxx + btn1.setLabel('Stop transfer').setStyle(MessageButtonStyles.SECONDARY).setCustomId('stopLog,' + cid); // stopLog,#mp_xxxx } else { - btn1.setLabel("Start transfer").setStyle(MessageButtonStyles.PRIMARY).setCustomId("startLog," + cid); // stopLog,#mp_xxxx + btn1.setLabel('Start transfer').setStyle(MessageButtonStyles.PRIMARY).setCustomId('startLog,' + cid); // stopLog,#mp_xxxx } const row = new MessageActionRow().addComponents(btn1, btn2); @@ -155,7 +155,7 @@ export class OahrDiscord extends OahrBase { playcount: this.inoutLogger.players.get(p) ?? 0, slot: p.slot, order: 16 - } + }; map.set(p, info); } for (const [i, p] of this.selector.hostQueue.entries()) { @@ -166,6 +166,6 @@ export class OahrDiscord extends OahrBase { } const fields = [...map.values()].sort((a, b) => a.order - b.order).map((info) => `${info.name}(${info.playcount})`); - return fields.join(", "); + return fields.join(', '); } } diff --git a/src/discord/index.ts b/src/discord/index.ts index f1917420..fce6eaa9 100644 --- a/src/discord/index.ts +++ b/src/discord/index.ts @@ -7,41 +7,41 @@ import { CONFIG_OPTION, getIrcConfig } from '../TypedConfig'; import { logPrivateMessage } from '../IIrcClient'; import { applySpeedLimit } from '../libs/ChatLimiter'; -const logger = log4js.getLogger("cli"); +const logger = log4js.getLogger('cli'); -console.log("starting up..."); +console.log('starting up...'); -const config_path = "./config/log_discord.json"; +const config_path = './config/log_discord.json'; log4js.configure(config_path); try { - CONFIG_OPTION.USE_ENV = true; - const c = getIrcConfig(); - if (c.nick == "your account id" || c.opt.password == "you can get password from 'https://osu.ppy.sh/p/irc'") { - logger.error("you must enter your account name and irc password in the config file. "); - logger.error("you can get the password from 'https://osu.ppy.sh/p/irc' "); - logger.error("Copy config/default.json to config/local.json, and enter your id and irc password."); - process.exit(1); + CONFIG_OPTION.USE_ENV = true; + const c = getIrcConfig(); + if (c.nick == 'your account id' || c.opt.password == 'you can get password from \'https://osu.ppy.sh/p/irc\'') { + logger.error('you must enter your account name and irc password in the config file. '); + logger.error('you can get the password from \'https://osu.ppy.sh/p/irc\' '); + logger.error('Copy config/default.json to config/local.json, and enter your id and irc password.'); + process.exit(1); + } + + const ircClient = new irc.Client(c.server, c.nick, c.opt); + ircClient.on('error', err => { + if (err.command == 'err_passwdmismatch') { + logger.error('%s: %s', err.command, err.args.join(' ')); + logger.error('check your account id and password.'); + process.exit(1); } + }); + applySpeedLimit(ircClient, 10, 5000); + logIrcEvent(ircClient); + logPrivateMessage(ircClient); + + const discordClient = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_INTEGRATIONS] }); - let ircClient = new irc.Client(c.server, c.nick, c.opt); - ircClient.on("error", err => { - if (err.command == "err_passwdmismatch") { - logger.error('%s: %s', err.command, err.args.join(' ')); - logger.error("check your account id and password."); - process.exit(1); - } - }); - applySpeedLimit(ircClient, 10, 5000); - logIrcEvent(ircClient); - logPrivateMessage(ircClient); - - let discordClient = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_INTEGRATIONS] }); - - const bot = new DiscordBot(ircClient, discordClient); - bot.start(); + const bot = new DiscordBot(ircClient, discordClient); + bot.start(); } catch (e: any) { - logger.error(e); - process.exit(1); + logger.error(e); + process.exit(1); } diff --git a/src/dummies/DummyHistoryFetcher.ts b/src/dummies/DummyHistoryFetcher.ts index 4fe495e9..8e3757f0 100644 --- a/src/dummies/DummyHistoryFetcher.ts +++ b/src/dummies/DummyHistoryFetcher.ts @@ -12,29 +12,29 @@ export class DummyHistoryFecher implements IHistoryFetcher { this.match = { end_time: null, id: 0, - name: "dummy match", + name: 'dummy match', start_time: (new Date(this.timestamp)).toUTCString() }; this.events = []; this.users = []; - this.addEvent("match-created", creatorId); - this.addEvent("host-changed", creatorId); + this.addEvent('match-created', creatorId); + this.addEvent('host-changed', creatorId); } fetchHistory(limit: number, before: number | null, after: number | null, matchId: number = 0): Promise { - let events = []; + const events = []; limit = Math.max(1, Math.min(this.limit, limit)); if (after) { after = Math.max(after, -1); - let end = Math.min(after + limit + 1, this.events.length); + const end = Math.min(after + limit + 1, this.events.length); for (let i = after + 1; i < end; i++) { events.push(this.events[i]); } } else { before = Math.min(before ?? this.events.length, this.events.length); - let start = Math.max(0, before - limit); + const start = Math.max(0, before - limit); for (let i = start; i < before; i++) { events.push(this.events[i]); } @@ -73,7 +73,7 @@ export class DummyHistoryFecher implements IHistoryFetcher { this.events.push({ id: this.events.length, detail: { - type: "other", + type: 'other', text: title }, timestamp: (new Date(this.timestamp)).toUTCString(), @@ -83,7 +83,7 @@ export class DummyHistoryFecher implements IHistoryFetcher { member.forEach(m => { if (!this.existsUser(m)) { - throw new Error("unknown member joined game"); + throw new Error('unknown member joined game'); } }); } @@ -94,14 +94,14 @@ export class DummyHistoryFecher implements IHistoryFetcher { beatmap: {}, end_time: ended ? n : null, id: id, - mode: "osu", + mode: 'osu', mode_int: 0, mods: [], scores: [], - scoring_type: "score", + scoring_type: 'score', start_time: n, - team_type: "head-to-head" - } + team_type: 'head-to-head' + }; } createDummyScores(nums: number[]): Score[] { @@ -114,7 +114,7 @@ export class DummyHistoryFecher implements IHistoryFetcher { created_at: null, match: { slot: v, - team: "none", + team: 'none', pass: 1 }, max_combo: 100, @@ -137,8 +137,8 @@ export class DummyHistoryFecher implements IHistoryFetcher { if (userId != null && !this.existsUser(userId)) { this.users.push({ avatar_url: null, - country_code: "AA", - default_group: "default", + country_code: 'AA', + default_group: 'default', id: userId, is_active: true, is_bot: false, @@ -147,10 +147,10 @@ export class DummyHistoryFecher implements IHistoryFetcher { last_visit: this.match.start_time, pm_friends_only: false, profile_colour: null, - username: "user" + userId, + username: 'user' + userId, country: { - code: "AA", - name: "AA" + code: 'AA', + name: 'AA' } }); } diff --git a/src/dummies/DummyIrcClient.ts b/src/dummies/DummyIrcClient.ts index 47929e1a..3887631e 100644 --- a/src/dummies/DummyIrcClient.ts +++ b/src/dummies/DummyIrcClient.ts @@ -6,7 +6,7 @@ import { escapeUserName } from '../Player'; import { MpSettingsCase } from '../tests/cases/MpSettingsCases'; import log4js from 'log4js'; import { EventEmitter } from 'events'; -const logger = log4js.getLogger("irc"); +const logger = log4js.getLogger('irc'); // テスト用の実際に通信を行わないダミーIRCクライアント export class DummyIrcClient extends EventEmitter implements IIrcClient { @@ -18,7 +18,7 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { stats: Map; conn: boolean | null; isMatching: boolean; - hostMask: string = ""; + hostMask: string = ''; latency: number = 0; referees: string[]; @@ -29,7 +29,7 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { ) { super(); this.nick = nick; - this.channel = ""; + this.channel = ''; this.connected = false; this.players = new Set(); this.stats = new Map(); @@ -37,8 +37,8 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { this.isMatching = false; this.referees = [this.nick]; this.msg = { - command: "dummy command", - rawCommand: "dummy command", + command: 'dummy command', + rawCommand: 'dummy command', commandType: 0 as irc.CommandType, args: [] }; @@ -51,7 +51,7 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { // サーバーとの接続イベントを発行する public raiseRegistered(): void { this.connected = true; - this.hostMask = "osu!Bancho."; + this.hostMask = 'osu!Bancho.'; this.emit('registered', this.msg); } @@ -60,22 +60,22 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { if (who == this.nick) { this.channel = channel; } - this.emit("join", channel, who, this.msg); - this.emit("join" + channel, who, this.msg); + this.emit('join', channel, who, this.msg); + this.emit('join' + channel, who, this.msg); } // チャンネル退出イベントを発行する public raisePart(channel: string, who: string): void { if (who == this.nick) { - this.channel = ""; + this.channel = ''; } - this.emit("part", channel, who, this.msg); - this.emit("part" + channel, who, this.msg); + this.emit('part', channel, who, this.msg); + this.emit('part' + channel, who, this.msg); } // メッセージイベントを発行する public emulateMessage(from: string, to: string, message: string): void { - const lines = message.split("\n"); + const lines = message.split('\n'); if (lines.length > 1) { lines.forEach(v => this.emulateMessage(from, to, v)); return; @@ -99,7 +99,7 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { const body = () => { this.emulateMessage(from, to, message); resolve(); - } + }; if (this.latency != 0) { setTimeout(body, this.latency); @@ -110,7 +110,7 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { } public emulateBanchoResponse(message: string): void { - this.emulateMessage("BanchoBot", this.channel, message); + this.emulateMessage('BanchoBot', this.channel, message); } public emulateChatAsync(from: string, message: string): Promise { @@ -119,20 +119,20 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { // ロビーにプレイヤーが参加した際の動作をエミュレートする public async emulateAddPlayerAsync(name: string): Promise { - let ename = escapeUserName(name); + const ename = escapeUserName(name); if (!this.players.has(ename)) { this.players.add(ename); } - await this.emulateMessageAsync("BanchoBot", this.channel, `${name} joined in slot ${this.players.size}.`); + await this.emulateMessageAsync('BanchoBot', this.channel, `${name} joined in slot ${this.players.size}.`); } // ロビーからプレイヤーが退出した際の動作をエミュレートする public async emulateRemovePlayerAsync(name: string): Promise { - let ename = escapeUserName(name); + const ename = escapeUserName(name); if (this.players.has(ename)) { this.players.delete(ename); } - await this.emulateMessageAsync("BanchoBot", this.channel, `${name} left the game.`); + await this.emulateMessageAsync('BanchoBot', this.channel, `${name} left the game.`); } // async呼び出し用のディレイ関数 @@ -147,100 +147,100 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { if (mapid == 0) { mapid = this.mapidSeed++; } - await this.emulateMessageAsync("BanchoBot", this.channel, "Host is changing map..."); + await this.emulateMessageAsync('BanchoBot', this.channel, 'Host is changing map...'); await this.delay(delay); - await this.emulateMessageAsync("BanchoBot", this.channel, `Beatmap changed to: mapname [version] (https://osu.ppy.sh/b/${mapid})`); + await this.emulateMessageAsync('BanchoBot', this.channel, `Beatmap changed to: mapname [version] (https://osu.ppy.sh/b/${mapid})`); } // 全員が準備完了になった動作をエミュレートする public async emulateReadyAsync(): Promise { - await this.emulateMessageAsync("BanchoBot", this.channel, "All players are ready"); + await this.emulateMessageAsync('BanchoBot', this.channel, 'All players are ready'); } // 試合をエミュレートする public async emulateMatchAsync(delay: number = 0, scores?: { name: string, score: number, passed: boolean }[]): Promise { this.isMatching = true; - await this.emulateMessageAsync("BanchoBot", this.channel, "The match has started!"); + await this.emulateMessageAsync('BanchoBot', this.channel, 'The match has started!'); if (delay) { await this.delay(delay); } const tasks: Promise[] = []; if (scores) { - for (let u of scores) { + for (const u of scores) { if (!this.isMatching) return; - tasks.push(this.emulateMessageAsync("BanchoBot", this.channel, `${u.name} finished playing (Score: ${u.score}, ${u.passed ? "PASSED" : "FAILED"}).`)); + tasks.push(this.emulateMessageAsync('BanchoBot', this.channel, `${u.name} finished playing (Score: ${u.score}, ${u.passed ? 'PASSED' : 'FAILED'}).`)); } } else { - for (let u of this.players) { + for (const u of this.players) { if (!this.isMatching) return; - tasks.push(this.emulateMessageAsync("BanchoBot", this.channel, `${u} finished playing (Score: 100000, PASSED).`)); + tasks.push(this.emulateMessageAsync('BanchoBot', this.channel, `${u} finished playing (Score: 100000, PASSED).`)); } } await Promise.all(tasks); if (!this.isMatching) return; this.isMatching = false; - await this.emulateMessageAsync("BanchoBot", this.channel, "The match has finished!"); + await this.emulateMessageAsync('BanchoBot', this.channel, 'The match has finished!'); } // 試合中断をエミュレートする public async emulateMatchAndAbortAsync(delay: number = 0, finishers: (number | string[]) = 0): Promise { this.isMatching = true; - await this.emulateMessageAsync("BanchoBot", this.channel, "The match has started!"); + await this.emulateMessageAsync('BanchoBot', this.channel, 'The match has started!'); if (delay) { await this.delay(delay); } const tasks: Promise[] = []; if (Array.isArray(finishers)) { - for (let p of finishers) { + for (const p of finishers) { tasks.push(this.emulatePlayerFinishAsync(p)); } } else { const players = Array.from(this.players); for (let i = 0; i < finishers && i < players.length; i++) { - let p = players[i]; + const p = players[i]; tasks.push(this.emulatePlayerFinishAsync(p)); } } await Promise.all(tasks); if (!this.isMatching) { - await this.emulateMessageAsync("BanchoBot", this.channel, "The match is not in progress"); + await this.emulateMessageAsync('BanchoBot', this.channel, 'The match is not in progress'); return; } this.isMatching = false; - await this.emulateMessageAsync("BanchoBot", this.channel, "Aborted the match"); + await this.emulateMessageAsync('BanchoBot', this.channel, 'Aborted the match'); } public async emulatePlayerFinishAsync(username: string): Promise { - await this.emulateMessageAsync("BanchoBot", this.channel, `${username} finished playing (Score: 100000, PASSED).`) + await this.emulateMessageAsync('BanchoBot', this.channel, `${username} finished playing (Score: 100000, PASSED).`); } public async emulateMpSettings(testcase: MpSettingsCase): Promise { this.players.clear(); - for (let p of testcase.result.players) { + for (const p of testcase.result.players) { this.players.add(escapeUserName(p.name)); } - for (let t of testcase.texts) { + for (const t of testcase.texts) { this.emulateBanchoResponse(t); } } public async emulateChangeHost(name: string): Promise { - await this.emulateMessageAsync("BanchoBot", this.channel, `${name} became the host.`); + await this.emulateMessageAsync('BanchoBot', this.channel, `${name} became the host.`); } // IRCClientのjoin public join(channel: string, callback?: irc.handlers.IJoinChannel | undefined): void { if (callback) { - this.once("join", callback); + this.once('join', callback); } - setImmediate(() => this.raiseJoin(channel, "")); + setImmediate(() => this.raiseJoin(channel, '')); } // IRCClientのpart public part(channel: string, message: string, callback?: irc.handlers.IPartChannel): void { if (callback) { - this.once("part", callback); + this.once('part', callback); } setImmediate(() => { this.raisePart(channel, this.nick); @@ -254,109 +254,109 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { private onMessage(from: string, to: string, message: string) { if (this.referees.includes(from)) { - let mp = parser.ParseMPCommand(message); + const mp = parser.ParseMPCommand(message); if (mp != null) { this.processMpCommand(to, message, mp); } } - if (message.startsWith("!stat")) { + if (message.startsWith('!stat')) { const m = message.match(/^!stats? (.+)/); if (m) { - this.sendStat(m[1], to == "BanchoBot"); + this.sendStat(m[1], to == 'BanchoBot'); } } } private processMpCommand(target: string, message: string, mp: MpCommand): void { - const m = (msg: string) => this.emulateMessageAsync("BanchoBot", this.channel, msg); - if (target == "BanchoBot" && mp.command == "make") { + const m = (msg: string) => this.emulateMessageAsync('BanchoBot', this.channel, msg); + if (target == 'BanchoBot' && mp.command == 'make') { const title = mp.arg; - if (title === "") { - this.emulateMessage("BanchoBot", this.nick, "No name provided"); + if (title === '') { + this.emulateMessage('BanchoBot', this.nick, 'No name provided'); return; } setImmediate(() => { - let id = "12345"; - this.raiseJoin("#mp_" + id, this.nick); - this.emulateMessage("BanchoBot", this.nick, `Created the tournament match https://osu.ppy.sh/mp/${id} ${title}`); + const id = '12345'; + this.raiseJoin('#mp_' + id, this.nick); + this.emulateMessage('BanchoBot', this.nick, `Created the tournament match https://osu.ppy.sh/mp/${id} ${title}`); }); } else if (target == this.channel) { switch (mp.command) { - case "host": + case 'host': if (this.players.has(escapeUserName(mp.arg))) { m(`${mp.arg} became the host.`); } else { - m("User not found"); + m('User not found'); } break; - case "password": - if (mp.arg == "") { - m("Removed the match password"); + case 'password': + if (mp.arg == '') { + m('Removed the match password'); } else { - m("Changed the match password"); + m('Changed the match password'); } break; - case "invite": + case 'invite': m(`Invited ${mp.arg} to the room`); break; - case "close": + case 'close': setImmediate(() => { - this.emulateMessage("BanchoBot", this.channel, "Closed the match"); + this.emulateMessage('BanchoBot', this.channel, 'Closed the match'); this.raisePart(this.channel, this.nick); }); break; - case "abort": + case 'abort': if (this.isMatching) { this.isMatching = false; - m("Aborted the match"); + m('Aborted the match'); } else { - m("The match is not in progress"); + m('The match is not in progress'); } break; - case "settings": + case 'settings': m('Room name: lobby name, History: https://osu.ppy.sh/mp/123'); - m("Beatmap: https://osu.ppy.sh/b/1562893 Feryquitous feat. Aitsuki Nakuru - Kairikou [Miura's Extra]"); - m("Team mode: HeadToHead, Win condition: Score"); - m("Active mods: Freemod"); + m('Beatmap: https://osu.ppy.sh/b/1562893 Feryquitous feat. Aitsuki Nakuru - Kairikou [Miura\'s Extra]'); + m('Team mode: HeadToHead, Win condition: Score'); + m('Active mods: Freemod'); m(`Players: ${this.players.size}`); let i = 1; - for (let p of this.players) { + for (const p of this.players) { m(`Slot ${i} Not Ready https://osu.ppy.sh/u/123 ${p} `); i++; } break; - case "start": - if (mp.arg == "") { - m("The match has started!"); - m("Started the match"); + case 'start': + if (mp.arg == '') { + m('The match has started!'); + m('Started the match'); } else { // カウントダウンや分表示は面倒なので省略 - m("Match starts in " + mp.arg + " seconds"); - m("Queued the match to start in " + mp.arg + " seconds"); + m('Match starts in ' + mp.arg + ' seconds'); + m('Queued the match to start in ' + mp.arg + ' seconds'); } break; - case "aborttimer": - m("Countdown aborted") + case 'aborttimer': + m('Countdown aborted'); break; - case "map": + case 'map': if (mp.arg.match(/\d+/)) { m(`Changed beatmap to https://osu.ppy.sh/b/${mp.arg} map name`); } else { - m("Invalid map ID provided"); + m('Invalid map ID provided'); } break; - case "clearhost": - m("Cleared match host"); + case 'clearhost': + m('Cleared match host'); break; - case "kick": - let ename = escapeUserName(mp.arg); + case 'kick': + const ename = escapeUserName(mp.arg); if (this.players.has(ename)) { this.players.delete(ename); m(`${ename} left the game.`); m(`Kicked ${ename} from the match.`); } else { - m("User not found"); + m('User not found'); } break; default: @@ -375,12 +375,12 @@ export class DummyIrcClient extends EventEmitter implements IIrcClient { let stat = this.stats.get(ename); const to = toPm ? this.nick : this.channel; if (stat == undefined) { - let status = this.players.has(ename) ? StatStatuses.Multiplayer : StatStatuses.None; + const status = this.players.has(ename) ? StatStatuses.Multiplayer : StatStatuses.None; stat = new StatResult(arg, 0, status); this.stats.set(ename, stat); } - stat.toString().split("\n").forEach(t => { - this.emulateMessage("BanchoBot", to, t); + stat.toString().split('\n').forEach(t => { + this.emulateMessage('BanchoBot', to, t); }); } diff --git a/src/dummies/DummyLobbyPlugin.ts b/src/dummies/DummyLobbyPlugin.ts index 4340eb2a..9b19b1c0 100644 --- a/src/dummies/DummyLobbyPlugin.ts +++ b/src/dummies/DummyLobbyPlugin.ts @@ -4,7 +4,7 @@ import { LobbyPlugin } from '../plugins/LobbyPlugin'; export class DummyLobbyPlugin extends LobbyPlugin { constructor(lobby: Lobby) { - super(lobby, "dummy"); + super(lobby, 'dummy'); } GetPluginStatus(): string { diff --git a/src/dummies/FakeBeatmapFetcher.ts b/src/dummies/FakeBeatmapFetcher.ts index c2ea5cd4..8abeda61 100644 --- a/src/dummies/FakeBeatmapFetcher.ts +++ b/src/dummies/FakeBeatmapFetcher.ts @@ -2,155 +2,155 @@ import { PlayMode } from '../Modes'; import { FetchBeatmapError, FetchBeatmapErrorReason, IBeatmapFetcher } from '../webapi/BeatmapRepository'; import { Beatmap, Beatmapset } from '../webapi/Beatmapsets'; -const MODES = ["osu", "taiko", "fruits", "mania"] +const MODES = ['osu', 'taiko', 'fruits', 'mania']; export class FakeBeatmapFetcher implements IBeatmapFetcher { - beatmapTemplate: Beatmap = { - beatmapset_id: 100, - difficulty_rating: 5.00, - id: 100, - mode: "osu", - status: "ranked", - total_length: 300, - version: "Insane", - accuracy: 5, - ar: 9, - bpm: 175, - convert: false, - count_circles: 161, - count_sliders: 420, - count_spinners: 0, - cs: 4, - deleted_at: null, - drain: 5, - hit_length: 216, - is_scoreable: true, - last_updated: "2021-06-30T00:00:00+00:00", - mode_int: 0, - passcount: 100, - playcount: 100, - ranked: 1, - url: "https:\/\/osu.ppy.sh\/beatmaps\/100", - failtimes: { - fail: [0, 0], - exit: [0, 0] - }, - max_combo: 1100, - }; - - beatmapsetTemplate: Beatmapset = { - "artist": "art", - "artist_unicode": "art", - "covers": { - "cover": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/cover.jpg?1000", - "cover@2x": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/cover@2x.jpg?1000", - "card": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/card.jpg?1000", - "card@2x": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/card@2x.jpg?1000", - "list": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/list.jpg?1000", - "list@2x": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/list@2x.jpg?1000", - "slimcover": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/slimcover.jpg?1000", - "slimcover@2x": "https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/slimcover@2x.jpg?1000" - }, - "creator": "theramdans", - "favourite_count": 100, - "hype": null, - "id": 100, - "nsfw": false, - "play_count": 100, - "preview_url": "\/\/b.ppy.sh\/preview\/100.mp3", - "source": "", - "status": "ranked", - "title": "title", - "title_unicode": "title", - "track_id": 100, - "user_id": 100, - "video": false, - "availability": { - "download_disabled": false, - "more_information": null - }, - "bpm": 175, - "can_be_hyped": false, - "discussion_enabled": true, - "discussion_locked": false, - "is_scoreable": true, - "last_updated": "2021-06-30T17:39:11+00:00", - "legacy_thread_url": "https:\/\/osu.ppy.sh\/community\/forums\/topics\/100", - "nominations_summary": { - "current": 2, - "required": 2 - }, - "ranked": 1, - "ranked_date": "2021-07-08T19:43:54+00:00", - "storyboard": true, - "submitted_date": "2020-12-14T10:48:15+00:00", - "tags": "", - "has_favourited": false, - "beatmaps": [], - "converts": [], - "description": { - "description": "" - }, - "genre": { - "id": 5, - "name": "Pop" - }, - "language": { - "id": 3, - "name": "Japanese" - }, - "ratings": [], - "recent_favourites": [] - } + beatmapTemplate: Beatmap = { + beatmapset_id: 100, + difficulty_rating: 5.00, + id: 100, + mode: 'osu', + status: 'ranked', + total_length: 300, + version: 'Insane', + accuracy: 5, + ar: 9, + bpm: 175, + convert: false, + count_circles: 161, + count_sliders: 420, + count_spinners: 0, + cs: 4, + deleted_at: null, + drain: 5, + hit_length: 216, + is_scoreable: true, + last_updated: '2021-06-30T00:00:00+00:00', + mode_int: 0, + passcount: 100, + playcount: 100, + ranked: 1, + url: 'https:\/\/osu.ppy.sh\/beatmaps\/100', + failtimes: { + fail: [0, 0], + exit: [0, 0] + }, + max_combo: 1100, + }; - beatmapset: Beatmapset; - id: number; + beatmapsetTemplate: Beatmapset = { + 'artist': 'art', + 'artist_unicode': 'art', + 'covers': { + 'cover': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/cover.jpg?1000', + 'cover@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/cover@2x.jpg?1000', + 'card': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/card.jpg?1000', + 'card@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/card@2x.jpg?1000', + 'list': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/list.jpg?1000', + 'list@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/list@2x.jpg?1000', + 'slimcover': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/slimcover.jpg?1000', + 'slimcover@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/slimcover@2x.jpg?1000' + }, + 'creator': 'theramdans', + 'favourite_count': 100, + 'hype': null, + 'id': 100, + 'nsfw': false, + 'play_count': 100, + 'preview_url': '\/\/b.ppy.sh\/preview\/100.mp3', + 'source': '', + 'status': 'ranked', + 'title': 'title', + 'title_unicode': 'title', + 'track_id': 100, + 'user_id': 100, + 'video': false, + 'availability': { + 'download_disabled': false, + 'more_information': null + }, + 'bpm': 175, + 'can_be_hyped': false, + 'discussion_enabled': true, + 'discussion_locked': false, + 'is_scoreable': true, + 'last_updated': '2021-06-30T17:39:11+00:00', + 'legacy_thread_url': 'https:\/\/osu.ppy.sh\/community\/forums\/topics\/100', + 'nominations_summary': { + 'current': 2, + 'required': 2 + }, + 'ranked': 1, + 'ranked_date': '2021-07-08T19:43:54+00:00', + 'storyboard': true, + 'submitted_date': '2020-12-14T10:48:15+00:00', + 'tags': '', + 'has_favourited': false, + 'beatmaps': [], + 'converts': [], + 'description': { + 'description': '' + }, + 'genre': { + 'id': 5, + 'name': 'Pop' + }, + 'language': { + 'id': 3, + 'name': 'Japanese' + }, + 'ratings': [], + 'recent_favourites': [] + }; - constructor() { - this.id = 100; - this.beatmapset = this.setBeatmapProperties(this.id, "test", PlayMode.Osu, 100, 4); - } + beatmapset: Beatmapset; + id: number; - setBeatmapProperties(id: number, title: string, mode: PlayMode, total_length: number, difficulty_rating: number): Beatmapset { - const set = { ...this.beatmapsetTemplate }; - set.title = title; - set.title_unicode = title; + constructor() { + this.id = 100; + this.beatmapset = this.setBeatmapProperties(this.id, 'test', PlayMode.Osu, 100, 4); + } - const map = { - ...this.beatmapTemplate, - id: id, - url: "https:\/\/osu.ppy.sh\/beatmaps\/" + id, - mode: MODES[mode.id], - mode_int: mode.id, - convert: false, - total_length: total_length, - difficulty_rating: difficulty_rating, - }; + setBeatmapProperties(id: number, title: string, mode: PlayMode, total_length: number, difficulty_rating: number): Beatmapset { + const set = { ...this.beatmapsetTemplate }; + set.title = title; + set.title_unicode = title; - set.beatmaps = [map]; - set.converts = []; + const map = { + ...this.beatmapTemplate, + id: id, + url: 'https:\/\/osu.ppy.sh\/beatmaps\/' + id, + mode: MODES[mode.id], + mode_int: mode.id, + convert: false, + total_length: total_length, + difficulty_rating: difficulty_rating, + }; - if (mode == PlayMode.Osu) { - set.converts.push({ ...map, mode: MODES[1], mode_int: 1, convert: true }); - set.converts.push({ ...map, mode: MODES[2], mode_int: 2, convert: true }); - set.converts.push({ ...map, mode: MODES[3], mode_int: 3, convert: true }); - } + set.beatmaps = [map]; + set.converts = []; - this.id = id; - this.beatmapset = set; - return set; + if (mode == PlayMode.Osu) { + set.converts.push({ ...map, mode: MODES[1], mode_int: 1, convert: true }); + set.converts.push({ ...map, mode: MODES[2], mode_int: 2, convert: true }); + set.converts.push({ ...map, mode: MODES[3], mode_int: 3, convert: true }); } - async getBeatmapset(id: number): Promise { + this.id = id; + this.beatmapset = set; + return set; + } - if (this.id != id) { - throw new FetchBeatmapError(FetchBeatmapErrorReason.NotFound); - } + async getBeatmapset(id: number): Promise { - if (id < 0) { - throw new FetchBeatmapError(FetchBeatmapErrorReason.FormatError); - } + if (this.id != id) { + throw new FetchBeatmapError(FetchBeatmapErrorReason.NotFound); + } - return this.beatmapset; + if (id < 0) { + throw new FetchBeatmapError(FetchBeatmapErrorReason.FormatError); } + + return this.beatmapset; + } } diff --git a/src/libs/ChatLimiter.ts b/src/libs/ChatLimiter.ts index 58b2af8c..5c3e25de 100644 --- a/src/libs/ChatLimiter.ts +++ b/src/libs/ChatLimiter.ts @@ -1,55 +1,55 @@ import { IIrcClient } from '../IIrcClient'; export function applySpeedLimit(ircClient: IIrcClient, tokens: number = 10, periodMs: number = 5000): { dispose: () => void } { - const queue: { target: string, message: string }[] = []; - const waitTime = periodMs / tokens; - let lastChatAt: number = 0; - let timeId: NodeJS.Timeout | undefined; - const originalSay = ircClient.say.bind(ircClient); - - const sayWrapper = (target: string, message: string) => { - message.split(/\r?\n/).filter(l => l.length > 0).forEach(l => queueMessage(target, l)); + const queue: { target: string, message: string }[] = []; + const waitTime = periodMs / tokens; + let lastChatAt: number = 0; + let timeId: NodeJS.Timeout | undefined; + const originalSay = ircClient.say.bind(ircClient); + + const sayWrapper = (target: string, message: string) => { + message.split(/\r?\n/).filter(l => l.length > 0).forEach(l => queueMessage(target, l)); + }; + + const queueMessage = (target: string, message: string) => { + if (timeId != undefined) { + queue.push({ target, message }); + return; } - const queueMessage = (target: string, message: string) => { - if (timeId != undefined) { - queue.push({ target, message }); - return; - } - - if (Date.now() < lastChatAt + waitTime) { - queue.push({ target, message }); - waitAndSay(); - return; - } - - originalSay(target, message); - lastChatAt = Date.now(); + if (Date.now() < lastChatAt + waitTime) { + queue.push({ target, message }); + waitAndSay(); + return; } - const waitAndSay = () => { - if (queue.length == 0) return; - let wt = lastChatAt + waitTime - Date.now(); - if (wt < 0) wt = 0; - timeId = setTimeout(() => { - timeId = undefined; - const task = queue.shift(); - if (task) { - originalSay(task.target, task.message); - lastChatAt = Date.now(); - waitAndSay(); - } - }, wt); + originalSay(target, message); + lastChatAt = Date.now(); + }; + + const waitAndSay = () => { + if (queue.length == 0) return; + let wt = lastChatAt + waitTime - Date.now(); + if (wt < 0) wt = 0; + timeId = setTimeout(() => { + timeId = undefined; + const task = queue.shift(); + if (task) { + originalSay(task.target, task.message); + lastChatAt = Date.now(); + waitAndSay(); + } + }, wt); + }; + + ircClient.say = sayWrapper; + + return { + dispose: () => { + if (timeId) { + clearTimeout(timeId); + } + queue.length = 0; } - - ircClient.say = sayWrapper; - - return { - dispose: () => { - if (timeId) { - clearTimeout(timeId); - } - queue.length = 0; - } - }; + }; } diff --git a/src/libs/OptionValidator.ts b/src/libs/OptionValidator.ts index c2468835..4ef2da2b 100644 --- a/src/libs/OptionValidator.ts +++ b/src/libs/OptionValidator.ts @@ -1,34 +1,34 @@ export const validateOption = { - number: function (name: string, value: any, min?: number, max?: number) { - let v = value; - if (typeof v != "number") { - v = parseFloat(v); - } - if (isNaN(v)) { - throw new Error(`Invalid number option @${name}. ${value} is not a number`); - } - if (min !== undefined && v < min) { - throw new Error(`Invalid number option. @${name} must be at least ${min}`); - } - if (max !== undefined && max < v) { - throw new Error(`Invalid number option. @${name} must be at most ${max}`); - } - return v; - }, - - bool: function (name: string, value: any) { - let v = value; - if (typeof v == "string") { - v = v.toLocaleLowerCase().trim(); - if (v == "false") { - v = false; - } else if (v == "true") { - v = true; - } else { - throw new Error(`${name} (${value}) is not a boolean`); - } - } + number: function (name: string, value: any, min?: number, max?: number) { + let v = value; + if (typeof v != 'number') { + v = parseFloat(v); + } + if (isNaN(v)) { + throw new Error(`Invalid number option @${name}. ${value} is not a number`); + } + if (min !== undefined && v < min) { + throw new Error(`Invalid number option. @${name} must be at least ${min}`); + } + if (max !== undefined && max < v) { + throw new Error(`Invalid number option. @${name} must be at most ${max}`); + } + return v; + }, - return !!v; + bool: function (name: string, value: any) { + let v = value; + if (typeof v == 'string') { + v = v.toLocaleLowerCase().trim(); + if (v == 'false') { + v = false; + } else if (v == 'true') { + v = true; + } else { + throw new Error(`${name} (${value}) is not a boolean`); + } } -} \ No newline at end of file + + return !!v; + } +}; \ No newline at end of file diff --git a/src/libs/TypedEvent.ts b/src/libs/TypedEvent.ts index 053d126a..34dacdfd 100644 --- a/src/libs/TypedEvent.ts +++ b/src/libs/TypedEvent.ts @@ -33,7 +33,7 @@ export class TypedEvent { } off(listener: Listener): void { - var callbackIndex = this.listeners.indexOf(listener); + const callbackIndex = this.listeners.indexOf(listener); if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1); } diff --git a/src/parsers/CommandParser.ts b/src/parsers/CommandParser.ts index df1c8697..9a76fb44 100644 --- a/src/parsers/CommandParser.ts +++ b/src/parsers/CommandParser.ts @@ -4,10 +4,10 @@ export namespace parser { // 1文字目を整数比較してifの評価回数を減らす switch (message.charCodeAt(0)) { case 65: // A - if (message == "Aborted the match") { + if (message == 'Aborted the match') { return makeBanchoResponse(BanchoResponseType.AbortedMatch); } - if (message == "All players are ready") { + if (message == 'All players are ready') { return makeBanchoResponse(BanchoResponseType.AllPlayerReady); } const m_add_ref = message.match(/Added (.+) to the match referees/); @@ -22,16 +22,16 @@ export namespace parser { } break; case 67: // C - if (message == "Changed the match password") { + if (message == 'Changed the match password') { return makeBanchoResponse(BanchoResponseType.PasswordChanged); } - if (message == "Cleared match host") { + if (message == 'Cleared match host') { return makeBanchoResponse(BanchoResponseType.ClearedHost); } - if (message == "Closed the match") { + if (message == 'Closed the match') { return makeBanchoResponse(BanchoResponseType.ClosedMatch); } - if (message == "Countdown aborted") { + if (message == 'Countdown aborted') { return makeBanchoResponse(BanchoResponseType.AbortedStartTimer); } const m_size = message.match(/Changed match to size (\d+)/); @@ -52,23 +52,23 @@ export namespace parser { } break; case 71: // G - if (message == "Good luck, have fun!") { + if (message == 'Good luck, have fun!') { return makeBanchoResponse(BanchoResponseType.FinishStartTimer); } break; case 72: // H - if (message == "Host is changing map...") { + if (message == 'Host is changing map...') { return makeBanchoResponse(BanchoResponseType.BeatmapChanging); } break; case 73: // I - if (message == "Invalid map ID provided") { + if (message == 'Invalid map ID provided') { return makeBanchoResponse(BanchoResponseType.MpInvalidMapId); } - if (message == "Invalid or no settings provided") { + if (message == 'Invalid or no settings provided') { return makeBanchoResponse(BanchoResponseType.MpInvalidSettings); } - if (message == "Invalid or no size provided") { + if (message == 'Invalid or no size provided') { return makeBanchoResponse(BanchoResponseType.MpInvalidSize); } const m_invite = message.match(/Invited (.*) to the room/); @@ -83,15 +83,15 @@ export namespace parser { } break; case 76: // L - if (message == "Locked the match") { + if (message == 'Locked the match') { return makeBanchoResponse(BanchoResponseType.LockedMatch); } break; case 77: // M - if (message == "Match referees:") { + if (message == 'Match referees:') { return makeBanchoResponse(BanchoResponseType.ListRefs); } - if (message.startsWith("Match starts in ")) { + if (message.startsWith('Match starts in ')) { const m_sec = message.match(/(\d+) seconds?/); const m_min = message.match(/(\d+) minutes?/); let secs = 0; @@ -105,12 +105,12 @@ export namespace parser { } break; case 78: // N - if (message == "No user specified") { + if (message == 'No user specified') { return makeBanchoResponse(BanchoResponseType.NoUserSpecified); } break; case 81: // Q - if (message.startsWith("Queued the match to start in ")) { + if (message.startsWith('Queued the match to start in ')) { const m_sec = message.match(/(\d+) seconds?/); const m_min = message.match(/(\d+) minutes?/); let secs = 0; @@ -124,38 +124,38 @@ export namespace parser { } break; case 82: // R - if (message == "Removed the match password") { + if (message == 'Removed the match password') { return makeBanchoResponse(BanchoResponseType.PasswordRemoved); } - const m_rm_ref = message.match(/Removed (.+) from the match referees/) + const m_rm_ref = message.match(/Removed (.+) from the match referees/); if (m_rm_ref) { return makeBanchoResponse(BanchoResponseType.RemovedReferee, m_rm_ref[1]); } break; case 83: // S - if (message == "Started the match") { + if (message == 'Started the match') { return makeBanchoResponse(BanchoResponseType.MpMatchStarted); } break; case 84: //T - if (message == "The match has started!") { + if (message == 'The match has started!') { return makeBanchoResponse(BanchoResponseType.MatchStarted); } - if (message == "The match has already been started") { + if (message == 'The match has already been started') { return makeBanchoResponse(BanchoResponseType.MpMatchAlreadyStarted); } - if (message == "The match has finished!") { + if (message == 'The match has finished!') { return makeBanchoResponse(BanchoResponseType.MatchFinished); } - if (message == "The match is not in progress") { + if (message == 'The match is not in progress') { return makeBanchoResponse(BanchoResponseType.AbortMatchFailed); } break; case 85: // U - if (message == "User not found") { + if (message == 'User not found') { return makeBanchoResponse(BanchoResponseType.UserNotFound); } - if (message == "Unlocked the match") { + if (message == 'Unlocked the match') { return makeBanchoResponse(BanchoResponseType.UnlockedMatch); } break; @@ -163,7 +163,7 @@ export namespace parser { const m_joined = message.match(/^(.+) joined in slot (\d+)( for team (blue|red))?\./); if (m_joined) { - const team = m_joined[4] == undefined ? Teams.None : m_joined[4] == "blue" ? Teams.Blue : Teams.Red + const team = m_joined[4] == undefined ? Teams.None : m_joined[4] == 'blue' ? Teams.Blue : Teams.Red; return makeBanchoResponse(BanchoResponseType.PlayerJoined, m_joined[1], parseInt(m_joined[2]), team); } @@ -185,7 +185,7 @@ export namespace parser { const m_finish = message.match(/^(.+) finished playing \(Score: (\d+), (PASSED|FAILED)\)\./); if (m_finish) { return makeBanchoResponse(BanchoResponseType.PlayerFinished, - m_finish[1], parseInt(m_finish[2]), m_finish[3] == "PASSED"); + m_finish[1], parseInt(m_finish[2]), m_finish[3] == 'PASSED'); } const m_roll = message.match(/^(.+) rolls (\d+) point\(s\)/); @@ -195,7 +195,7 @@ export namespace parser { const m_team_change = message.match(/^(.+) changed to (Blue|Red)/); if (m_team_change) { - return makeBanchoResponse(BanchoResponseType.TeamChanged, m_team_change[1], (m_team_change[2] == "Blue" ? Teams.Blue : Teams.Red)); + return makeBanchoResponse(BanchoResponseType.TeamChanged, m_team_change[1], (m_team_change[2] == 'Blue' ? Teams.Blue : Teams.Red)); } const m_stat = message.match(/^(Stats for \(|Score:\s+\d|Plays:\s+\d|Accuracy:\s+\d)/); @@ -211,7 +211,7 @@ export namespace parser { } export function ParseMpMakeResponse(nick: string, message: string): { id: string, title: string } | null { - if (nick != "BanchoBot") return null; + if (nick != 'BanchoBot') return null; const reg = /Created the tournament match https:\/\/osu.ppy.sh\/mp\/(\d+) (.+)/; const res = message.match(reg); if (res) { @@ -231,23 +231,23 @@ export namespace parser { export function SplitCliCommand(line: string): { command: string, arg: string } { const l = line.match(/^\s*([\!\*]?\w+)\s+(.*)/); if (l == null) { - return { command: line, arg: "" }; + return { command: line, arg: '' }; } else { return { command: l[1], arg: l[2], - } + }; } } export function EnsureMpChannelId(id: string): string { - if (id == null || id == "") return ""; + if (id == null || id == '') return ''; if (id.match(/^#mp_\d+$/)) return id; - if (id.match(/^\d+$/)) return "#mp_" + id; - let m = id.match(/^https:\/\/osu\.ppy\.sh\/mp\/(\d+)$/); + if (id.match(/^\d+$/)) return '#mp_' + id; + const m = id.match(/^https:\/\/osu\.ppy\.sh\/mp\/(\d+)$/); - if (m) return "#mp_" + m[1]; - else return ""; + if (m) return '#mp_' + m[1]; + else return ''; } /** @@ -258,8 +258,8 @@ export namespace parser { */ export function IsChatCommand(message: string) { message = message.trimRight().toLowerCase(); - if (message[0] != "!" && message[0] != "*") return false; - if (message == "!mp") return false; + if (message[0] != '!' && message[0] != '*') return false; + if (message == '!mp') return false; return message.match(/^[\!\*](?!roll|stats?|where|faq|report|request)\w+/) != null; } @@ -267,7 +267,7 @@ export namespace parser { message = message.trimRight(); let m = message.match(/^\!mp\s+(\w+)\s*(.*?)$/); if (m) { - return { command: "!" + m[1].toLowerCase(), param: m[2] }; + return { command: '!' + m[1].toLowerCase(), param: m[2] }; } m = message.match(/^([\!\*]\w+)\s*(.*?)$/); if (m) { diff --git a/src/parsers/MpSettingsParser.ts b/src/parsers/MpSettingsParser.ts index d82a1e97..c7d8bd7a 100644 --- a/src/parsers/MpSettingsParser.ts +++ b/src/parsers/MpSettingsParser.ts @@ -39,15 +39,15 @@ export class MpSettingsParser { name: m[1], id: parseInt(m[3]), history: m[2], - beatmapUrl: "", + beatmapUrl: '', beatmapId: 0, - beatmapTitle: "", - teamMode: "", - winCondition: "", - activeMods: "", + beatmapTitle: '', + teamMode: '', + winCondition: '', + activeMods: '', numPlayers: 0, players: [], - } + }; this.isParsing = true; return true; } @@ -79,19 +79,19 @@ export class MpSettingsParser { } m = line.match(/^Slot (\d+)\s+(.+) https:\/\/osu\.ppy\.sh\/u\/(\d+) (.{15})\s*(\[(.+)\])?$/); if (m) { - let team = m[6] == undefined || !m[6].includes("Team") ? Teams.None - : m[6].includes("Blue") ? Teams.Blue : Teams.Red; + const team = m[6] == undefined || !m[6].includes('Team') ? Teams.None + : m[6].includes('Blue') ? Teams.Blue : Teams.Red; const p: PlayerSettings = { slot: parseInt(m[1]), ready: m[2].trim(), id: parseInt(m[3]), - profile: "https://osu.ppy.sh/u/" + m[3], + profile: 'https://osu.ppy.sh/u/' + m[3], name: m[4].trim(), - isHost: m[6] == undefined ? false : m[6].includes("Host"), + isHost: m[6] == undefined ? false : m[6].includes('Host'), team: team, - options: m[6] == undefined ? "" : m[6].trim() - } + options: m[6] == undefined ? '' : m[6].trim() + }; this.result.players.push(p); this.isParsing = this.result.players.length != this.result.numPlayers; return true; diff --git a/src/parsers/StatParser.ts b/src/parsers/StatParser.ts index 93d7a5bd..a65974bb 100644 --- a/src/parsers/StatParser.ts +++ b/src/parsers/StatParser.ts @@ -20,7 +20,7 @@ export class StatResult { this.date = date; } toString(): string { - return `Stats for (${this.name})[https://osu.ppy.sh/u/${this.id}]${this.status == StatStatuses.None ? "" : " is " + StatStatuses[this.status]}: + return `Stats for (${this.name})[https://osu.ppy.sh/u/${this.id}]${this.status == StatStatuses.None ? '' : ' is ' + StatStatuses[this.status]}: Score: ${this.score} (#${this.rank}) Plays: ${this.plays} (lv${this.level}) Accuracy: ${this.accuracy}%`; @@ -69,7 +69,7 @@ export class StatParser { const line2 = message.match(/Score:\s+([\d,]+)\s+\(#(\d+)\)/); if (line2) { - this.result.score = parseInt(line2[1].replace(/,/g, "")); + this.result.score = parseInt(line2[1].replace(/,/g, '')); this.result.rank = parseInt(line2[2]); return true; } diff --git a/src/plugins/AfkKicker.ts b/src/plugins/AfkKicker.ts index a8f4418c..04c0d3e1 100644 --- a/src/plugins/AfkKicker.ts +++ b/src/plugins/AfkKicker.ts @@ -44,162 +44,162 @@ export interface AfkKickerOption { class PlayerState { - /** + /** * 最後の試合のスコア * 試合開始時に全員0にセットされ、playerfinishedの値がセットされる。 * 全員終了時に0のプレイヤーはafkCount + 1される * マップ未所持のプレイヤーもカウントされる */ - score: number = -1; + score: number = -1; - /** + /** * 試合開始時にロビーにいたかどうか * マップ不所持判定に使用する */ - isPlaying: boolean = false; + isPlaying: boolean = false; - /** + /** * 最後にAFK判定された時間 !statを連続使用された際に上昇数を制限するため */ - timeLastChange: number = 0; + timeLastChange: number = 0; - /** + /** * AFK判定点 */ - afkPoint: number = 0; + afkPoint: number = 0; - constructor() { - this.timeLastChange = Date.now(); - } + constructor() { + this.timeLastChange = Date.now(); + } } export class AfkKicker extends LobbyPlugin { - option: AfkKickerOption; - playerStats: Map; - constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "AfkKicker", "afk"); - this.option = getConfig(this.pluginName, option) as AfkKickerOption; - this.playerStats = new Map(); - this.registerEvents(); + option: AfkKickerOption; + playerStats: Map; + constructor(lobby: Lobby, option: Partial = {}) { + super(lobby, 'AfkKicker', 'afk'); + this.option = getConfig(this.pluginName, option) as AfkKickerOption; + this.playerStats = new Map(); + this.registerEvents(); + } + + private registerEvents(): void { + this.lobby.PlayerJoined.on(({ player }) => { + this.playerStats.set(player, new PlayerState()); + }); + this.lobby.PlayerLeft.on(({ player }) => { + this.playerStats.delete(player); + }); + this.lobby.MatchStarted.on(() => { + for (const stat of this.playerStats.values()) { + stat.isPlaying = true; + stat.score = -1; + } + }); + this.lobby.PlayerFinished.on(({ player, score }) => { + const stat = this.playerStats.get(player); + if (stat) { + stat.score = score; + } + }); + this.lobby.MatchFinished.on(() => { + for (const [player, stat] of this.playerStats.entries()) { + if (stat.isPlaying) { + if (stat.score == -1) { + this.changeAfkPoint(player, stat, POINT_NO_MAP, 'NO_MAP'); + } else if (stat.score == 0) { + this.changeAfkPoint(player, stat, POINT_NO_SCORE, 'NO_SCORE'); + } else { + this.changeAfkPoint(player, stat, POINT_HAS_SCORE, 'HAS_SCORE'); + } + } + stat.isPlaying = false; + stat.score = 0; + } + }); + this.lobby.PlayerChated.on(({ player }) => { + const stat = this.playerStats.get(player); + if (stat) { + this.changeAfkPoint(player, stat, POINT_CHAT, 'CHATED'); + } + }); + this.lobby.ParsedStat.on(({ player, result }) => { + const stat = this.playerStats.get(player); + if (stat && result.status == StatStatuses.Afk) { + this.changeAfkPoint(player, stat, POINT_STAT_AFK, 'AFK_STAT'); + } + }); + this.lobby.ReceivedChatCommand.on(({ player, command, param }) => this.onReceivedChatCommand(player, command, param)); + + } + + changeAfkPoint(player: Player, stat: PlayerState, delta: number, reason: string) { + if (!this.option.enabled) return; + const now = Date.now(); + if (now < stat.timeLastChange + this.option.cooltime_ms) return; + + if (!this.lobby.players.has(player)) { + this.playerStats.delete(player); + return; } - - private registerEvents(): void { - this.lobby.PlayerJoined.on(({ player }) => { - this.playerStats.set(player, new PlayerState()); - }); - this.lobby.PlayerLeft.on(({ player }) => { - this.playerStats.delete(player); - }); - this.lobby.MatchStarted.on(() => { - for (const stat of this.playerStats.values()) { - stat.isPlaying = true; - stat.score = -1; - } - }); - this.lobby.PlayerFinished.on(({ player, score }) => { - const stat = this.playerStats.get(player); - if (stat) { - stat.score = score; - } - }); - this.lobby.MatchFinished.on(() => { - for (const [player, stat] of this.playerStats.entries()) { - if (stat.isPlaying) { - if (stat.score == -1) { - this.changeAfkPoint(player, stat, POINT_NO_MAP, "NO_MAP"); - } else if (stat.score == 0) { - this.changeAfkPoint(player, stat, POINT_NO_SCORE, "NO_SCORE"); - } else { - this.changeAfkPoint(player, stat, POINT_HAS_SCORE, "HAS_SCORE"); - } - } - stat.isPlaying = false; - stat.score = 0; - } - }); - this.lobby.PlayerChated.on(({ player }) => { - const stat = this.playerStats.get(player); - if (stat) { - this.changeAfkPoint(player, stat, POINT_CHAT, "CHATED"); - } - }); - this.lobby.ParsedStat.on(({ player, result }) => { - const stat = this.playerStats.get(player); - if (stat && result.status == StatStatuses.Afk) { - this.changeAfkPoint(player, stat, POINT_STAT_AFK, "AFK_STAT"); - } - }); - this.lobby.ReceivedChatCommand.on(({ player, command, param }) => this.onReceivedChatCommand(player, command, param)); - + stat.timeLastChange = now; + stat.afkPoint += delta; + if (delta > 0) { + this.logger.info(`Detected ${player.escaped_name} is afk. Reason: ${reason}(${(delta > 0 ? '+' : '') + delta}), ${stat.afkPoint} / ${this.option.threshold}`); } - changeAfkPoint(player: Player, stat: PlayerState, delta: number, reason: string) { - if (!this.option.enabled) return; - const now = Date.now(); - if (now < stat.timeLastChange + this.option.cooltime_ms) return; - - if (!this.lobby.players.has(player)) { - this.playerStats.delete(player); - return; - } - stat.timeLastChange = now; - stat.afkPoint += delta; - if (0 < delta) { - this.logger.info(`Detected ${player.escaped_name} is afk. Reason: ${reason}(${(delta > 0 ? "+" : "") + delta}), ${stat.afkPoint} / ${this.option.threshold}`); - } - - if (stat.afkPoint < 0) { - stat.afkPoint = 0; - } else if (this.option.threshold <= stat.afkPoint) { - this.lobby.SendMessage("!mp kick " + player.escaped_name); - this.lobby.SendMessage("bot: kicked afk player."); - this.logger.info("kicked " + player.escaped_name); - } + if (stat.afkPoint < 0) { + stat.afkPoint = 0; + } else if (this.option.threshold <= stat.afkPoint) { + this.lobby.SendMessage('!mp kick ' + player.escaped_name); + this.lobby.SendMessage('bot: kicked afk player.'); + this.logger.info('kicked ' + player.escaped_name); } - - private onReceivedChatCommand(player: Player, command: string, param: string) { - if (!player.isAuthorized) return; - switch (command) { - case "*afkkick_enable": - this.option.enabled = true; - this.logger.info("afkkick enabled"); - break; - case "*afkkick_disable": - this.option.enabled = false; - this.logger.info("afkkick disabled"); - break; - case "*afkkick_threshold": - let th = parseInt(param); - if (Number.isNaN(th)) { - this.logger.warn("invalid *afkkick_threshold param : %s", param); - return; - } - th = Math.max(th, 1); - this.option.threshold = th; - this.logger.info("afkkicker.threshold was set to %s", th); - break; - case "*afkkick_cooltime": - let ct = parseInt(param); - if (Number.isNaN(ct)) { - this.logger.warn("invalid *afkkick_cooltime param : %s", param); - return; - } - ct = Math.max(ct, 10000); - this.option.cooltime_ms = ct; - this.logger.info("afkkicker.cool_time_ms was set to %s", ct); - break; + } + + private onReceivedChatCommand(player: Player, command: string, param: string) { + if (!player.isAuthorized) return; + switch (command) { + case '*afkkick_enable': + this.option.enabled = true; + this.logger.info('afkkick enabled'); + break; + case '*afkkick_disable': + this.option.enabled = false; + this.logger.info('afkkick disabled'); + break; + case '*afkkick_threshold': + let th = parseInt(param); + if (Number.isNaN(th)) { + this.logger.warn('invalid *afkkick_threshold param : %s', param); + return; } - } - - GetPluginStatus(): string { - let points = [...this.playerStats.entries()] - .filter(([player, stat]) => stat.afkPoint > 0) - .map(([player, stat]) => `${player.escaped_name}: ${stat.afkPoint}`).join(","); - if (points) { - points = "\n points: " + points; + th = Math.max(th, 1); + this.option.threshold = th; + this.logger.info('afkkicker.threshold was set to %s', th); + break; + case '*afkkick_cooltime': + let ct = parseInt(param); + if (Number.isNaN(ct)) { + this.logger.warn('invalid *afkkick_cooltime param : %s', param); + return; } - return `-- AFK Kicker -- - status: ${this.option.enabled ? "enabled" : "disabled"}, threshold: ${this.option.threshold}, cooltime: ${this.option.cooltime_ms} (ms)${points}`; + ct = Math.max(ct, 10000); + this.option.cooltime_ms = ct; + this.logger.info('afkkicker.cool_time_ms was set to %s', ct); + break; + } + } + + GetPluginStatus(): string { + let points = [...this.playerStats.entries()] + .filter(([player, stat]) => stat.afkPoint > 0) + .map(([player, stat]) => `${player.escaped_name}: ${stat.afkPoint}`).join(','); + if (points) { + points = '\n points: ' + points; } + return `-- AFK Kicker -- + status: ${this.option.enabled ? 'enabled' : 'disabled'}, threshold: ${this.option.threshold}, cooltime: ${this.option.cooltime_ms} (ms)${points}`; + } } diff --git a/src/plugins/AutoHostSelector.ts b/src/plugins/AutoHostSelector.ts index 084e4411..fb9d3e87 100644 --- a/src/plugins/AutoHostSelector.ts +++ b/src/plugins/AutoHostSelector.ts @@ -14,7 +14,7 @@ export interface AutoHostSelectorOption { deny_list: string[]; } -export type OrderChangeType = "added" | "removed" | "rotated" | "orderd"; +export type OrderChangeType = 'added' | 'removed' | 'rotated' | 'orderd'; /** * 拒否リスト @@ -24,7 +24,7 @@ class DenyList { players = new Set(); playerAdded = new TypedEvent<{ name: string }>(); playerRemoved = new TypedEvent<{ name: string }>(); - logger = log4js.getLogger("DenyList"); + logger = log4js.getLogger('DenyList'); addPlayer(player: Player) { if (this.players.has(player.escaped_name)) { this.logger.info(`${player.name} is already in denylist.`); @@ -64,7 +64,7 @@ export class AutoHostSelector extends LobbyPlugin { eventDisposers: Disposable[] = []; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "AutoHostSelector", "selector"); + super(lobby, 'AutoHostSelector', 'selector'); this.option = getConfig(this.pluginName, option) as AutoHostSelectorOption; if (Array.isArray(this.option.deny_list)) { @@ -86,7 +86,7 @@ export class AutoHostSelector extends LobbyPlugin { this.eventDisposers.push(this.lobby.ReceivedBanchoResponse.on(a => { switch (a.response.type) { case BanchoResponseType.BeatmapChanging: - this.onBeatmapChanging() + this.onBeatmapChanging(); break; case BanchoResponseType.MatchStarted: this.onMatchStarted(); @@ -115,12 +115,12 @@ export class AutoHostSelector extends LobbyPlugin { if (isMpSettingResult) return; this.hostQueue.push(player); - this.logger.trace("added %s", player.name); + this.logger.trace('added %s', player.name); if (this.hostQueue.length == 1) { - this.logger.trace("appoint first player to host"); + this.logger.trace('appoint first player to host'); this.changeHost(); } - this.raiseOrderChanged("added"); + this.raiseOrderChanged('added'); } /** @@ -136,7 +136,7 @@ export class AutoHostSelector extends LobbyPlugin { if (isMpSettingResult) return; if (this.hostQueue.length == 0) return; if (this.lobby.host == null && this.lobby.hostPending == null && !this.lobby.isClearedHost) { // ホストがいない、かつ承認待ちのホストがいない、!mp clearhostが実行されていない - this.logger.info("host has left"); + this.logger.info('host has left'); this.changeHost(); } } @@ -152,11 +152,11 @@ export class AutoHostSelector extends LobbyPlugin { if (this.lobby.isMatching) return; // 試合中は何もしない if (this.hostQueue[0] == newhost) { - this.logger.trace("a new host has been appointed:%s", newhost.name); + this.logger.trace('a new host has been appointed:%s', newhost.name); } else { // ホストがキューの先頭以外に変更された場合 if (this.lobby.hostPending == null) { - this.logger.trace("the host may have manually changed by the previous host"); + this.logger.trace('the host may have manually changed by the previous host'); this.rotateQueue(); } this.changeHost(); @@ -164,7 +164,7 @@ export class AutoHostSelector extends LobbyPlugin { if (this.mapChanger != null && this.mapChanger != newhost) { // 前任のホストがマップを変更している this.needsRotate = false; - this.logger.info("host is appointed after map change"); + this.logger.info('host is appointed after map change'); } } @@ -174,7 +174,7 @@ export class AutoHostSelector extends LobbyPlugin { private onBeatmapChanging(): void { if (this.hostQueue[0] != this.lobby.host) { // アボートで中断後にマップ変更しようとした場合は次のホストに変更 - this.logger.info("host changed map after abort the match"); + this.logger.info('host changed map after abort the match'); this.changeHost(); this.needsRotate = false; } else { @@ -191,7 +191,7 @@ export class AutoHostSelector extends LobbyPlugin { if (this.lobby.hostPending == null && this.needsRotate) { this.rotateQueue(); } else { - this.logger.info("rotation skipped."); + this.logger.info('rotation skipped.'); } } @@ -209,16 +209,16 @@ export class AutoHostSelector extends LobbyPlugin { private onMatchAborted(playersFinished: number, playersInGame: number): void { if (playersFinished != 0) { // 誰か一人でも試合終了している場合は通常の終了処理 - this.logger.trace("The match was aborted after several players were Finished. call normal match finish process"); + this.logger.trace('The match was aborted after several players were Finished. call normal match finish process'); this.onMatchFinished(); } else { if (this.lobby.host != null) { // 誰も終了していない場合は試合再開許可モードへ this.needsRotate = false; - this.logger.trace("The match was aborted before any Player Finished."); + this.logger.trace('The match was aborted before any Player Finished.'); } else { // ホストがいない状態で試合が中断されたら - this.logger.trace("The match was aborted after the host left."); + this.logger.trace('The match was aborted after the host left.'); this.changeHost(); } } @@ -254,31 +254,31 @@ export class AutoHostSelector extends LobbyPlugin { } else { // hostがいない場合は先頭へ this.changeHost(); - this.raiseOrderChanged("orderd"); + this.raiseOrderChanged('orderd'); } // this.lobby.SendMessage("The host queue was rearranged. You can check the current order with !queue command."); } private onChatCommand(player: Player, command: string, param: string): void { - if (command.startsWith("!q")) { + if (command.startsWith('!q')) { this.ShowHostQueue(); } else if (player.isAuthorized) { - if (command == "*reorder" || command == "*order") { - if (param != "") { + if (command == '*reorder' || command == '*order') { + if (param != '') { this.Reorder(param); return; } } - if (command == "*denylist") { - let matAdd = param.match(/^add\s+(.+)/); + if (command == '*denylist') { + const matAdd = param.match(/^add\s+(.+)/); if (matAdd) { - let p = this.lobby.GetOrMakePlayer(matAdd[1]); + const p = this.lobby.GetOrMakePlayer(matAdd[1]); DENY_LIST.addPlayer(p); // 後続処理はイベント経由でonDenylistAddedで実行 } - let matRemove = param.match(/^remove\s+(.+)/); + const matRemove = param.match(/^remove\s+(.+)/); if (matRemove) { - let p = this.lobby.GetOrMakePlayer(matRemove[1]); + const p = this.lobby.GetOrMakePlayer(matRemove[1]); DENY_LIST.removePlayer(p); // 後続処理はイベント経由でonDenylistRemovedで実行 } } @@ -286,7 +286,7 @@ export class AutoHostSelector extends LobbyPlugin { } private onDenylistAdded(name: string) { - let player = this.lobby.GetOrMakePlayer(name); + const player = this.lobby.GetOrMakePlayer(name); if (this.hostQueue.includes(player)) { this.hostQueue = this.hostQueue.filter(p => p != player); this.logger.info(`removed ${player.name} from hostqueue`); @@ -297,7 +297,7 @@ export class AutoHostSelector extends LobbyPlugin { } private onDenylistRemoved(name: string) { - let player = this.lobby.GetOrMakePlayer(name); + const player = this.lobby.GetOrMakePlayer(name); if (this.lobby.players.has(player) && !this.hostQueue.includes(player)) { this.onPlayerJoined(player, player.slot, false); this.logger.info(`added ${player.name} to hostqueue`); @@ -306,22 +306,22 @@ export class AutoHostSelector extends LobbyPlugin { // 別のプラグインからskipの要請があった場合に実行する private onPluginMessage(type: string, args: string[], src: LobbyPlugin | null): void { - if (type == "skip") { + if (type == 'skip') { this.Skip(); - } else if (type == "skipto") { - this.logger.trace("received plugin message skipto"); + } else if (type == 'skipto') { + this.logger.trace('received plugin message skipto'); if (args.length != 1) { - this.logger.error("skipto invalid arguments length"); + this.logger.error('skipto invalid arguments length'); return; } const to = this.lobby.GetOrMakePlayer(args[0]); if (!this.hostQueue.includes(to)) { - this.logger.error("skipto target dosent exist"); + this.logger.error('skipto target dosent exist'); return; } this.SkipTo(to); - } else if (type == "reorder") { - this.logger.trace("received plugin message reorder"); + } else if (type == 'reorder') { + this.logger.trace('received plugin message reorder'); this.Reorder(args[0]); } } @@ -331,19 +331,19 @@ export class AutoHostSelector extends LobbyPlugin { * @param result */ OrderBySlotBase(result: MpSettingsResult): void { - this.logger.info("reordered slot base order."); + this.logger.info('reordered slot base order.'); this.hostQueue = result.players.map(r => this.lobby.GetOrMakePlayer(r.name)).filter(p => !DENY_LIST.includes(p)); } ModifyOderByMpSettingsResult(result: MpSettingsResult, playersIn: Player[], playersOut: Player[], hostChanged: boolean) { // 少人数が出入りしただけとみなし、現在のキューを維持する - let newQueue = this.hostQueue.concat(playersIn).filter(p => !playersOut.includes(p) && !DENY_LIST.includes(p)); + const newQueue = this.hostQueue.concat(playersIn).filter(p => !playersOut.includes(p) && !DENY_LIST.includes(p)); if (this.validateNewQueue(newQueue)) { - this.logger.info("modified host queue."); + this.logger.info('modified host queue.'); this.hostQueue = newQueue; } else { - this.logger.warn("failed to modified the host queue."); + this.logger.warn('failed to modified the host queue.'); this.OrderBySlotBase(result); } } @@ -354,20 +354,20 @@ export class AutoHostSelector extends LobbyPlugin { */ ShowHostQueue(): void { this.lobby.SendMessageWithCoolTime(() => { - let m = this.hostQueue.map(c => disguiseUserName(c.name)).join(", "); + let m = this.hostQueue.map(c => disguiseUserName(c.name)).join(', '); this.logger.trace(m); if (this.option.host_order_chars_limit < m.length) { - m = m.substring(0, this.option.host_order_chars_limit) + "..."; + m = m.substring(0, this.option.host_order_chars_limit) + '...'; } - return "host order : " + m; - }, "!queue", this.option.host_order_cooltime_ms); + return 'host order : ' + m; + }, '!queue', this.option.host_order_cooltime_ms); } /** * 強制ローテーション */ Skip(): void { - this.logger.trace("received plugin message skip"); + this.logger.trace('received plugin message skip'); this.rotateQueue(); this.changeHost(); } @@ -379,7 +379,7 @@ export class AutoHostSelector extends LobbyPlugin { */ SkipTo(to: string | Player): void { let trg: Player; - if (typeof to == "string") { + if (typeof to == 'string') { trg = this.lobby.GetOrMakePlayer(to); } else { trg = to; @@ -395,14 +395,14 @@ export class AutoHostSelector extends LobbyPlugin { while (this.hostQueue[0] != trg) { this.rotateQueue(false); if (c++ > 16) { - this.logger.error("infinity loop detected"); + this.logger.error('infinity loop detected'); return; } } if (this.logger.isTraceEnabled()) { - this.logger.trace("skipto: %s", this.hostQueue.map(p => p.name).join(", ")); + this.logger.trace('skipto: %s', this.hostQueue.map(p => p.name).join(', ')); } - this.raiseOrderChanged("rotated"); + this.raiseOrderChanged('rotated'); this.changeHost(); } @@ -411,40 +411,40 @@ export class AutoHostSelector extends LobbyPlugin { * @param order */ Reorder(order: Player[] | string): void { - if (typeof (order) == "string") { - const players = order.split(",").map(t => this.lobby.GetPlayer(revealUserName(t.trim()))).filter(p => p != null) as Player[]; + if (typeof (order) == 'string') { + const players = order.split(',').map(t => this.lobby.GetPlayer(revealUserName(t.trim()))).filter(p => p != null) as Player[]; if (players.length == 0) { - this.logger.info("Faild reorder, invalid order string : %s", order); + this.logger.info('Faild reorder, invalid order string : %s', order); } else { this.Reorder(players); } } else { const nq = order.filter(p => this.lobby.players.has(p) && !DENY_LIST.includes(p)); - for (let p of this.hostQueue) { + for (const p of this.hostQueue) { if (!nq.includes(p)) { nq.push(p); } } if (this.validateNewQueue(nq)) { - this.logger.info("reordered host queue."); + this.logger.info('reordered host queue.'); this.hostQueue = nq; - this.raiseOrderChanged("orderd"); + this.raiseOrderChanged('orderd'); this.changeHost(); } else { - this.logger.info("failed to reorder."); + this.logger.info('failed to reorder.'); } } } private validateNewQueue(que: Player[]): boolean { let isValid = true; - for (let p of que) { + for (const p of que) { isValid = isValid && this.lobby.players.has(p) && !DENY_LIST.includes(p); } - this.logger.trace("validate queue."); - this.logger.trace(" old: %s", Array.from(this.lobby.players).map(p => p.name).join(", ")); - this.logger.trace(" new: %s", que.map(p => p.name).join(", ")); + this.logger.trace('validate queue.'); + this.logger.trace(' old: %s', Array.from(this.lobby.players).map(p => p.name).join(', ')); + this.logger.trace(' new: %s', que.map(p => p.name).join(', ')); return isValid; } @@ -459,15 +459,15 @@ export class AutoHostSelector extends LobbyPlugin { private changeHost(): void { if (this.hostQueue.length == 0) { if (this.lobby.host != null) { - this.lobby.SendMessage("!mp clearhost"); + this.lobby.SendMessage('!mp clearhost'); } return; } if (this.hostQueue[0] != this.lobby.host) { this.lobby.TransferHost(this.hostQueue[0]); - this.logger.trace("sent !mp host %s", this.hostQueue[0].name); + this.logger.trace('sent !mp host %s', this.hostQueue[0].name); } else { - this.logger.trace("%s is already host", this.hostQueue[0].name); + this.logger.trace('%s is already host', this.hostQueue[0].name); } } @@ -478,9 +478,9 @@ export class AutoHostSelector extends LobbyPlugin { const current = this.hostQueue.shift() as Player; this.hostQueue.push(current); if (this.logger.isTraceEnabled() && showLog) { - this.logger.trace("rotated host queue: %s", this.hostQueue.map(p => p.name).join(", ")); + this.logger.trace('rotated host queue: %s', this.hostQueue.map(p => p.name).join(', ')); } - this.raiseOrderChanged("rotated"); + this.raiseOrderChanged('rotated'); } /** @@ -491,8 +491,8 @@ export class AutoHostSelector extends LobbyPlugin { const i = this.hostQueue.indexOf(player); if (i != -1) { this.hostQueue.splice(i, 1); - this.logger.trace("removed %s", player.name); - this.raiseOrderChanged("removed"); + this.logger.trace('removed %s', player.name); + this.raiseOrderChanged('removed'); return true; } else { return false; @@ -504,11 +504,11 @@ export class AutoHostSelector extends LobbyPlugin { } GetPluginStatus(): string { - const m = this.hostQueue.map(p => p.name).join(", "); - const b = this.getDeniedPlayerNames().join(","); + const m = this.hostQueue.map(p => p.name).join(', '); + const b = this.getDeniedPlayerNames().join(','); return `-- AutoHostSelector -- queue : ${m} - mapChanger : ${this.mapChanger == null ? "null" : this.mapChanger.name}, needsRotate : ${this.needsRotate} + mapChanger : ${this.mapChanger == null ? 'null' : this.mapChanger.name}, needsRotate : ${this.needsRotate} denyList : ${b}`; } diff --git a/src/plugins/AutoStartTimer.ts b/src/plugins/AutoStartTimer.ts index 49cb5967..5232a567 100644 --- a/src/plugins/AutoStartTimer.ts +++ b/src/plugins/AutoStartTimer.ts @@ -17,7 +17,7 @@ export class AutoStartTimer extends LobbyPlugin { lastMapId: number; useMapValidation: boolean = false; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "AutoStartTimer", "autostart"); + super(lobby, 'AutoStartTimer', 'autostart'); this.option = getConfig(this.pluginName, option) as AutoStartTimerOption; this.lastMapId = 0; this.registerEvents(); @@ -33,16 +33,16 @@ export class AutoStartTimer extends LobbyPlugin { if (this.lobby.isMatching) return; if (!player.isAuthorized) return; switch (command) { - case "*autostart_enable": + case '*autostart_enable': this.option.enabled = true; break; - case "*autostart_disable": + case '*autostart_disable': this.option.enabled = false; break; - case "*autostart_time": + case '*autostart_time': let ct = parseInt(param); if (Number.isNaN(ct)) { - this.logger.warn("invalid *autostart_time param : %s", param); + this.logger.warn('invalid *autostart_time param : %s', param); return; } if (ct < WAITINGTIME_MIN) { @@ -50,10 +50,10 @@ export class AutoStartTimer extends LobbyPlugin { } this.option.waitingTime = ct; break; - case "*autostart_clearhost_enable": + case '*autostart_clearhost_enable': this.option.doClearHost = true; break; - case "*atuostart_clearhost_disable": + case '*atuostart_clearhost_disable': this.option.doClearHost = false; break; } @@ -70,9 +70,9 @@ export class AutoStartTimer extends LobbyPlugin { case BanchoResponseType.BeatmapChanging: case BanchoResponseType.HostChanged: if (this.lobby.isStartTimerActive) { - this.lobby.SendMessage("!mp aborttimer"); + this.lobby.SendMessage('!mp aborttimer'); } - this.SendPluginMessage("mp_abort_start"); + this.SendPluginMessage('mp_abort_start'); break; case BanchoResponseType.MatchStarted: this.lastMapId = this.lobby.mapId; @@ -82,21 +82,21 @@ export class AutoStartTimer extends LobbyPlugin { private startTimer() { if (!this.option.enabled || this.option.waitingTime < WAITINGTIME_MIN) return; - this.SendPluginMessage("mp_start", [this.option.waitingTime.toString(), "withhelp"]); + this.SendPluginMessage('mp_start', [this.option.waitingTime.toString(), 'withhelp']); if (this.option.doClearHost) { - this.lobby.SendMessage(`!mp clearhost`); + this.lobby.SendMessage('!mp clearhost'); } } private onPluginMessage(type: string, args: string[], src: LobbyPlugin | null): void { switch (type) { - case "enabledMapChecker": + case 'enabledMapChecker': this.useMapValidation = true; break; - case "disabledMapChecker": + case 'disabledMapChecker': this.useMapValidation = false; break; - case "validatedMap": + case 'validatedMap': this.startTimer(); break; } diff --git a/src/plugins/CacheCleaner.ts b/src/plugins/CacheCleaner.ts index a544235b..a30ffc27 100644 --- a/src/plugins/CacheCleaner.ts +++ b/src/plugins/CacheCleaner.ts @@ -16,85 +16,85 @@ export interface CacheCleanerOption { } export class CacheCleaner extends LobbyPlugin { - option: CacheCleanerOption; - cleanedAt: number; - lastHeapSize: number; - cleaning: boolean; + option: CacheCleanerOption; + cleanedAt: number; + lastHeapSize: number; + cleaning: boolean; - constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "CacheCleaner", "cleaner"); - this.option = getConfig(this.pluginName, option) as CacheCleanerOption; - this.cleanedAt = Date.now(); - this.lastHeapSize = process.memoryUsage().heapUsed; - this.cleaning = false; - this.registerEvents(); - } + constructor(lobby: Lobby, option: Partial = {}) { + super(lobby, 'CacheCleaner', 'cleaner'); + this.option = getConfig(this.pluginName, option) as CacheCleanerOption; + this.cleanedAt = Date.now(); + this.lastHeapSize = process.memoryUsage().heapUsed; + this.cleaning = false; + this.registerEvents(); + } - private registerEvents(): void { + private registerEvents(): void { - this.lobby.MatchStarted.on(() => { - if (this.option.enabled && (this.cleanedAt + this.option.intervalMs < Date.now())) { - setTimeout(() => { - this.clearCache(); - }, 5000); - } - }); + this.lobby.MatchStarted.on(() => { + if (this.option.enabled && (this.cleanedAt + this.option.intervalMs < Date.now())) { + setTimeout(() => { + this.clearCache(); + }, 5000); + } + }); - this.lobby.ReceivedChatCommand.on(({ player, command, param }) => this.onReceivedChatCommand(player, command, param)); - } + this.lobby.ReceivedChatCommand.on(({ player, command, param }) => this.onReceivedChatCommand(player, command, param)); + } - private onReceivedChatCommand(player: Player, command: string, param: string) { - if (!player.isAuthorized) return; - switch (command.toLocaleLowerCase()) { - case "*clearcache_enable": - this.option.enabled = true; - this.logger.info("CacheCleaner enabled"); - break; - case "*clearcache_disable": - this.option.enabled = false; - this.logger.info("CacheCleaner disabled"); - break; - case "*clearcache": - case "*clear": - this.clearCache(); - break; - } + private onReceivedChatCommand(player: Player, command: string, param: string) { + if (!player.isAuthorized) return; + switch (command.toLocaleLowerCase()) { + case '*clearcache_enable': + this.option.enabled = true; + this.logger.info('CacheCleaner enabled'); + break; + case '*clearcache_disable': + this.option.enabled = false; + this.logger.info('CacheCleaner disabled'); + break; + case '*clearcache': + case '*clear': + this.clearCache(); + break; } + } - private async clearCache() { - try { - await this.lobby.historyRepository.clearCache(); - BeatmapRepository.discardExpiredCache(this.option.intervalMs); - ProfileRepository.discardExpiredCache(this.option.intervalMs); - if (global.gc) { - global.gc(); - } - const currentMem = process.memoryUsage().heapUsed; - this.logger.info(`heap size: ${this.formatByte(this.lastHeapSize)} -> ${this.formatByte(currentMem)}`); - this.lastHeapSize = currentMem; - this.cleanedAt = Date.now(); - } catch (e) { - this.logger.error(e); - } + private async clearCache() { + try { + await this.lobby.historyRepository.clearCache(); + BeatmapRepository.discardExpiredCache(this.option.intervalMs); + ProfileRepository.discardExpiredCache(this.option.intervalMs); + if (global.gc) { + global.gc(); + } + const currentMem = process.memoryUsage().heapUsed; + this.logger.info(`heap size: ${this.formatByte(this.lastHeapSize)} -> ${this.formatByte(currentMem)}`); + this.lastHeapSize = currentMem; + this.cleanedAt = Date.now(); + } catch (e) { + this.logger.error(e); } + } - private formatByte(numByte: number): string { - if (isNaN(numByte)) return "NaN"; - if (!isFinite(numByte)) return numByte > 0 ? "∞" : "-∞"; - const notations = ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", "Ri", "Qi"]; - const sign = 0 <= numByte ? "" : "-"; - numByte = Math.abs(numByte); - let idx = 0; - while (1024 <= numByte) { - numByte /= 1024; - idx++; - } - const valueStr = numByte.toFixed(3).slice(0, 5); - if (notations.length <= idx) { - return `${sign}${valueStr}*2^${idx * 10}B`; - } else { - return `${sign}${valueStr}${notations[idx]}B`; - } + private formatByte(numByte: number): string { + if (isNaN(numByte)) return 'NaN'; + if (!isFinite(numByte)) return numByte > 0 ? '∞' : '-∞'; + const notations = ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi', 'Ri', 'Qi']; + const sign = numByte >= 0 ? '' : '-'; + numByte = Math.abs(numByte); + let idx = 0; + while (numByte >= 1024) { + numByte /= 1024; + idx++; + } + const valueStr = numByte.toFixed(3).slice(0, 5); + if (notations.length <= idx) { + return `${sign}${valueStr}*2^${idx * 10}B`; + } else { + return `${sign}${valueStr}${notations[idx]}B`; } + } } diff --git a/src/plugins/HistoryLoader.ts b/src/plugins/HistoryLoader.ts index 8dd4d689..c07d3998 100644 --- a/src/plugins/HistoryLoader.ts +++ b/src/plugins/HistoryLoader.ts @@ -19,7 +19,7 @@ export class HistoryLoader extends LobbyPlugin { fetchInvervalId: NodeJS.Timeout | null = null; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "HistoryLoader", "history"); + super(lobby, 'HistoryLoader', 'history'); this.option = getConfig(this.pluginName, option) as HistoryLoaderOption; this.repository = lobby.historyRepository; this.registerEvents(); @@ -34,8 +34,8 @@ export class HistoryLoader extends LobbyPlugin { async onFixedSettings(result: MpSettingsResult, playersIn: Player[], playersOut: Player[], hostChanged: boolean): Promise { if (!this.repository) return; - let order = (await this.repository.calcCurrentOrderAsName()).join(","); - this.SendPluginMessage("reorder", [order]); + const order = (await this.repository.calcCurrentOrderAsName()).join(','); + this.SendPluginMessage('reorder', [order]); } onJoinedLobby(channel: string): any { @@ -54,7 +54,7 @@ export class HistoryLoader extends LobbyPlugin { } onGotUserProfile(user: User): any { - let p = this.lobby.GetOrMakePlayer(user.username); + const p = this.lobby.GetOrMakePlayer(user.username); p.id = user.id; } @@ -66,7 +66,7 @@ export class HistoryLoader extends LobbyPlugin { startFetch(): void { this.stopFetch(); if (this.option.fetch_interval_ms >= 5000) { - this.logger.trace("start fetching"); + this.logger.trace('start fetching'); this.fetchInvervalId = setInterval(() => { if (!this.lobby.isMatching) { this.repository.updateToLatest(); @@ -77,13 +77,13 @@ export class HistoryLoader extends LobbyPlugin { stopFetch(): void { if (this.fetchInvervalId) { - this.logger.trace("stop fetching"); + this.logger.trace('stop fetching'); clearInterval(this.fetchInvervalId); this.fetchInvervalId = null; } } GetPluginStatus(): string { - return `-- HistoryLoader -- hasError : ${this.repository?.hasError}, latest : ${this.repository?.latestEventId} loaded events : ${this.repository?.events.length}` + return `-- HistoryLoader -- hasError : ${this.repository?.hasError}, latest : ${this.repository?.latestEventId} loaded events : ${this.repository?.events.length}`; } } diff --git a/src/plugins/HostSkipper.ts b/src/plugins/HostSkipper.ts index 118841b2..4f0fc64c 100644 --- a/src/plugins/HostSkipper.ts +++ b/src/plugins/HostSkipper.ts @@ -35,7 +35,7 @@ export class HostSkipper extends LobbyPlugin { } constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "HostSkipper", "skipper"); + super(lobby, 'HostSkipper', 'skipper'); this.option = getConfig(this.pluginName, option) as HostSkipperOption; this.voting = new VoteCounter(this.option.vote_rate, this.option.vote_min); this.registerEvents(); @@ -105,14 +105,14 @@ export class HostSkipper extends LobbyPlugin { private onParsedStat(player: Player, result: StatResult, isPm: boolean): void { if (!isPm && this.lobby.host == player && this.statIsAfk(result.status) && !this.lobby.isMatching) { - this.logger.trace("passed afk check %s -> %s", result.name, StatStatuses[result.status]); + this.logger.trace('passed afk check %s -> %s', result.name, StatStatuses[result.status]); if (this.option.afk_check_do_skip) { this.Skip(); } else { if (this.isMapChanged) { - this.lobby.SendMessage("bot : players can start the match by !start vote."); + this.lobby.SendMessage('bot : players can start the match by !start vote.'); } else { - this.lobby.SendMessage("bot : players can skip afk host by !skip vote."); + this.lobby.SendMessage('bot : players can skip afk host by !skip vote.'); } } } @@ -122,13 +122,13 @@ export class HostSkipper extends LobbyPlugin { private onChatCommand(player: Player, command: string, param: string): void { if (this.lobby.isMatching) return; - if (command == "!skip") { - if (param != "" && this.lobby.host != null && escapeUserName(param) != this.lobby.host.escaped_name) return; // 関係ないユーザーのスキップは無視 + if (command == '!skip') { + if (param != '' && this.lobby.host != null && escapeUserName(param) != this.lobby.host.escaped_name) return; // 関係ないユーザーのスキップは無視 this.vote(player); } else if (player.isAuthorized) { - if (command == "*skip") { + if (command == '*skip') { this.Skip(); - } else if (command == "*skipto" && param != "") { + } else if (command == '*skipto' && param != '') { this.SkipTo(param); } } @@ -136,22 +136,22 @@ export class HostSkipper extends LobbyPlugin { private vote(player: Player): void { if (this.voting.passed) { - this.logger.debug("vote from %s was ignored, already skipped", player.name); + this.logger.debug('vote from %s was ignored, already skipped', player.name); } else if (this.elapsedSinceHostChanged < this.option.vote_cooltime_ms) { - this.logger.debug("vote from %s was ignored, at cool time.", player.name); + this.logger.debug('vote from %s was ignored, at cool time.', player.name); if (player.isHost) { const secs = (this.option.vote_cooltime_ms - this.elapsedSinceHostChanged) / 1000; this.lobby.SendMessage(`skip command is in cooltime. you have to wait ${secs.toFixed(2)} sec(s).`); } } else if (player.isHost) { - this.logger.debug("host(%s) sent !skip command", player.name); + this.logger.debug('host(%s) sent !skip command', player.name); this.Skip(); } else { if (this.voting.Vote(player)) { - this.logger.trace("accept skip request from %s", player.name); + this.logger.trace('accept skip request from %s', player.name); this.checkSkipCount(true); } else { - this.logger.debug("vote from %s was ignored, double vote", player.name); + this.logger.debug('vote from %s was ignored, double vote', player.name); } } } @@ -159,29 +159,29 @@ export class HostSkipper extends LobbyPlugin { // スキップ状況を確認して、必要数に達している場合は private checkSkipCount(showMessage: boolean = false): void { if (this.voting.count != 0 && showMessage) { - this.lobby.DeferMessage(`bot : Host skip progress: ${this.voting.toString()}`, "checkSkipCount", this.option.vote_msg_defer_ms, false); + this.lobby.DeferMessage(`bot : Host skip progress: ${this.voting.toString()}`, 'checkSkipCount', this.option.vote_msg_defer_ms, false); } if (this.voting.passed) { - this.lobby.DeferMessage(`bot : Passed skip vote: ${this.voting.toString()}`, "checkSkipCount", 100, true); + this.lobby.DeferMessage(`bot : Passed skip vote: ${this.voting.toString()}`, 'checkSkipCount', 100, true); this.Skip(); } } Skip(): void { - this.logger.info("do skip"); + this.logger.info('do skip'); this.StopTimer(); - this.SendPluginMessage("skip"); + this.SendPluginMessage('skip'); this.timeHostChanged = Date.now(); } SkipTo(username: string): void { if (!this.lobby.Includes(username)) { - this.logger.info("invalid username @skipto : %s", username); + this.logger.info('invalid username @skipto : %s', username); return; } - this.logger.info("do skipTo : %s", username); + this.logger.info('do skipTo : %s', username); this.StopTimer(); - this.SendPluginMessage("skipto", [username]); + this.SendPluginMessage('skipto', [username]); } Reset(): void { @@ -193,19 +193,19 @@ export class HostSkipper extends LobbyPlugin { StartTimer(isFirst: boolean): void { if (this.option.afk_check_interval_ms == 0 || this.lobby.host == null || this.lobby.status != LobbyStatus.Entered || this.lobby.isMatching) return; this.StopTimer(); - this.logger.trace("start afk check timer"); + this.logger.trace('start afk check timer'); const target = this.lobby.host; this.afkTimer = setTimeout(async () => { if (!this.lobby.isMatching && this.lobby.host == target) { try { const stat1 = await this.lobby.RequestStatAsync(target, true, this.option.afk_check_timeout_ms); - this.logger.trace("stat check phase 1 %s -> %s", stat1.name, StatStatuses[stat1.status]); + this.logger.trace('stat check phase 1 %s -> %s', stat1.name, StatStatuses[stat1.status]); if (this.afkTimer != undefined && this.lobby.host == target && this.statIsAfk(stat1.status)) { // double check and show stat for players await this.lobby.RequestStatAsync(target, false, this.option.afk_check_timeout_ms); } } catch { - this.logger.warn("stat check timeout!"); + this.logger.warn('stat check timeout!'); } // StopTimerが呼び出されていない、かつホストがターゲットと同じならタイマー再開 if (this.afkTimer != undefined && this.lobby.host == target) { @@ -217,7 +217,7 @@ export class HostSkipper extends LobbyPlugin { StopTimer(): void { if (this.afkTimer != undefined) { - this.logger.trace("stop timer"); + this.logger.trace('stop timer'); clearTimeout(this.afkTimer); this.afkTimer = undefined; } @@ -228,6 +228,6 @@ export class HostSkipper extends LobbyPlugin { } GetPluginStatus(): string { - return `-- Host Skipper -- timer : ${this.afkTimer != undefined ? "active" : "###"}, skip_vote : ${this.voting.toString()}`; + return `-- Host Skipper -- timer : ${this.afkTimer != undefined ? 'active' : '###'}, skip_vote : ${this.voting.toString()}`; } } diff --git a/src/plugins/InOutLogger.ts b/src/plugins/InOutLogger.ts index dfde933a..a32c56da 100644 --- a/src/plugins/InOutLogger.ts +++ b/src/plugins/InOutLogger.ts @@ -8,7 +8,7 @@ export class InOutLogger extends LobbyPlugin { withColorTag: boolean = true; constructor(lobby: Lobby) { - super(lobby, "InOutLogger", "inout"); + super(lobby, 'InOutLogger', 'inout'); this.lobby.ReceivedBanchoResponse.on(a => this.onReceivedBanchoResponse(a.message, a.response)); } @@ -33,19 +33,19 @@ export class InOutLogger extends LobbyPlugin { GetInOutLog(useColor: boolean): string { const arr = this.GetInOutPlayers(); const msgOut = arr.out.map(p => { - let num = this.players.get(p) || 0; + const num = this.players.get(p) || 0; return `${p.name}(${num})`; - }).join(", "); - const msgIn = arr.in.map(p => p.name).join(", "); - let msg = ""; - const ctagIn = useColor ? "\x1b[32m" : ""; - const ctagOut = useColor ? "\x1b[31m" : ""; - const ctagEnd = useColor ? "\x1b[0m" : ""; - if (msgIn != "") { + }).join(', '); + const msgIn = arr.in.map(p => p.name).join(', '); + let msg = ''; + const ctagIn = useColor ? '\x1b[32m' : ''; + const ctagOut = useColor ? '\x1b[31m' : ''; + const ctagEnd = useColor ? '\x1b[0m' : ''; + if (msgIn != '') { msg = `+${ctagIn} ${msgIn} ${ctagEnd}`; } - if (msgOut != "") { - if (msg != "") msg += ", " + if (msgOut != '') { + if (msg != '') msg += ', '; msg += `-${ctagOut} ${msgOut} ${ctagEnd}`; } return msg; @@ -54,20 +54,20 @@ export class InOutLogger extends LobbyPlugin { LogInOutPlayers(): void { if (this.logger.isInfoEnabled()) { const msg = this.GetInOutLog(this.withColorTag); - if (msg != "") { + if (msg != '') { this.logger.info(msg); } } } private saveCurrentPlayers(): void { - for (let p of this.lobby.players) { - let num = this.players.get(p); + for (const p of this.lobby.players) { + const num = this.players.get(p); if (num === undefined) { this.players.set(p, 0); } } - for (let p of this.players.keys()) { + for (const p of this.players.keys()) { if (!this.lobby.players.has(p)) { this.players.delete(p); } @@ -75,8 +75,8 @@ export class InOutLogger extends LobbyPlugin { } private countUp(): void { - for (let p of this.players.keys()) { - let num = this.players.get(p); + for (const p of this.players.keys()) { + const num = this.players.get(p); if (num !== undefined) { this.players.set(p, num + 1); } @@ -85,9 +85,9 @@ export class InOutLogger extends LobbyPlugin { GetPluginStatus(): string { const m = Array.from(this.players.keys()).map(p => { - let num = this.players.get(p) || 0; + const num = this.players.get(p) || 0; return `${p.name}(${num})`; - }).join(", "); + }).join(', '); return `-- InOut -- players: ${m}`; } diff --git a/src/plugins/LobbyKeeper.ts b/src/plugins/LobbyKeeper.ts index 0f6b96c1..ada45a0d 100644 --- a/src/plugins/LobbyKeeper.ts +++ b/src/plugins/LobbyKeeper.ts @@ -38,12 +38,12 @@ export interface LobbyKeeperOption { } const OPTION_TYPE_HINTS: ConfigTypeHint[] = [ - { key: "mode", nullable: true, type: "string" }, - { key: "size", nullable: true, type: "number" }, - { key: "password", nullable: true, type: "string" }, - { key: "mods", nullable: true, type: "string" }, - { key: "hostkick_tolerance", nullable: false, type: "number" }, - { key: "title", nullable: true, type: "string" }, + { key: 'mode', nullable: true, type: 'string' }, + { key: 'size', nullable: true, type: 'number' }, + { key: 'password', nullable: true, type: 'string' }, + { key: 'mods', nullable: true, type: 'string' }, + { key: 'hostkick_tolerance', nullable: false, type: 'number' }, + { key: 'title', nullable: true, type: 'string' }, ]; export class LobbyKeeper extends LobbyPlugin { @@ -53,7 +53,7 @@ export class LobbyKeeper extends LobbyPlugin { slotKeeper: SlotKeeper; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "LobbyKeeper", "keeper"); + super(lobby, 'LobbyKeeper', 'keeper'); this.option = getConfig(this.pluginName, option, OPTION_TYPE_HINTS) as LobbyKeeperOption; this.kickedUsers = new Set(); this.mpKickedUsers = new Set(); @@ -63,7 +63,7 @@ export class LobbyKeeper extends LobbyPlugin { } private registerEvents(): void { - this.lobby.JoinedLobby.on(a => this.onJoined()) + this.lobby.JoinedLobby.on(a => this.onJoined()); this.lobby.HostChanged.on(a => this.onHostChanged(a.player)); this.lobby.MatchFinished.on(() => this.onMatchFinished()); this.lobby.ReceivedChatCommand.on(a => this.onChatCommand(a.player, a.command, a.param)); @@ -83,22 +83,22 @@ export class LobbyKeeper extends LobbyPlugin { } private setModeOption(mode: any) { - if (mode == null || mode == "null" || mode == "") { + if (mode == null || mode == 'null' || mode == '') { this.option.mode = null; return; } - if (typeof mode == "string") { + if (typeof mode == 'string') { const r = this.tryParseModeParams(mode); if (r) { this.option.mode = r; return; } else { - throw new Error("Invalid Option. LobbyKeeper.mode : " + mode); + throw new Error('Invalid Option. LobbyKeeper.mode : ' + mode); } } - if ("team" in mode && "score" in mode) { + if ('team' in mode && 'score' in mode) { if ((mode.team instanceof TeamMode) && (mode.score instanceof ScoreMode)) { this.option.mode = mode; } else { @@ -110,34 +110,34 @@ export class LobbyKeeper extends LobbyPlugin { return; } - throw new Error("Invalid Option. LobbyKeeper.mode : " + mode); + throw new Error('Invalid Option. LobbyKeeper.mode : ' + mode); } private setSizeOption(size: any) { - if (size == null || size == "null" || size == "") { + if (size == null || size == 'null' || size == '') { size = 0; } - if (typeof size == "string") { + if (typeof size == 'string') { size = parseInt(size); } - if (typeof size != "number") { - throw new Error("invalid size " + size); + if (typeof size != 'number') { + throw new Error('invalid size ' + size); } - if (size < 0 || 16 < size || isNaN(size)) { - throw new Error("invalid size " + size); + if (size < 0 || size > 16 || isNaN(size)) { + throw new Error('invalid size ' + size); } this.option.size = size; this.slotKeeper.size = size; } private setModsOption(mods: any) { - if (mods == null || mods == "null") { + if (mods == null || mods == 'null') { this.option.mods = null; return; } - if (typeof mods == "string") { + if (typeof mods == 'string') { this.option.mods = Mod.parseMods(mods); return; } @@ -146,7 +146,7 @@ export class LobbyKeeper extends LobbyPlugin { this.option.mods = Mod.removeInvalidCombinations(mods); return; } - throw new Error("Invalid Option. LobbyKeeper.mods : " + mods); + throw new Error('Invalid Option. LobbyKeeper.mods : ' + mods); } private tryParseModeParams(param: string) { @@ -178,7 +178,7 @@ export class LobbyKeeper extends LobbyPlugin { return { team: this.option.mode?.team ?? TeamMode.HeadToHead, score }; } catch { } - throw new Error("Invalid Option. LobbyKeeper.mode : " + param); + throw new Error('Invalid Option. LobbyKeeper.mode : ' + param); } private checkMode(teamMode: TeamMode, scoreMode: ScoreMode) { @@ -240,7 +240,7 @@ export class LobbyKeeper extends LobbyPlugin { private fixMods(): void { if (this.option.mods != null) { - this.lobby.SendMessage(`!mp mods ${this.option.mods.map(m => m.value).join(" ")}`) + this.lobby.SendMessage(`!mp mods ${this.option.mods.map(m => m.value).join(' ')}`); } } @@ -269,7 +269,7 @@ export class LobbyKeeper extends LobbyPlugin { } } catch (e: any) { - this.logger.error("@LobbyKeeper#onParsedSettings " + e?.message); + this.logger.error('@LobbyKeeper#onParsedSettings ' + e?.message); } } @@ -314,7 +314,7 @@ export class LobbyKeeper extends LobbyPlugin { private onChatCommand(player: Player, command: string, param: string): void { if (player.isAuthorized) { - if (command.startsWith("*keep") || command.startsWith("*no")) { + if (command.startsWith('*keep') || command.startsWith('*no')) { const msg = this.processCommand(command, param); if (msg != null) { this.lobby.SendMessage(msg); @@ -331,7 +331,7 @@ export class LobbyKeeper extends LobbyPlugin { } if (this.option.title != null || this.option.mode != null || this.option.mods != null) { this.lobby.LoadMpSettingsAsync().catch((e: any) => { - this.logger.error("lobbyKeeper#onMatchFinished failed to LoadMpSettingsAsync"); + this.logger.error('lobbyKeeper#onMatchFinished failed to LoadMpSettingsAsync'); }); } } @@ -341,11 +341,11 @@ export class LobbyKeeper extends LobbyPlugin { } private processCommand(command: string, param: string): string | null { - if (command == "*keep") { + if (command == '*keep') { const matchMode = /^mode(\s+(.+))?\s*$/.exec(param); if (matchMode) { if (matchMode[2] == undefined) { - this.logger.warn("missing parameters. *keep mode [0-3] [0-3] e.g. *keep mode 0 0"); + this.logger.warn('missing parameters. *keep mode [0-3] [0-3] e.g. *keep mode 0 0'); return null; } try { @@ -354,10 +354,10 @@ export class LobbyKeeper extends LobbyPlugin { this.fixLobbyModeAndSize(); return `Keep lobby mode ${this.option.mode.team.name}, ${this.option.mode.score.name}`; } else { - return `Disabled keeping lobby mode`; + return 'Disabled keeping lobby mode'; } } catch (e: any) { - this.logger.warn(e?.message ?? "failed to parse mode params"); + this.logger.warn(e?.message ?? 'failed to parse mode params'); return null; } } @@ -365,7 +365,7 @@ export class LobbyKeeper extends LobbyPlugin { const matchSize = /^size(\s+(\d+))?\s*$/.exec(param); if (matchSize) { if (matchSize[2] == undefined) { - this.logger.warn("missing parameter. *keep size [1-16]"); + this.logger.warn('missing parameter. *keep size [1-16]'); return null; } try { @@ -374,11 +374,11 @@ export class LobbyKeeper extends LobbyPlugin { this.fixLobbyModeAndSize(); return `Keep lobby size ${this.option.size}`; } else { - return `Disabled keeping lobby size.`; + return 'Disabled keeping lobby size.'; } } catch (e: any) { - this.logger.warn(e?.message ?? "failed to parse size params"); + this.logger.warn(e?.message ?? 'failed to parse size params'); return null; } } @@ -386,68 +386,68 @@ export class LobbyKeeper extends LobbyPlugin { const matchMods = /^mods?(\s+(.+))?\s*$/.exec(param); if (matchMods) { if (matchMods[2] == undefined) { - this.logger.warn("missing parameters. *keep mods [mod] ([mod]) ([mod]) ..."); + this.logger.warn('missing parameters. *keep mods [mod] ([mod]) ([mod]) ...'); return null; } try { this.setModsOption(matchMods[2]); if (this.option.mods) { this.fixMods(); - return `Keep mods ${this.option.mods == null || this.option.mods.length == 0 ? "None" : this.option.mods.map(m => m.name).join(", ")}`; + return `Keep mods ${this.option.mods == null || this.option.mods.length == 0 ? 'None' : this.option.mods.map(m => m.name).join(', ')}`; } else { - return `Disabled keeping lobby mods.`; + return 'Disabled keeping lobby mods.'; } } catch (e: any) { - this.logger.warn(e?.message ?? "failed to parse mods"); + this.logger.warn(e?.message ?? 'failed to parse mods'); return null; } } const matchPassword = /^password(\s+(.+))?\s*$/.exec(param); if (matchPassword) { - this.option.password = matchPassword[2] !== undefined ? matchPassword[2] : ""; + this.option.password = matchPassword[2] !== undefined ? matchPassword[2] : ''; this.fixPassword(); - return `Keep lobby password ${this.option.password != "" ? this.option.password : "[empty]"}`; + return `Keep lobby password ${this.option.password != '' ? this.option.password : '[empty]'}`; } const matchTitle = /^(title|name)(\s+(.+))?\s*$/.exec(param); if (matchTitle) { - this.option.title = matchTitle[3] !== undefined ? matchTitle[3] : ""; + this.option.title = matchTitle[3] !== undefined ? matchTitle[3] : ''; this.fixTitle(); - return `Keep lobby title ${this.option.title !== "" ? this.option.title : "[empty]"}`; + return `Keep lobby title ${this.option.title !== '' ? this.option.title : '[empty]'}`; } - this.logger.warn("missing parameters. *keep ...params"); + this.logger.warn('missing parameters. *keep ...params'); } - if (command == "*no") { - if (param == "keep mode" && this.option.mode != null) { + if (command == '*no') { + if (param == 'keep mode' && this.option.mode != null) { this.setModeOption(null); - return "disabled keeping teammode and scoremode"; + return 'disabled keeping teammode and scoremode'; } - if (param == "keep size" && this.option.size != 0) { + if (param == 'keep size' && this.option.size != 0) { this.setSizeOption(0); - return "disabled keeping lobby size"; + return 'disabled keeping lobby size'; } - if ((param == "keep mod" || param == "keep mods") && this.option.mods != null) { + if ((param == 'keep mod' || param == 'keep mods') && this.option.mods != null) { this.setModsOption(null); - return "disabled keeping mods"; + return 'disabled keeping mods'; } - if (param == "keep password" && this.option.password != null) { - if (this.option.password != "") { - this.option.password = ""; + if (param == 'keep password' && this.option.password != null) { + if (this.option.password != '') { + this.option.password = ''; this.fixPassword(); } this.option.password = null; - return "disabled keeping lobby password"; + return 'disabled keeping lobby password'; } - if ((param == "keep title" || param == "keep name") && this.option.title != null) { + if ((param == 'keep title' || param == 'keep name') && this.option.title != null) { this.option.title = null; - return "disabled keeping room title"; + return 'disabled keeping room title'; } - if (param.startsWith("keep")) { - this.logger.warn("missing parameters. *no keep "); + if (param.startsWith('keep')) { + this.logger.warn('missing parameters. *no keep '); } } @@ -464,23 +464,23 @@ export class LobbyKeeper extends LobbyPlugin { } if (this.option.password) { - keeps.push(`password: ${this.option.password != "" ? this.option.password : "(empty)"}`); + keeps.push(`password: ${this.option.password != '' ? this.option.password : '(empty)'}`); } if (this.option.mods) { - keeps.push(`mods: ${this.option.mods.map(m => m.value).join(" ")}`); + keeps.push(`mods: ${this.option.mods.map(m => m.value).join(' ')}`); } if (this.option.title) { keeps.push(`title: ${this.option.title}`); } - return keeps.join(", "); + return keeps.join(', '); } GetPluginStatus(): string { return `-- Lobby Keeper -- - ${this.getDescription()}` + ${this.getDescription()}`; } } diff --git a/src/plugins/LobbyPlugin.ts b/src/plugins/LobbyPlugin.ts index 632963d0..993c90d8 100644 --- a/src/plugins/LobbyPlugin.ts +++ b/src/plugins/LobbyPlugin.ts @@ -10,12 +10,12 @@ export class LobbyPlugin { logger: log4js.Logger; pluginName: string; - constructor(lobby: Lobby, pluginName: string, loggerTag: string = "default") { + constructor(lobby: Lobby, pluginName: string, loggerTag: string = 'default') { this.lobby = lobby; this.lobby.plugins.push(this); this.pluginName = pluginName; this.logger = log4js.getLogger(loggerTag); - this.logger.addContext("channel", "lobby"); + this.logger.addContext('channel', 'lobby'); } /** @@ -32,7 +32,7 @@ export class LobbyPlugin { * プラグインごとのステータスメッセージを取得する */ GetPluginStatus(): string { - return ""; + return ''; } /** @@ -55,8 +55,8 @@ export class LobbyPlugin { } export function regSwitch(val: string, cases: { case: RegExp, action: (m: RegExpExecArray) => void }[]) { - for (let c of cases) { - let ea = c.case.exec(val); + for (const c of cases) { + const ea = c.case.exec(val); if (ea) { c.action(ea); return; diff --git a/src/plugins/LobbyTerminator.ts b/src/plugins/LobbyTerminator.ts index 570f6969..53101d13 100644 --- a/src/plugins/LobbyTerminator.ts +++ b/src/plugins/LobbyTerminator.ts @@ -13,7 +13,7 @@ export class LobbyTerminator extends LobbyPlugin { multilimeMessageInterval: number = 1000; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "LobbyTerminator", "terminator"); + super(lobby, 'LobbyTerminator', 'terminator'); this.option = getConfig(this.pluginName, option) as LobbyTerminatorOption; this.registerEvents(); } @@ -32,7 +32,7 @@ export class LobbyTerminator extends LobbyPlugin { if (this.terminateTimer) { clearTimeout(this.terminateTimer); this.terminateTimer = undefined; - this.logger.trace("terminate_timer canceled"); + this.logger.trace('terminate_timer canceled'); } } @@ -41,9 +41,9 @@ export class LobbyTerminator extends LobbyPlugin { if (this.terminateTimer) { clearTimeout(this.terminateTimer); } - this.logger.trace("terminate_timer start") + this.logger.trace('terminate_timer start'); this.terminateTimer = setTimeout(() => { - this.logger.info("terminated lobby"); + this.logger.info('terminated lobby'); this.lobby.CloseLobbyAsync(); }, this.option.terminate_time_ms); } @@ -52,23 +52,23 @@ export class LobbyTerminator extends LobbyPlugin { CloseLobby(time_ms: number = 0): void { if (time_ms == 0) { if (this.lobby.players.size == 0) { - this.logger.info("terminated lobby"); + this.logger.info('terminated lobby'); this.lobby.CloseLobbyAsync(); } else { this.lobby.SendMultilineMessageWithInterval([ - "!mp password closed", - "This lobby will be closed after everyone leaves.", - "Thank you for playing with the auto host rotation lobby." - ], this.multilimeMessageInterval, "close lobby announcement", 100000); + '!mp password closed', + 'This lobby will be closed after everyone leaves.', + 'Thank you for playing with the auto host rotation lobby.' + ], this.multilimeMessageInterval, 'close lobby announcement', 100000); this.option.terminate_time_ms = 1000; } } else { this.lobby.SendMultilineMessageWithInterval([ - "!mp password closed", + '!mp password closed', `This lobby will be closed in ${(time_ms / 1000).toFixed(0)}sec(s).`, - "Thank you for playing with the auto host rotation lobby." - ], this.multilimeMessageInterval, "close lobby announcement", 100000) - .then(() => this.sendMessageWithDelay("!mp close", time_ms)); + 'Thank you for playing with the auto host rotation lobby.' + ], this.multilimeMessageInterval, 'close lobby announcement', 100000) + .then(() => this.sendMessageWithDelay('!mp close', time_ms)); } } diff --git a/src/plugins/MapChecker.ts b/src/plugins/MapChecker.ts index 6184a73b..1bf4a2a6 100644 --- a/src/plugins/MapChecker.ts +++ b/src/plugins/MapChecker.ts @@ -32,7 +32,7 @@ export class MapChecker extends LobbyPlugin { validator: MapValidator; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "MapChecker", "mapChecker"); + super(lobby, 'MapChecker', 'mapChecker'); const d = getConfig(this.pluginName, option) as MapCheckerUncheckedOption; validateMapCheckerOption(d); this.option = d as MapCheckerOption; @@ -67,7 +67,7 @@ export class MapChecker extends LobbyPlugin { private onJoinedLobby(): void { if (this.option.enabled) { - this.SendPluginMessage("enabledMapChecker"); + this.SendPluginMessage('enabledMapChecker'); } } @@ -86,8 +86,8 @@ export class MapChecker extends LobbyPlugin { } private onReceivedChatCommand(command: string, param: string, player: Player): void { - if (command == "!r" || command == "!regulation") { - this.lobby.SendMessageWithCoolTime(this.getRegulationDescription(), "regulation", 10000); + if (command == '!r' || command == '!regulation') { + this.lobby.SendMessageWithCoolTime(this.getRegulationDescription(), 'regulation', 10000); return; } @@ -106,33 +106,33 @@ export class MapChecker extends LobbyPlugin { } if (p.num_violations_allowed !== undefined) { this.option.num_violations_allowed = p.num_violations_allowed; - this.logger.info("num_violations_allowed was set to " + p.num_violations_allowed); + this.logger.info('num_violations_allowed was set to ' + p.num_violations_allowed); } let changed = false; if (p.star_min !== undefined) { this.option.star_min = p.star_min; - if (this.option.star_max <= this.option.star_min && 0 < this.option.star_max) { + if (this.option.star_max <= this.option.star_min && this.option.star_max > 0) { this.option.star_max = 0; } changed = true; } if (p.star_max !== undefined) { this.option.star_max = p.star_max; - if (this.option.star_max <= this.option.star_min && 0 < this.option.star_max) { + if (this.option.star_max <= this.option.star_min && this.option.star_max > 0) { this.option.star_min = 0; } changed = true; } if (p.length_min !== undefined) { this.option.length_min = p.length_min; - if (this.option.length_max <= this.option.length_min && 0 < this.option.length_max) { + if (this.option.length_max <= this.option.length_min && this.option.length_max > 0) { this.option.length_max = 0; } changed = true; } if (p.length_max !== undefined) { this.option.length_max = p.length_max; - if (this.option.length_max <= this.option.length_min && 0 < this.option.length_max) { + if (this.option.length_max <= this.option.length_min && this.option.length_max > 0) { this.option.length_min = 0; } changed = true; @@ -148,7 +148,7 @@ export class MapChecker extends LobbyPlugin { } if (changed) { - const m = "New regulation: " + this.validator.GetDescription(); + const m = 'New regulation: ' + this.validator.GetDescription(); this.lobby.SendMessage(m); this.logger.info(m); } @@ -161,7 +161,7 @@ export class MapChecker extends LobbyPlugin { if (this.option.enabled) { return this.validator.GetDescription(); } else { - return "Disabled (" + this.validator.GetDescription() + ")"; + return 'Disabled (' + this.validator.GetDescription() + ')'; } } @@ -169,13 +169,13 @@ export class MapChecker extends LobbyPlugin { if (v == this.option.enabled) return; if (v) { - this.SendPluginMessage("enabledMapChecker"); - this.lobby.SendMessage("mapChecker Enabled"); - this.logger.info("mapChecker Enabled"); + this.SendPluginMessage('enabledMapChecker'); + this.lobby.SendMessage('mapChecker Enabled'); + this.logger.info('mapChecker Enabled'); } else { - this.SendPluginMessage("disabledMapChecker"); - this.lobby.SendMessage("mapChecker Disabled"); - this.logger.info("mapChecker Disabled"); + this.SendPluginMessage('disabledMapChecker'); + this.lobby.SendMessage('mapChecker Disabled'); + this.logger.info('mapChecker Disabled'); } this.option.enabled = v; } @@ -196,7 +196,7 @@ export class MapChecker extends LobbyPlugin { } const r = this.validator.RateBeatmap(map); - if (0 < r.rate) { + if (r.rate > 0) { this.rejectMap(r.message, true); } else { this.acceptMap(map); @@ -227,10 +227,10 @@ export class MapChecker extends LobbyPlugin { } private skipHost(): void { - let msg = `The number of violations has reached ${this.option.num_violations_allowed}. Skipped ${this.lobby.host?.escaped_name}`; + const msg = `The number of violations has reached ${this.option.num_violations_allowed}. Skipped ${this.lobby.host?.escaped_name}`; this.logger.info(msg); this.lobby.SendMessage(msg); - this.SendPluginMessage("skip"); + this.SendPluginMessage('skip'); } private rejectMap(reason: string, showRegulation: boolean): void { @@ -240,7 +240,7 @@ export class MapChecker extends LobbyPlugin { if (showRegulation) { this.lobby.SendMessage(`!mp map ${this.lastMapId} ${this.option.gamemode.value} | Current Regulation: ${this.validator.GetDescription()}`); this.lobby.SendMessage(reason); - this.lobby.SendMessage("*Attention! Difficulty will not be calculated correctly if a global mod is applied."); + this.lobby.SendMessage('*Attention! Difficulty will not be calculated correctly if a global mod is applied.'); } else { this.lobby.SendMessage(`!mp map ${this.lastMapId} ${this.option.gamemode.value} | ${reason}`); } @@ -253,7 +253,7 @@ export class MapChecker extends LobbyPlugin { } private acceptMap(map: BeatmapCache): void { - this.SendPluginMessage("validatedMap"); + this.SendPluginMessage('validatedMap'); this.lastMapId = this.lobby.mapId; if (map.beatmapset) { const desc = this.getMapDescription(map, map.beatmapset); @@ -279,9 +279,9 @@ export class MapChecker extends LobbyPlugin { } export function secToTimeNotation(sec: number): string { - let m = Math.floor(sec / 60); - let s = Math.round(sec - m * 60); - return `${m}:${s.toString().padStart(2, "0")}`; + const m = Math.floor(sec / 60); + const s = Math.round(sec - m * 60); + return `${m}:${s.toString().padStart(2, '0')}`; } export class MapValidator { @@ -296,7 +296,7 @@ export class MapValidator { RateBeatmap(map: Beatmap): { rate: number, message: string } { let rate = 0; - let violationMsgs = []; + const violationMsgs = []; const mapmode = PlayMode.from(map.mode); if (mapmode != this.option.gamemode && this.option.gamemode != null) { @@ -304,114 +304,114 @@ export class MapValidator { rate += 1; } - if (0 < this.option.star_min && map.difficulty_rating < this.option.star_min) { + if (this.option.star_min > 0 && map.difficulty_rating < this.option.star_min) { rate += parseFloat((this.option.star_min - map.difficulty_rating).toFixed(2)); - violationMsgs.push("map star rating is lower than allowed star rating."); + violationMsgs.push('map star rating is lower than allowed star rating.'); } - if (0 < this.option.star_max && this.option.star_max < map.difficulty_rating) { + if (this.option.star_max > 0 && this.option.star_max < map.difficulty_rating) { rate += parseFloat((map.difficulty_rating - this.option.star_max).toFixed(2)); - violationMsgs.push("map star rating is higher than allowed star rating."); + violationMsgs.push('map star rating is higher than allowed star rating.'); } - if (0 < this.option.length_min && map.total_length < this.option.length_min) { + if (this.option.length_min > 0 && map.total_length < this.option.length_min) { rate += (this.option.length_min - map.total_length) / 60.0; - violationMsgs.push("map duration is shorter than allowed duration."); + violationMsgs.push('map duration is shorter than allowed duration.'); } - if (0 < this.option.length_max && this.option.length_max < map.total_length) { + if (this.option.length_max > 0 && this.option.length_max < map.total_length) { rate += (map.total_length - this.option.length_max) / 60.0; - violationMsgs.push("map duration is longer than allowed duration."); + violationMsgs.push('map duration is longer than allowed duration.'); } - if (0 < rate) { + if (rate > 0) { let message; - const mapDesc = `[${map.url} ${map.beatmapset?.title}] (Star Rating: ${map.difficulty_rating} Duration: ${secToTimeNotation(map.total_length)})` + const mapDesc = `[${map.url} ${map.beatmapset?.title}] (Star Rating: ${map.difficulty_rating} Duration: ${secToTimeNotation(map.total_length)})`; if (violationMsgs.length == 1) { message = `${mapDesc} was rejected because ${violationMsgs[0]}`; } else { - message = `${mapDesc} was rejected because of following reason:\n${violationMsgs.map(m => "- " + m).join("\n")}`; + message = `${mapDesc} was rejected because of following reason:\n${violationMsgs.map(m => '- ' + m).join('\n')}`; } - return { rate, message } + return { rate, message }; } else { - return { rate: 0, message: "" }; + return { rate: 0, message: '' }; } } GetDescription(): string { - let d_star = ""; - let d_length = ""; + let d_star = ''; + let d_length = ''; let d_gamemode = `mode: ${this.option.gamemode.officialName}`; if (this.option.gamemode != PlayMode.Osu) { if (this.option.allow_convert) { - d_gamemode += " (converts allowed)"; + d_gamemode += ' (converts allowed)'; } else { - d_gamemode += " (converts disallowed)"; + d_gamemode += ' (converts disallowed)'; } } - if (0 < this.option.star_min && 0 < this.option.star_max) { + if (this.option.star_min > 0 && this.option.star_max > 0) { d_star = `${this.option.star_min.toFixed(2)} <= difficulty <= ${this.option.star_max.toFixed(2)}`; - } else if (0 < this.option.star_min) { + } else if (this.option.star_min > 0) { d_star = `${this.option.star_min.toFixed(2)} <= difficulty`; - } else if (0 < this.option.star_max) { + } else if (this.option.star_max > 0) { d_star = `difficulty <= ${this.option.star_max.toFixed(2)}`; } - if (0 < this.option.length_min && 0 < this.option.length_max) { + if (this.option.length_min > 0 && this.option.length_max > 0) { d_length = `${secToTimeNotation(this.option.length_min)} <= length <= ${secToTimeNotation(this.option.length_max)}`; - } else if (0 < this.option.length_min) { + } else if (this.option.length_min > 0) { d_length = `${secToTimeNotation(this.option.length_min)} <= length`; - } else if (0 < this.option.length_max) { + } else if (this.option.length_max > 0) { d_length = `length <= ${secToTimeNotation(this.option.length_max)}`; } - return [d_star, d_length, d_gamemode].filter(d => d != "").join(", "); + return [d_star, d_length, d_gamemode].filter(d => d != '').join(', '); } } function validateMapCheckerOption(option: MapCheckerUncheckedOption): option is Partial { if (option.enabled !== undefined) { - option.enabled = validateOption.bool("MapChecker.enabled", option.enabled); + option.enabled = validateOption.bool('MapChecker.enabled', option.enabled); } if (option.star_min !== undefined) { - option.star_min = validateOption.number("MapChecker.star_min", option.star_min, 0); + option.star_min = validateOption.number('MapChecker.star_min', option.star_min, 0); } if (option.star_max !== undefined) { - option.star_max = validateOption.number("MapChecker.star_max", option.star_max, 0); + option.star_max = validateOption.number('MapChecker.star_max', option.star_max, 0); } if (option.length_min !== undefined) { - option.length_min = validateOption.number("MapChecker.length_min", option.length_min, 0); + option.length_min = validateOption.number('MapChecker.length_min', option.length_min, 0); } if (option.length_max !== undefined) { - option.length_max = validateOption.number("MapChecker.length_max", option.length_max, 0); + option.length_max = validateOption.number('MapChecker.length_max', option.length_max, 0); } - if (option.star_max !== undefined && option.star_min !== undefined && option.star_max <= option.star_min && 0 < option.star_max) { + if (option.star_max !== undefined && option.star_min !== undefined && option.star_max <= option.star_min && option.star_max > 0) { option.star_min = 0; } - if (option.length_max !== undefined && option.length_min !== undefined && option.length_max <= option.length_min && 0 < option.length_max) { + if (option.length_max !== undefined && option.length_min !== undefined && option.length_max <= option.length_min && option.length_max > 0) { option.length_min = 0; } if (option.gamemode !== undefined) { - if (typeof option.gamemode == "string") { + if (typeof option.gamemode == 'string') { try { option.gamemode = PlayMode.from(option.gamemode, true); } catch { - throw new Error("option MapChecker#gamemode must be [osu | fruits | taiko | mania]."); + throw new Error('option MapChecker#gamemode must be [osu | fruits | taiko | mania].'); } } if (!(option.gamemode instanceof PlayMode)) { - throw new Error("option MapChecker#gamemode must be [osu | fruits | taiko | mania]."); + throw new Error('option MapChecker#gamemode must be [osu | fruits | taiko | mania].'); } } @@ -419,14 +419,14 @@ function validateMapCheckerOption(option: MapCheckerUncheckedOption): option is option.num_violations_allowed = option.num_violations_to_skip; } if (option.num_violations_allowed !== undefined) { - option.num_violations_allowed = validateOption.number("MapChecker.num_violations_allowed", option.num_violations_allowed, 0); + option.num_violations_allowed = validateOption.number('MapChecker.num_violations_allowed', option.num_violations_allowed, 0); } if (option.allowConvert !== undefined) { option.allow_convert = option.allowConvert; } if (option.allow_convert !== undefined) { - option.allow_convert = validateOption.bool("MapChecker.allow_convert", option.allow_convert); + option.allow_convert = validateOption.bool('MapChecker.allow_convert', option.allow_convert); } return true; } @@ -438,24 +438,24 @@ function validateMapCheckerOption(option: MapCheckerUncheckedOption): option is export function parseMapcheckerOwnerCommand(command: string, param: string): Partial | undefined { let option: undefined | MapCheckerUncheckedOption = undefined; command = command.toLocaleLowerCase(); - if (command == "*mapchecker_enable") { + if (command == '*mapchecker_enable') { return { enabled: true }; } - if (command == "*mapchecker_disable") { + if (command == '*mapchecker_disable') { option = { enabled: false }; } - if (command.startsWith("*regulation")) { - if (param.indexOf("=") != -1) { + if (command.startsWith('*regulation')) { + if (param.indexOf('=') != -1) { option = parseRegulationSetter(param); } else { - const params = param.split(/\s+/).map(s => s.toLowerCase()).filter(s => s != ""); + const params = param.split(/\s+/).map(s => s.toLowerCase()).filter(s => s != ''); option = parseRegulationCommand(params); } } - if (command == "*no" && param.startsWith("regulation")) { - const params = param.split(/\s+/).map(s => s.toLowerCase()).filter(s => s != ""); + if (command == '*no' && param.startsWith('regulation')) { + const params = param.split(/\s+/).map(s => s.toLowerCase()).filter(s => s != ''); if (params.length == 1) { option = { enabled: false }; } else { @@ -470,61 +470,61 @@ export function parseMapcheckerOwnerCommand(command: string, param: string): Par function parseRegulationCommand(params: string[]): MapCheckerUncheckedOption { switch (unifyParamName(params[0])) { - case "enabled": + case 'enabled': return { enabled: true }; - case "disabled": + case 'disabled': return { enabled: false }; - case "num_violations_allowed": - if (params.length < 2) throw new Error("missing parameter. *regulation num_violations_allowed [number]"); + case 'num_violations_allowed': + if (params.length < 2) throw new Error('missing parameter. *regulation num_violations_allowed [number]'); return { num_violations_allowed: params[1] }; - case "star_min": - if (params.length < 2) throw new Error("missing parameter. *regulation star_min [number]"); + case 'star_min': + if (params.length < 2) throw new Error('missing parameter. *regulation star_min [number]'); return { star_min: params[1] }; - case "star_max": - if (params.length < 2) throw new Error("missing parameter. *regulation star_max [number]"); + case 'star_max': + if (params.length < 2) throw new Error('missing parameter. *regulation star_max [number]'); return { star_max: params[1] }; - case "length_min": - if (params.length < 2) throw new Error("missing parameter. *regulation length_min [number]"); + case 'length_min': + if (params.length < 2) throw new Error('missing parameter. *regulation length_min [number]'); return { length_min: params[1] }; - case "length_max": - if (params.length < 2) throw new Error("missing parameter. *regulation length_max [number]"); + case 'length_max': + if (params.length < 2) throw new Error('missing parameter. *regulation length_max [number]'); return { length_max: params[1] }; - case "gamemode": - if (params.length < 2) throw new Error("missing parameter. *regulation gamemode [osu | fruits | taiko | mania]"); + case 'gamemode': + if (params.length < 2) throw new Error('missing parameter. *regulation gamemode [osu | fruits | taiko | mania]'); return { gamemode: params[1] }; - case "allow_convert": + case 'allow_convert': if (params.length < 2) { return { allow_convert: true }; } else { return { allow_convert: params[1] }; } - case "disallow_convert": + case 'disallow_convert': return { allow_convert: false }; } - throw new Error("missing parameter. *regulation [enable | disable | star_min | star_max | length_min | length_max | gamemode | num_violations_allowed] <...params>"); + throw new Error('missing parameter. *regulation [enable | disable | star_min | star_max | length_min | length_max | gamemode | num_violations_allowed] <...params>'); } function parseNoRegulationCommand(param: string): MapCheckerUncheckedOption | undefined { switch (unifyParamName(param)) { - case "num_violations_allowed": + case 'num_violations_allowed': return { num_violations_allowed: 0 }; - case "star_min": + case 'star_min': return { star_min: 0 }; - case "star_max": + case 'star_max': return { star_max: 0 }; - case "length_min": + case 'length_min': return { length_min: 0 }; - case "length_max": + case 'length_max': return { length_max: 0 }; - case "gamemode": + case 'gamemode': return { gamemode: PlayMode.Osu, allow_convert: true }; - case "allow_convert": + case 'allow_convert': return { allow_convert: false }; } } function parseRegulationSetter(param: string): MapCheckerUncheckedOption { - let result: { [key: string]: string } = {}; + const result: { [key: string]: string } = {}; for (const m of param.matchAll(/([0-9a-zA-Z_\-]+)\s*=\s*([^\s,]+)/g)) { const name = unifyParamName(m[1]); const value = m[2]; @@ -536,28 +536,28 @@ function parseRegulationSetter(param: string): MapCheckerUncheckedOption { function unifyParamName(name: string): string { name = name.toLowerCase(); - if (name.includes("star") || name.includes("diff")) { - if (name.includes("low") || name.includes("min")) { - return "star_min"; - } else if (name.includes("up") || name.includes("max")) { - return "star_max" + if (name.includes('star') || name.includes('diff')) { + if (name.includes('low') || name.includes('min')) { + return 'star_min'; + } else if (name.includes('up') || name.includes('max')) { + return 'star_max'; } - } else if (name.includes("len")) { - if (name.includes("low") || name.includes("min")) { - return "length_min" - } else if (name.includes("up") || name.includes("max")) { - return "length_max" + } else if (name.includes('len')) { + if (name.includes('low') || name.includes('min')) { + return 'length_min'; + } else if (name.includes('up') || name.includes('max')) { + return 'length_max'; } - } else if (name.startsWith("enable")) { - return "enabled"; - } else if (name.startsWith("disable")) { - return "disabled"; - } else if (name == "num_violations_to_skip" || name.includes("violations")) { - return "num_violations_allowed"; - } else if (name == "allowconvert") { - return "allow_convert"; - } else if (name == "disallowconvert") { - return "disallow_convert"; + } else if (name.startsWith('enable')) { + return 'enabled'; + } else if (name.startsWith('disable')) { + return 'disabled'; + } else if (name == 'num_violations_to_skip' || name.includes('violations')) { + return 'num_violations_allowed'; + } else if (name == 'allowconvert') { + return 'allow_convert'; + } else if (name == 'disallowconvert') { + return 'disallow_convert'; } return name; } diff --git a/src/plugins/MapRecaster.ts b/src/plugins/MapRecaster.ts index 4240b7da..ac8d4de1 100644 --- a/src/plugins/MapRecaster.ts +++ b/src/plugins/MapRecaster.ts @@ -15,13 +15,13 @@ export class MapRecaster extends LobbyPlugin { option: MapRecasterOption; canRecast: boolean = true; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "MapRecaster", "recaster"); + super(lobby, 'MapRecaster', 'recaster'); this.option = getConfig(this.pluginName, option) as MapRecasterOption; this.registerEvents(); } private registerEvents(): void { - this.lobby.ReceivedChatCommand.on(a => this.onReceivedChatCommand(a.command, a.param, a.player)) + this.lobby.ReceivedChatCommand.on(a => this.onReceivedChatCommand(a.command, a.param, a.player)); this.lobby.ReceivedBanchoResponse.on(a => { if (a.response.type == BanchoResponseType.BeatmapChanged) { this.canRecast = true; @@ -30,10 +30,10 @@ export class MapRecaster extends LobbyPlugin { } private onReceivedChatCommand(command: string, param: string, player: Player): void { - if (command == "!update") { + if (command == '!update') { if (this.canRecast) { this.canRecast = false; - this.lobby.SendMessage("!mp map " + this.lobby.mapId); + this.lobby.SendMessage('!mp map ' + this.lobby.mapId); } } } diff --git a/src/plugins/MatchAborter.ts b/src/plugins/MatchAborter.ts index bfc57a3a..f7e02e8a 100644 --- a/src/plugins/MatchAborter.ts +++ b/src/plugins/MatchAborter.ts @@ -24,7 +24,7 @@ export class MatchAborter extends LobbyPlugin { voting: VoteCounter; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "MatchAborter", "aborter"); + super(lobby, 'MatchAborter', 'aborter'); this.option = getConfig(this.pluginName, option) as MatchAborterOption; this.voting = new VoteCounter(this.option.vote_rate, this.option.vote_min); this.registerEvents(); @@ -57,7 +57,7 @@ export class MatchAborter extends LobbyPlugin { private onMatchStarted(): void { this.voting.RemoveAllVoters(); - for (let p of this.lobby.players) { + for (const p of this.lobby.players) { this.voting.AddVoter(p); } } @@ -72,15 +72,15 @@ export class MatchAborter extends LobbyPlugin { private onChatCommand(player: Player, command: string, param: string): void { if (!this.lobby.isMatching) return; - if (command == "!abort") { + if (command == '!abort') { if (player == this.lobby.host) { - this.logger.trace("host(%s) sent !abort command", player.name); + this.logger.trace('host(%s) sent !abort command', player.name); this.doAbort(); } else { this.vote(player); } } else if (player.isAuthorized) { - if (command == "*abort") { + if (command == '*abort') { this.doAbort(); } } @@ -89,20 +89,20 @@ export class MatchAborter extends LobbyPlugin { private vote(player: Player): void { if (this.voting.passed) return; if (this.voting.Vote(player)) { - this.logger.trace("accept abort request from %s (%s)", player.name, this.voting.toString()); + this.logger.trace('accept abort request from %s (%s)', player.name, this.voting.toString()); this.checkVoteCount(true); } else { - this.logger.trace("vote from %s was ignored", player.name); + this.logger.trace('vote from %s was ignored', player.name); } } // 投票数を確認して必要数に達していたら試合中断 private checkVoteCount(showMessage: boolean = false): void { if (this.voting.count != 0 && showMessage) { - this.lobby.DeferMessage(`bot : match abort progress: ${this.voting.toString()}`, "aborter vote", this.option.vote_msg_defer_ms, false); + this.lobby.DeferMessage(`bot : match abort progress: ${this.voting.toString()}`, 'aborter vote', this.option.vote_msg_defer_ms, false); } if (this.voting.passed) { - this.lobby.DeferMessage(`bot : passed abort vote: ${this.voting.toString()}`, "aborter vote", 100, true); + this.lobby.DeferMessage(`bot : passed abort vote: ${this.voting.toString()}`, 'aborter vote', 100, true); this.doAbort(); } } @@ -128,7 +128,7 @@ export class MatchAborter extends LobbyPlugin { } private doAbort(): void { - this.logger.info("do abort"); + this.logger.info('do abort'); this.stopTimer(); this.lobby.AbortMatch(); } @@ -136,10 +136,10 @@ export class MatchAborter extends LobbyPlugin { private startTimer(): void { if (this.option.auto_abort_delay_ms == 0) return; this.stopTimer(); - this.logger.trace("start timer"); + this.logger.trace('start timer'); this.abortTimer = setTimeout(() => { if (this.abortTimer != null && this.lobby.isMatching) { - this.logger.trace("abort timer action"); + this.logger.trace('abort timer action'); this.doAutoAbortAsync(); } }, this.option.auto_abort_delay_ms); @@ -147,7 +147,7 @@ export class MatchAborter extends LobbyPlugin { private async doAutoAbortAsync(): Promise { const playersStillPlaying = Array.from(this.lobby.players).filter(v => v.mpstatus == MpStatuses.Playing); - for (let p of playersStillPlaying) { + for (const p of playersStillPlaying) { if (p.mpstatus == MpStatuses.Playing) { try { const stat = await this.lobby.RequestStatAsync(p, true); @@ -156,7 +156,7 @@ export class MatchAborter extends LobbyPlugin { return; } } catch { - this.logger.warn("couldn't get players status. AutoAbortCheck was canceled."); + this.logger.warn('couldn\'t get players status. AutoAbortCheck was canceled.'); } } } @@ -164,19 +164,19 @@ export class MatchAborter extends LobbyPlugin { if (this.option.auto_abort_do_abort) { this.doAbort(); } else { - this.lobby.SendMessage("bot : if the game is stuck, abort the game with !abort vote."); + this.lobby.SendMessage('bot : if the game is stuck, abort the game with !abort vote.'); } } private stopTimer(): void { if (this.abortTimer != null) { - this.logger.trace("stop timer"); + this.logger.trace('stop timer'); clearTimeout(this.abortTimer); this.abortTimer = null; } } GetPluginStatus(): string { - return `-- Match Aborter -- timer : ${this.abortTimer != null ? "active" : "###"}, vote : ${this.voting.toString()}`; + return `-- Match Aborter -- timer : ${this.abortTimer != null ? 'active' : '###'}, vote : ${this.voting.toString()}`; } } diff --git a/src/plugins/MatchStarter.ts b/src/plugins/MatchStarter.ts index 97867526..51b0bb1a 100644 --- a/src/plugins/MatchStarter.ts +++ b/src/plugins/MatchStarter.ts @@ -17,7 +17,7 @@ export class MatchStarter extends LobbyPlugin { voting: VoteCounter; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "MatchStarter", "starter"); + super(lobby, 'MatchStarter', 'starter'); this.option = getConfig(this.pluginName, option) as MatchStarterOption; this.voting = new VoteCounter(this.option.vote_rate, this.option.vote_min); this.registerEvents(); @@ -71,8 +71,8 @@ export class MatchStarter extends LobbyPlugin { if (this.lobby.isMatching) return; switch (command) { - case "!start": - if (param == "") { + case '!start': + if (param == '') { if (player.isHost) { this.start(); } else { @@ -82,16 +82,16 @@ export class MatchStarter extends LobbyPlugin { this.startTimer(parseInt(param)); } break; - case "!stop": - case "!abort": + case '!stop': + case '!abort': if (player.isHost || player.isAuthorized) { if (this.IsSelfStartTimerActive) { - this.lobby.SendMessage("Aborted the match start timer"); + this.lobby.SendMessage('Aborted the match start timer'); this.stopTimer(); } } break; - case "*start": + case '*start': if (player.isAuthorized) { this.start(); } @@ -99,15 +99,15 @@ export class MatchStarter extends LobbyPlugin { } private onPluginMessage(type: string, args: string[], src: LobbyPlugin | null): void { - if (type == "mp_start") { + if (type == 'mp_start') { if (args.length == 0) { this.start(); } else { const count = parseInt(args[0]); - const withhelp = args[1] !== undefined && args[1] === "withhelp"; + const withhelp = args[1] !== undefined && args[1] === 'withhelp'; this.startTimer(count, withhelp); } - } else if (type == "mp_abort_start") { + } else if (type == 'mp_abort_start') { this.stopTimer(); } } @@ -115,20 +115,20 @@ export class MatchStarter extends LobbyPlugin { private vote(player: Player): void { if (this.voting.passed) return; if (this.voting.Vote(player)) { - this.logger.trace("accepted start request from %s", player.name); + this.logger.trace('accepted start request from %s', player.name); this.checkVoteCount(true); } else { - this.logger.trace("vote was ignored"); + this.logger.trace('vote was ignored'); } } // 投票状況を確認して、必要数に達している場合は試合を開始する private checkVoteCount(showMessage: boolean = false): void { if (this.voting.count != 0 && showMessage) { - this.lobby.DeferMessage(`bot : Match start progress: ${this.voting.toString()}`, "match start vote", this.option.vote_msg_defer_ms, false); + this.lobby.DeferMessage(`bot : Match start progress: ${this.voting.toString()}`, 'match start vote', this.option.vote_msg_defer_ms, false); } if (this.voting.passed) { - this.lobby.DeferMessage(`bot : passed start vote: ${this.voting.toString()}`, "match start vote", 100, true); + this.lobby.DeferMessage(`bot : passed start vote: ${this.voting.toString()}`, 'match start vote', 100, true); this.start(); } } @@ -137,10 +137,10 @@ export class MatchStarter extends LobbyPlugin { if (count == 0) { this.start(); } else { - this.lobby.SendMessage(`Queued the match to start in ${this.secsToCountdownText(count)}${withHint ? ". (Host can stop the timer with !stop command.)" : ""}`); - this.lobby.DeferMessage("!mp start", "mp_start", count * 1000, true); - if (15 < count) { - this.lobby.DeferMessage("Match starts in 10 seconds", "mp_start 10 sec", (count - 10) * 1000, true); + this.lobby.SendMessage(`Queued the match to start in ${this.secsToCountdownText(count)}${withHint ? '. (Host can stop the timer with !stop command.)' : ''}`); + this.lobby.DeferMessage('!mp start', 'mp_start', count * 1000, true); + if (count > 15) { + this.lobby.DeferMessage('Match starts in 10 seconds', 'mp_start 10 sec', (count - 10) * 1000, true); } } } @@ -149,24 +149,24 @@ export class MatchStarter extends LobbyPlugin { const min = Math.floor(secs / 60); const sec = Math.floor(secs % 60); - let strMin = ""; - let strAnd = ""; - let strSec = ""; + let strMin = ''; + let strAnd = ''; + let strSec = ''; if (min > 1) { - strMin = min.toString() + " minutes"; + strMin = min.toString() + ' minutes'; } else if (min == 1) { - strMin = "1 minute" + strMin = '1 minute'; } if (min > 0 && sec > 0) { - strAnd = " and " + strAnd = ' and '; } if (sec > 1) { - strSec = sec.toString() + " seconds"; + strSec = sec.toString() + ' seconds'; } else if (sec == 1) { - strSec = "1 second"; + strSec = '1 second'; } return `${strMin}${strAnd}${strSec}`; @@ -174,23 +174,23 @@ export class MatchStarter extends LobbyPlugin { private start(): void { this.stopTimer(); - this.lobby.SendMessageWithCoolTime("!mp start", "mp_start", 1000); + this.lobby.SendMessageWithCoolTime('!mp start', 'mp_start', 1000); this.voting.Clear(); } private stopTimer(): void { - this.lobby.CancelDeferredMessage("mp_start"); - this.lobby.CancelDeferredMessage("mp_start 10 sec"); - this.lobby.CancelDeferredMessage("match start vote"); + this.lobby.CancelDeferredMessage('mp_start'); + this.lobby.CancelDeferredMessage('mp_start 10 sec'); + this.lobby.CancelDeferredMessage('match start vote'); if (this.lobby.isStartTimerActive) { - this.lobby.SendMessage("!mp aborttimer"); + this.lobby.SendMessage('!mp aborttimer'); } } get IsSelfStartTimerActive(): boolean { - if ("mp_start" in this.lobby.deferredMessages) { - return !this.lobby.deferredMessages["mp_start"].done + if ('mp_start' in this.lobby.deferredMessages) { + return !this.lobby.deferredMessages['mp_start'].done; } return false; } diff --git a/src/plugins/MiscLoader.ts b/src/plugins/MiscLoader.ts index 84c4f64b..99619fd5 100644 --- a/src/plugins/MiscLoader.ts +++ b/src/plugins/MiscLoader.ts @@ -17,12 +17,12 @@ export interface MiscLoaderOption { export class MiscLoader extends LobbyPlugin { option: MiscLoaderOption; canResend: boolean = true; - beatconnectURL: string = "https://beatconnect.io/b/${beatmapset_id}"; - kitsuURL: string = "https://kitsu.moe/d/${beatmapset_id}"; + beatconnectURL: string = 'https://beatconnect.io/b/${beatmapset_id}'; + kitsuURL: string = 'https://kitsu.moe/d/${beatmapset_id}'; canSeeRank: boolean = false; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "MiscLoader", "miscLoader"); + super(lobby, 'MiscLoader', 'miscLoader'); if (WebApiClient.available) { this.canSeeRank = true; } @@ -31,7 +31,7 @@ export class MiscLoader extends LobbyPlugin { } private registerEvents(): void { - this.lobby.ReceivedChatCommand.on(a => this.onReceivedChatCommand(a.command, a.param, a.player)) + this.lobby.ReceivedChatCommand.on(a => this.onReceivedChatCommand(a.command, a.param, a.player)); this.lobby.ReceivedBanchoResponse.on(a => { if (a.response.type == BanchoResponseType.BeatmapChanged) { this.canResend = true; @@ -40,13 +40,13 @@ export class MiscLoader extends LobbyPlugin { } private async onReceivedChatCommand(command: string, param: string, player: Player): Promise { - if (command == "!mirror") { + if (command == '!mirror') { if (this.canResend) { this.checkMirror(this.lobby.mapId); } } - if (command == "!rank") { - this.getProfile(player) + if (command == '!rank') { + this.getProfile(player); } } @@ -55,32 +55,32 @@ export class MiscLoader extends LobbyPlugin { if (!this.canSeeRank) { return; } - let currentPlayer = this.lobby.GetPlayer(player.name); + const currentPlayer = this.lobby.GetPlayer(player.name); if (!currentPlayer) return; if (currentPlayer.id == 0 || this.lobby.gameMode == undefined) { - this.lobby.SendMessageWithCoolTime("!stats " + currentPlayer.name, "!rank", 10000); + this.lobby.SendMessageWithCoolTime('!stats ' + currentPlayer.name, '!rank', 10000); return; } - let selectedMode = ""; + let selectedMode = ''; switch (this.lobby.gameMode.value) { - case "0": - selectedMode = "osu"; + case '0': + selectedMode = 'osu'; break; - case "1": - selectedMode = "taiko"; + case '1': + selectedMode = 'taiko'; break; - case "2": - selectedMode = "fruits"; + case '2': + selectedMode = 'fruits'; break; - case "3": - selectedMode = "mania"; + case '3': + selectedMode = 'mania'; break; } const profile = await WebApiClient.getPlayer(currentPlayer.id, selectedMode); - const msg = profile.username + " your rank is #" + profile.statistics.global_rank; - this.lobby.SendMessageWithCoolTime(msg, "!rank", 5000); + const msg = profile.username + ' your rank is #' + profile.statistics.global_rank; + this.lobby.SendMessageWithCoolTime(msg, '!rank', 5000); } catch (e: any) { if (e instanceof FetchProfileError) { @@ -100,18 +100,18 @@ export class MiscLoader extends LobbyPlugin { async checkMirror(mapId: number): Promise { try { - let map = await BeatmapRepository.getBeatmap(mapId, this.lobby.gameMode); + const map = await BeatmapRepository.getBeatmap(mapId, this.lobby.gameMode); this.canResend = false; if (!map) { - this.lobby.SendMessage("Current beatmap doesn't have mirror..."); + this.lobby.SendMessage('Current beatmap doesn\'t have mirror...'); this.canResend = false; return; } this.canResend = true; - var beatconnectLink = this.beatconnectURL.replace(/\$\{beatmapset_id\}/g, map.beatmapset_id.toString()); - var kitsuLink = this.kitsuURL.replace(/\$\{beatmapset_id\}/g, map.beatmapset_id.toString()); - var beatmapView = map.beatmapset?.title.toString(); - this.lobby.SendMessageWithCoolTime(`Alternative download link for ${beatmapView} : [${beatconnectLink} BeatConnect.io] | [${kitsuLink} Kitsu.moe]`, "!mirror", 5000); + const beatconnectLink = this.beatconnectURL.replace(/\$\{beatmapset_id\}/g, map.beatmapset_id.toString()); + const kitsuLink = this.kitsuURL.replace(/\$\{beatmapset_id\}/g, map.beatmapset_id.toString()); + const beatmapView = map.beatmapset?.title.toString(); + this.lobby.SendMessageWithCoolTime(`Alternative download link for ${beatmapView} : [${beatconnectLink} BeatConnect.io] | [${kitsuLink} Kitsu.moe]`, '!mirror', 5000); } catch (e: any) { this.canResend = false; if (e instanceof FetchBeatmapError) { diff --git a/src/plugins/ProfileFecher.ts b/src/plugins/ProfileFecher.ts index f8465c71..1836e705 100644 --- a/src/plugins/ProfileFecher.ts +++ b/src/plugins/ProfileFecher.ts @@ -18,7 +18,7 @@ export class ProfileFecher extends LobbyPlugin { task: Promise; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "profile", "profile"); + super(lobby, 'profile', 'profile'); this.option = getConfig(this.pluginName, option) as ProfileFecherOption; this.profileMap = new Map(); this.pendingNames = new Set(); @@ -42,7 +42,7 @@ export class ProfileFecher extends LobbyPlugin { private addTaskQueueIfNeeded(player: Player): boolean { if (player.id !== 0) return false; - let profile = this.profileMap.get(player.name); + const profile = this.profileMap.get(player.name); if (profile && !this.isExpiredProfile(profile)) { player.id = profile.id; player.profile = profile; @@ -56,18 +56,18 @@ export class ProfileFecher extends LobbyPlugin { this.task = this.task.then(async () => { try { - let profile = await this.getProfileFromWebApi(player); + const profile = await this.getProfileFromWebApi(player); if (profile != null) { player.id = profile.id; player.profile = profile; - this.logger.info("fetch profile :" + player.name); + this.logger.info('fetch profile :' + player.name); } else { - this.logger.warn("user not found! " + player.name); + this.logger.warn('user not found! ' + player.name); } this.pendingNames.delete(player.name); } catch (e) { - this.logger.error("@addTaskQueueIfNeeded" + e); + this.logger.error('@addTaskQueueIfNeeded' + e); } }); diff --git a/src/plugins/VoteCounter.ts b/src/plugins/VoteCounter.ts index 824a500e..531d9ff2 100644 --- a/src/plugins/VoteCounter.ts +++ b/src/plugins/VoteCounter.ts @@ -33,7 +33,7 @@ export class VoteCounter { } public Clear(): void { - for (let k of this.voters.keys()) { + for (const k of this.voters.keys()) { this.voters.set(k, false); } this._passed = false; diff --git a/src/plugins/WordCounter.ts b/src/plugins/WordCounter.ts index c92d45ef..577963d1 100644 --- a/src/plugins/WordCounter.ts +++ b/src/plugins/WordCounter.ts @@ -34,7 +34,7 @@ export class WordCounter extends LobbyPlugin { lastLogTime: number = 0; constructor(lobby: Lobby, option: Partial = {}) { - super(lobby, "WordCounter", "wcounter"); + super(lobby, 'WordCounter', 'wcounter'); const d = config.get(this.pluginName); this.option = { ...d, ...option } as WordCounterOption; this.loadEnvSettings(this.option); @@ -47,7 +47,7 @@ export class WordCounter extends LobbyPlugin { chatsPerPeriodMax: 0, wordsPerPeriodMax: 0, index: 0 - } + }; }); this.registerEvents(); } @@ -71,7 +71,7 @@ export class WordCounter extends LobbyPlugin { const ns = { time: now, length: message.length }; let changedMax = false; - for (let p of this.periods) { + for (const p of this.periods) { p.chatsPerPeriod++; p.wordsPerPeriod += ns.length; while (p.index < this.samples.length && this.samples[p.index].time + p.durationMs < now) { @@ -92,10 +92,10 @@ export class WordCounter extends LobbyPlugin { this.samples.push(ns); const topIndex = this.periods.reduce((p, a) => a.index < p ? a.index : p, 1000000); // 時間切れのサンプルが溜まってきたら捨てる - if (this.samples.length / 2 < topIndex && 100 < this.samples.length) { + if (this.samples.length / 2 < topIndex && this.samples.length > 100) { this.logger.trace(`gc start len:${this.samples.length}, idx:${topIndex}`); this.samples = this.samples.slice(topIndex); - for (let p of this.periods) { + for (const p of this.periods) { p.index -= topIndex; } } @@ -103,16 +103,16 @@ export class WordCounter extends LobbyPlugin { } private log(msg: string, important: boolean): void { - let f = (important ? this.logger.info : this.logger.debug).bind(this.logger); - f("msg:%s", msg); - for (let p of this.periods) { + const f = (important ? this.logger.info : this.logger.debug).bind(this.logger); + f('msg:%s', msg); + for (const p of this.periods) { f(` ${p.symbol}(${(p.durationMs / 1000).toFixed(2)}sec) cp${p.symbol}:${p.chatsPerPeriod}(max:${p.chatsPerPeriodMax}), wp${p.symbol}:${p.wordsPerPeriod}(max:${p.wordsPerPeriodMax}) `); } } GetPluginStatus(): string { - let m = "-- Word Counter --"; - for (let p of this.periods) { + let m = '-- Word Counter --'; + for (const p of this.periods) { m += `\n ${p.symbol}(${(p.durationMs / 1000).toFixed(2)}sec) cp${p.symbol}:${p.chatsPerPeriod}(max:${p.chatsPerPeriodMax}), wp${p.symbol}:${p.wordsPerPeriod}(max:${p.wordsPerPeriodMax}) `; } diff --git a/src/tests/AfkKickerTest.ts b/src/tests/AfkKickerTest.ts index 95bda169..4cb67db0 100644 --- a/src/tests/AfkKickerTest.ts +++ b/src/tests/AfkKickerTest.ts @@ -5,184 +5,184 @@ import { StatResult, StatStatuses } from '../parsers/StatParser'; import { AfkKicker } from '../plugins/AfkKicker'; import tu from './TestUtils'; -describe("AfkKicker Tests", function () { - before(function () { - tu.configMochaAsSilent(); - }); +describe('AfkKicker Tests', function () { + before(function () { + tu.configMochaAsSilent(); + }); - async function setupAsync(): + async function setupAsync(): Promise<{ kicker: AfkKicker, lobby: Lobby, ircClient: DummyIrcClient }> { - const li = await tu.SetupLobbyAsync(); - const kicker = new AfkKicker(li.lobby, { cooltime_ms: 0, threshold: 6, enabled: true }); - return { kicker, ...li }; - } - - it("stat afk test", async () => { - let { kicker, lobby, ircClient } = await setupAsync(); - let players = (await tu.AddPlayersAsync(["p1", "p2"], ircClient)) - .map(name => lobby.GetOrMakePlayer(name)); - - ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); - - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - lobby.SendMessage("!stat p1"); - lobby.SendMessage("!stat p2"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - }); - - it("zero score test", async () => { - let { kicker, lobby, ircClient } = await setupAsync(); - let players = (await tu.AddPlayersAsync(["p1", "p2"], ircClient)) - .map(name => lobby.GetOrMakePlayer(name)); - - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - await ircClient.emulateMatchAsync(0, [{ name: "p1", score: 0, passed: false }, { name: "p2", score: 100, passed: true }]); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 2); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - await ircClient.emulateMatchAsync(0, [{ name: "p1", score: 100, passed: true }, { name: "p2", score: 100, passed: true }]); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - }); - - it("no map test", async () => { - let { kicker, lobby, ircClient } = await setupAsync(); - let players = (await tu.AddPlayersAsync(["p1", "p2"], ircClient)) - .map(name => lobby.GetOrMakePlayer(name)); - - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - await ircClient.emulateMatchAsync(0, [{ name: "p2", score: 100, passed: true }]); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 2); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - await ircClient.emulateMatchAsync(0, [{ name: "p1", score: 100, passed: true }, { name: "p2", score: 100, passed: true }]); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - }); - - it("chat test", async () => { - let { kicker, lobby, ircClient } = await setupAsync(); - let players = (await tu.AddPlayersAsync(["p1", "p2"], ircClient)) - .map(name => lobby.GetOrMakePlayer(name)); - - ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); - lobby.SendMessage("!stat p1"); - - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - - ircClient.emulateMessage("p1", ircClient.channel, "hello"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 2); - ircClient.emulateMessage("p1", ircClient.channel, "hello"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 1); - ircClient.emulateMessage("p1", ircClient.channel, "hello"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); - ircClient.emulateMessage("p1", ircClient.channel, "hello"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); - - ircClient.emulateMessage("p2", ircClient.channel, "hello"); - assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); - }); - - it("kick test", async () => { - let { kicker, lobby, ircClient } = await setupAsync(); - let players = (await tu.AddPlayersAsync(["p1", "p2"], ircClient)) - .map(name => lobby.GetOrMakePlayer(name)); - - ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); - lobby.SendMessage("!stat p1"); - assert.notInclude(lobby.players, players[0]); - assert.include(lobby.players, players[1]); - }); - - it("cooltime test", async () => { - let { kicker, lobby, ircClient } = await setupAsync(); - let players = (await tu.AddPlayersAsync(["p1", "p2"], ircClient)) - .map(name => lobby.GetOrMakePlayer(name)); - - kicker.option.threshold = 100; - kicker.option.cooltime_ms = 0; - - ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); - lobby.SendMessage("!stat p1"); - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); - - kicker.option.cooltime_ms = 1000; - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); - - kicker.option.cooltime_ms = 0; - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 9); - }); - - it("enabled / disabled test", async () => { - let { kicker, lobby, ircClient } = await setupAsync(); - let players = (await tu.AddPlayersAsync(["p1", "p2"], ircClient)) - .map(name => lobby.GetOrMakePlayer(name)); - - kicker.option.threshold = 100; - kicker.option.cooltime_ms = 0; - - ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); - - kicker.option.enabled = false; - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); - - kicker.option.enabled = true; - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); - - kicker.option.enabled = false; - lobby.SendMessage("!stat p1"); - assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); - }); - - - it("command tests", async () => { - let { kicker, lobby } = await setupAsync(); - kicker.option.enabled = false; - kicker.option.cooltime_ms = 0; - kicker.option.threshold = 0; - - - await tu.sendMessageAsOwner(lobby, "*afkkick_enable"); - assert.isTrue(kicker.option.enabled); - assert.equal(kicker.option.cooltime_ms, 0); - assert.equal(kicker.option.threshold, 0); - - await tu.sendMessageAsOwner(lobby, "*afkkick_disable"); - assert.isFalse(kicker.option.enabled); - assert.equal(kicker.option.cooltime_ms, 0); - assert.equal(kicker.option.threshold, 0); - - await tu.sendMessageAsOwner(lobby, "*afkkick_threshold 100"); - assert.isFalse(kicker.option.enabled); - assert.equal(kicker.option.cooltime_ms, 0); - assert.equal(kicker.option.threshold, 100); - - await tu.sendMessageAsOwner(lobby, "*afkkick_threshold 0"); - assert.isFalse(kicker.option.enabled); - assert.equal(kicker.option.cooltime_ms, 0); - assert.equal(kicker.option.threshold, 1); // min v = 1 - - await tu.sendMessageAsOwner(lobby, "*afkkick_cooltime 100000000"); - assert.isFalse(kicker.option.enabled); - assert.equal(kicker.option.cooltime_ms, 100000000); - assert.equal(kicker.option.threshold, 1); - - await tu.sendMessageAsOwner(lobby, "*afkkick_cooltime 0"); - assert.isFalse(kicker.option.enabled); - assert.equal(kicker.option.cooltime_ms, 10000); - assert.equal(kicker.option.threshold, 1); - - }); + const li = await tu.SetupLobbyAsync(); + const kicker = new AfkKicker(li.lobby, { cooltime_ms: 0, threshold: 6, enabled: true }); + return { kicker, ...li }; + } + + it('stat afk test', async () => { + const { kicker, lobby, ircClient } = await setupAsync(); + const players = (await tu.AddPlayersAsync(['p1', 'p2'], ircClient)) + .map(name => lobby.GetOrMakePlayer(name)); + + ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); + + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + lobby.SendMessage('!stat p1'); + lobby.SendMessage('!stat p2'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + }); + + it('zero score test', async () => { + const { kicker, lobby, ircClient } = await setupAsync(); + const players = (await tu.AddPlayersAsync(['p1', 'p2'], ircClient)) + .map(name => lobby.GetOrMakePlayer(name)); + + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + await ircClient.emulateMatchAsync(0, [{ name: 'p1', score: 0, passed: false }, { name: 'p2', score: 100, passed: true }]); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 2); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + await ircClient.emulateMatchAsync(0, [{ name: 'p1', score: 100, passed: true }, { name: 'p2', score: 100, passed: true }]); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + }); + + it('no map test', async () => { + const { kicker, lobby, ircClient } = await setupAsync(); + const players = (await tu.AddPlayersAsync(['p1', 'p2'], ircClient)) + .map(name => lobby.GetOrMakePlayer(name)); + + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + await ircClient.emulateMatchAsync(0, [{ name: 'p2', score: 100, passed: true }]); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 2); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + await ircClient.emulateMatchAsync(0, [{ name: 'p1', score: 100, passed: true }, { name: 'p2', score: 100, passed: true }]); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + }); + + it('chat test', async () => { + const { kicker, lobby, ircClient } = await setupAsync(); + const players = (await tu.AddPlayersAsync(['p1', 'p2'], ircClient)) + .map(name => lobby.GetOrMakePlayer(name)); + + ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); + lobby.SendMessage('!stat p1'); + + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + + ircClient.emulateMessage('p1', ircClient.channel, 'hello'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 2); + ircClient.emulateMessage('p1', ircClient.channel, 'hello'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 1); + ircClient.emulateMessage('p1', ircClient.channel, 'hello'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); + ircClient.emulateMessage('p1', ircClient.channel, 'hello'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 0); + + ircClient.emulateMessage('p2', ircClient.channel, 'hello'); + assert.equal(kicker.playerStats.get(players[1])?.afkPoint, 0); + }); + + it('kick test', async () => { + const { kicker, lobby, ircClient } = await setupAsync(); + const players = (await tu.AddPlayersAsync(['p1', 'p2'], ircClient)) + .map(name => lobby.GetOrMakePlayer(name)); + + ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); + lobby.SendMessage('!stat p1'); + assert.notInclude(lobby.players, players[0]); + assert.include(lobby.players, players[1]); + }); + + it('cooltime test', async () => { + const { kicker, lobby, ircClient } = await setupAsync(); + const players = (await tu.AddPlayersAsync(['p1', 'p2'], ircClient)) + .map(name => lobby.GetOrMakePlayer(name)); + + kicker.option.threshold = 100; + kicker.option.cooltime_ms = 0; + + ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); + lobby.SendMessage('!stat p1'); + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); + + kicker.option.cooltime_ms = 1000; + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); + + kicker.option.cooltime_ms = 0; + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 9); + }); + + it('enabled / disabled test', async () => { + const { kicker, lobby, ircClient } = await setupAsync(); + const players = (await tu.AddPlayersAsync(['p1', 'p2'], ircClient)) + .map(name => lobby.GetOrMakePlayer(name)); + + kicker.option.threshold = 100; + kicker.option.cooltime_ms = 0; + + ircClient.SetStat(new StatResult(players[0].escaped_name, 100, StatStatuses.Afk)); + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); + + kicker.option.enabled = false; + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 3); + + kicker.option.enabled = true; + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); + + kicker.option.enabled = false; + lobby.SendMessage('!stat p1'); + assert.equal(kicker.playerStats.get(players[0])?.afkPoint, 6); + }); + + + it('command tests', async () => { + const { kicker, lobby } = await setupAsync(); + kicker.option.enabled = false; + kicker.option.cooltime_ms = 0; + kicker.option.threshold = 0; + + + await tu.sendMessageAsOwner(lobby, '*afkkick_enable'); + assert.isTrue(kicker.option.enabled); + assert.equal(kicker.option.cooltime_ms, 0); + assert.equal(kicker.option.threshold, 0); + + await tu.sendMessageAsOwner(lobby, '*afkkick_disable'); + assert.isFalse(kicker.option.enabled); + assert.equal(kicker.option.cooltime_ms, 0); + assert.equal(kicker.option.threshold, 0); + + await tu.sendMessageAsOwner(lobby, '*afkkick_threshold 100'); + assert.isFalse(kicker.option.enabled); + assert.equal(kicker.option.cooltime_ms, 0); + assert.equal(kicker.option.threshold, 100); + + await tu.sendMessageAsOwner(lobby, '*afkkick_threshold 0'); + assert.isFalse(kicker.option.enabled); + assert.equal(kicker.option.cooltime_ms, 0); + assert.equal(kicker.option.threshold, 1); // min v = 1 + + await tu.sendMessageAsOwner(lobby, '*afkkick_cooltime 100000000'); + assert.isFalse(kicker.option.enabled); + assert.equal(kicker.option.cooltime_ms, 100000000); + assert.equal(kicker.option.threshold, 1); + + await tu.sendMessageAsOwner(lobby, '*afkkick_cooltime 0'); + assert.isFalse(kicker.option.enabled); + assert.equal(kicker.option.cooltime_ms, 10000); + assert.equal(kicker.option.threshold, 1); + + }); }); diff --git a/src/tests/AutoHostSelectorTest.ts b/src/tests/AutoHostSelectorTest.ts index 79fe245f..eafa2f7e 100644 --- a/src/tests/AutoHostSelectorTest.ts +++ b/src/tests/AutoHostSelectorTest.ts @@ -8,7 +8,7 @@ import { MpSettingsCases } from './cases/MpSettingsCases'; import tu from './TestUtils'; -describe("AutoHostSelectorTest", function () { +describe('AutoHostSelectorTest', function () { before(function () { tu.configMochaAsSilent(); }); @@ -23,27 +23,27 @@ describe("AutoHostSelectorTest", function () { function assertStateIs(state: string, s: AutoHostSelector): void { const l = s.lobby; switch (state) { - case "s0": // no players + case 's0': // no players assert.equal(s.hostQueue.length, 0); break; - case "s1": // no host + case 's1': // no host assert.isTrue(s.hostQueue.length > 0); assert.isTrue(!l.isMatching); assert.isTrue(l.host == null); break; - case "hr": // has host and needs to rotate - assert.isTrue(s.hostQueue.length > 0, "s.hostQueue.length > 0"); - assert.isTrue(!l.isMatching), "!l.isMatching"; - assert.isTrue(s.needsRotate, "s.needsRotate"); - assert.isTrue(l.host != null, "l.host != null"); + case 'hr': // has host and needs to rotate + assert.isTrue(s.hostQueue.length > 0, 's.hostQueue.length > 0'); + assert.isTrue(!l.isMatching), '!l.isMatching'; + assert.isTrue(s.needsRotate, 's.needsRotate'); + assert.isTrue(l.host != null, 'l.host != null'); break; - case "hn": // has host and no needs to rotate + case 'hn': // has host and no needs to rotate assert.isTrue(s.hostQueue.length > 0); assert.isTrue(!l.isMatching); assert.isFalse(s.needsRotate); assert.isTrue(l.host != null); break; - case "m": // matching + case 'm': // matching assert.isTrue(s.hostQueue.length > 0); assert.isTrue(l.isMatching); break; @@ -52,617 +52,617 @@ describe("AutoHostSelectorTest", function () { } } - it("constructor test", async () => { + it('constructor test', async () => { const { selector } = await prepareSelector(); - assertStateIs("s0", selector); + assertStateIs('s0', selector); }); - it("dispose event test", (done) => { + it('dispose event test', (done) => { prepareSelector().then(({ selector, ircClient }) => { - ircClient.part(ircClient.channel, "", () => { + ircClient.part(ircClient.channel, '', () => { assert.isEmpty(selector.eventDisposers); done(); }); - }) + }); }); - describe("state transition tests", function () { - it("s0 -> h test", async () => { + describe('state transition tests', function () { + it('s0 -> h test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - assertStateIs("s0", selector); - await ircClient.emulateAddPlayerAsync("player1"); - assertStateIs("hr", selector); + assertStateIs('s0', selector); + await ircClient.emulateAddPlayerAsync('player1'); + assertStateIs('hr', selector); }); - it("s0 -> s1 -> hr test", async () => { + it('s0 -> s1 -> hr test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); ircClient.latency = 1; let s1checked = false; lobby.PlayerJoined.once(({ player, slot }) => { - assert.equal(player.name, "player1"); - assertStateIs("s1", selector); + assert.equal(player.name, 'player1'); + assertStateIs('s1', selector); s1checked = true; }); - assertStateIs("s0", selector); + assertStateIs('s0', selector); - await ircClient.emulateAddPlayerAsync("player1"); + await ircClient.emulateAddPlayerAsync('player1'); tu.assertEventFire(lobby.HostChanged, (a) => { - assertStateIs("hr", selector); + assertStateIs('hr', selector); assert.isTrue(s1checked); return true; }); }); - it("s0 -> hr -> s0 test", async () => { + it('s0 -> hr -> s0 test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - assertStateIs("s0", selector); - await ircClient.emulateAddPlayerAsync("player1"); - assertStateIs("hr", selector); + assertStateIs('s0', selector); + await ircClient.emulateAddPlayerAsync('player1'); + assertStateIs('hr', selector); await tu.delayAsync(10); - await ircClient.emulateRemovePlayerAsync("player1"); - assertStateIs("s0", selector); + await ircClient.emulateRemovePlayerAsync('player1'); + assertStateIs('s0', selector); }); - it("hr[1] -> hr[3] -> s0", async () => { + it('hr[1] -> hr[3] -> s0', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - assertStateIs("s0", selector); - const pids = ["player1", "player2", "player3"]; + assertStateIs('s0', selector); + const pids = ['player1', 'player2', 'player3']; await tu.AddPlayersAsync(pids, ircClient); - tu.assertHost("player1", lobby); - assertStateIs("hr", selector); - await ircClient.emulateRemovePlayerAsync("player2"); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); - await ircClient.emulateRemovePlayerAsync("player1"); - assertStateIs("hr", selector); - tu.assertHost("player3", lobby); - await ircClient.emulateRemovePlayerAsync("player3"); - assertStateIs("s0", selector); - }); - - it("hr -> m -> hr", async () => { + tu.assertHost('player1', lobby); + assertStateIs('hr', selector); + await ircClient.emulateRemovePlayerAsync('player2'); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); + await ircClient.emulateRemovePlayerAsync('player1'); + assertStateIs('hr', selector); + tu.assertHost('player3', lobby); + await ircClient.emulateRemovePlayerAsync('player3'); + assertStateIs('s0', selector); + }); + + it('hr -> m -> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); }); - it("hr -> m -> hr repeat", async () => { + it('hr -> m -> hr repeat', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player3", lobby); + assertStateIs('hr', selector); + tu.assertHost('player3', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); }); - it("hr -> hn -> m -> hr", async () => { + it('hr -> hn -> m -> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - await ircClient.emulateRemovePlayerAsync("player1"); - assertStateIs("hn", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + await ircClient.emulateRemovePlayerAsync('player1'); + assertStateIs('hn', selector); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); }); - it("hr -[leave]-> hn -[change map]-> hr -> m -> hr", async () => { + it('hr -[leave]-> hn -[change map]-> hr -> m -> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - await ircClient.emulateRemovePlayerAsync("player1"); - assertStateIs("hn", selector); - tu.assertHost("player2", lobby); + await ircClient.emulateRemovePlayerAsync('player1'); + assertStateIs('hn', selector); + tu.assertHost('player2', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player3", lobby); + assertStateIs('hr', selector); + tu.assertHost('player3', lobby); }); - it("hr -[transfer]-> hn -[change map]-> hr -> m -> hr", async () => { + it('hr -[transfer]-> hn -[change map]-> hr -> m -> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - await ircClient.emulateChangeHost("player2"); - assertStateIs("hn", selector); - tu.assertHost("player2", lobby); + await ircClient.emulateChangeHost('player2'); + assertStateIs('hn', selector); + tu.assertHost('player2', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player3", lobby); + assertStateIs('hr', selector); + tu.assertHost('player3', lobby); }); - it("hr -> m -[abort]-> hn", async () => { + it('hr -> m -[abort]-> hn', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); + assertStateIs('hr', selector); await ircClient.emulateMatchAndAbortAsync(0, 0); - assertStateIs("hn", selector); - tu.assertHost("player1", lobby); + assertStateIs('hn', selector); + tu.assertHost('player1', lobby); }); // アボート後にホストがマップを変更するとhostが切り替わる - it("hr -> m -[abort]-> hn -[mapchange]-> hn -> hr", async () => { + it('hr -> m -[abort]-> hn -[mapchange]-> hn -> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); + assertStateIs('hr', selector); await ircClient.emulateMatchAndAbortAsync(0, 0); - assertStateIs("hn", selector); - tu.assertHost("player1", lobby); + assertStateIs('hn', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hn", selector); - tu.assertHost("player2", lobby); + assertStateIs('hn', selector); + tu.assertHost('player2', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); }); - it("hr -> m -[abort]-> hn -[leave]-> hn -> hr", async () => { + it('hr -> m -[abort]-> hn -[leave]-> hn -> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); + assertStateIs('hr', selector); await ircClient.emulateMatchAndAbortAsync(0, 0); - assertStateIs("hn", selector); - tu.assertHost("player1", lobby); - await ircClient.emulateRemovePlayerAsync("player1"); - assertStateIs("hn", selector); - tu.assertHost("player2", lobby); + assertStateIs('hn', selector); + tu.assertHost('player1', lobby); + await ircClient.emulateRemovePlayerAsync('player1'); + assertStateIs('hn', selector); + tu.assertHost('player2', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); }); - it("hr -> s0 -> hr", async () => { + it('hr -> s0 -> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - await ircClient.emulateRemovePlayerAsync("player1"); - assertStateIs("s0", selector); - await tu.AddPlayersAsync(["player1"], ircClient); - tu.assertHost("player1", lobby); - assertStateIs("hr", selector); - }); - it("hr -> s0 -> hn -[map change]-> hr", async () => { + assertStateIs('hr', selector); + await ircClient.emulateRemovePlayerAsync('player1'); + assertStateIs('s0', selector); + await tu.AddPlayersAsync(['player1'], ircClient); + tu.assertHost('player1', lobby); + assertStateIs('hr', selector); + }); + it('hr -> s0 -> hn -[map change]-> hr', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - await ircClient.emulateRemovePlayerAsync("player1"); - assertStateIs("s0", selector); - await tu.AddPlayersAsync(["player2", "player3"], ircClient); - tu.assertHost("player2", lobby); - assertStateIs("hn", selector); + assertStateIs('hr', selector); + await ircClient.emulateRemovePlayerAsync('player1'); + assertStateIs('s0', selector); + await tu.AddPlayersAsync(['player2', 'player3'], ircClient); + tu.assertHost('player2', lobby); + assertStateIs('hn', selector); await ircClient.emulateMatchAsync(0); - tu.assertHost("player2", lobby); - assertStateIs("hr", selector); + tu.assertHost('player2', lobby); + assertStateIs('hr', selector); }); }); - describe("join and left tests", function () { + describe('join and left tests', function () { // 試合中にプレイヤーが入ってきた場合、現在のホストの後ろに配置される - it("newcomer who join during the match should be enqueued after the currnt host.", async () => { + it('newcomer who join during the match should be enqueued after the currnt host.', async () => { const { selector, lobby, ircClient } = await prepareSelector(false); - await tu.AddPlayersAsync(["player1", "player2"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); const task = ircClient.emulateMatchAsync(4); await tu.delayAsync(1); - ircClient.emulateAddPlayerAsync("player3"); // join during the match + ircClient.emulateAddPlayerAsync('player3'); // join during the match await task; - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); // not player3 + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); // not player3 }); - it("player left in the match", async () => { + it('player left in the match', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); let task = ircClient.emulateMatchAsync(4); await tu.delayAsync(1); - await ircClient.emulateRemovePlayerAsync("player3"); + await ircClient.emulateRemovePlayerAsync('player3'); await task; - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); task = ircClient.emulateMatchAsync(4); await tu.delayAsync(1); - await ircClient.emulateRemovePlayerAsync("player2"); + await ircClient.emulateRemovePlayerAsync('player2'); await task; - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); - await ircClient.emulateAddPlayerAsync("player4"); - await ircClient.emulateAddPlayerAsync("player5"); - await ircClient.emulateAddPlayerAsync("player6"); + await ircClient.emulateAddPlayerAsync('player4'); + await ircClient.emulateAddPlayerAsync('player5'); + await ircClient.emulateAddPlayerAsync('player6'); task = ircClient.emulateMatchAsync(4); await tu.delayAsync(1); - await ircClient.emulateRemovePlayerAsync("player1"); + await ircClient.emulateRemovePlayerAsync('player1'); await task; - assertStateIs("hr", selector); - tu.assertHost("player4", lobby); + assertStateIs('hr', selector); + tu.assertHost('player4', lobby); }); - it("transfer host manually test", async () => { + it('transfer host manually test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); - await ircClient.emulateChangeHost("player2"); + await ircClient.emulateChangeHost('player2'); await tu.delayAsync(1); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); - await ircClient.emulateChangeHost("player1"); + await ircClient.emulateChangeHost('player1'); await tu.delayAsync(1); - tu.assertHost("player3", lobby); + tu.assertHost('player3', lobby); - await ircClient.emulateChangeHost("player3"); + await ircClient.emulateChangeHost('player3'); await tu.delayAsync(1); - tu.assertHost("player3", lobby); + tu.assertHost('player3', lobby); - await ircClient.emulateChangeHost("player2"); + await ircClient.emulateChangeHost('player2'); await tu.delayAsync(1); - tu.assertHost("player1", lobby); + tu.assertHost('player1', lobby); }); - it("appoint next host when current host leave", async () => { + it('appoint next host when current host leave', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); - await ircClient.emulateRemovePlayerAsync("player1"); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); + await ircClient.emulateRemovePlayerAsync('player1'); await tu.delayAsync(1); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); }); - it("conflict transfer host manually and plugin rotation test1", async () => { + it('conflict transfer host manually and plugin rotation test1', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); const t1 = ircClient.emulateMatchAsync(1); ircClient.latency = 1; await t1; ircClient.latency = 0; - await ircClient.emulateChangeHost("player3"); + await ircClient.emulateChangeHost('player3'); await tu.delayAsync(10); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); }); - it("conflict transfer host manually and plugin rotation test2", async () => { + it('conflict transfer host manually and plugin rotation test2', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); const t1 = ircClient.emulateMatchAsync(1); ircClient.latency = 1; await t1; ircClient.latency = 0; - await ircClient.emulateChangeHost("player2"); + await ircClient.emulateChangeHost('player2'); await tu.delayAsync(10); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); }); - it("issue #37 host left and match started at the same time", async () => { + it('issue #37 host left and match started at the same time', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); ircClient.latency = 10; // it makes bot respond to !mp start command before !mp host command - await ircClient.emulateRemovePlayerAsync("player1"); + await ircClient.emulateRemovePlayerAsync('player1'); ircClient.latency = 0; const t1 = ircClient.emulateMatchAsync(20); await tu.delayAsync(10); - tu.assertHost("player2", lobby); - assertStateIs("m", selector); + tu.assertHost('player2', lobby); + assertStateIs('m', selector); await t1; - tu.assertHost("player2", lobby); - assertStateIs("hr", selector); + tu.assertHost('player2', lobby); + assertStateIs('hr', selector); }); - it("issue #37 test rotation after the issue", async () => { + it('issue #37 test rotation after the issue', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); ircClient.latency = 10; - await ircClient.emulateRemovePlayerAsync("player1"); + await ircClient.emulateRemovePlayerAsync('player1'); ircClient.latency = 0; const t1 = ircClient.emulateMatchAsync(20); await tu.delayAsync(10); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); await t1; - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); await ircClient.emulateChangeMapAsync(0); await ircClient.emulateMatchAsync(0); - tu.assertHost("player3", lobby); + tu.assertHost('player3', lobby); }); - it("issue #37 player2 dosen't change map test", async () => { + it('issue #37 player2 dosen\'t change map test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(0); ircClient.latency = 10; // it makes bot respond to !mp start command before !mp host command - await ircClient.emulateRemovePlayerAsync("player1"); + await ircClient.emulateRemovePlayerAsync('player1'); ircClient.latency = 0; const t1 = ircClient.emulateMatchAsync(20); await tu.delayAsync(10); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); await t1; - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(0); - tu.assertHost("player3", lobby); + tu.assertHost('player3', lobby); }); }); - describe("external operation tests", function () { - it("plugin message skip test", async () => { + describe('external operation tests', function () { + it('plugin message skip test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); - selector.SendPluginMessage("skip"); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); + selector.SendPluginMessage('skip'); await tu.delayAsync(5); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); }); - it("plugin message skipto test", async () => { + it('plugin message skipto test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); - selector.SendPluginMessage("skipto", ["player3"]); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); + selector.SendPluginMessage('skipto', ['player3']); await tu.delayAsync(5); - tu.assertHost("player3", lobby); - assert.equal(selector.hostQueue[0].name, "player3"); - assert.equal(selector.hostQueue[1].name, "player1"); - assert.equal(selector.hostQueue[2].name, "player2"); + tu.assertHost('player3', lobby); + assert.equal(selector.hostQueue[0].name, 'player3'); + assert.equal(selector.hostQueue[1].name, 'player1'); + assert.equal(selector.hostQueue[2].name, 'player2'); - selector.SendPluginMessage("skipto", ["player3"]); + selector.SendPluginMessage('skipto', ['player3']); await tu.delayAsync(5); - tu.assertHost("player3", lobby); - assert.equal(selector.hostQueue[0].name, "player3"); - assert.equal(selector.hostQueue[1].name, "player1"); - assert.equal(selector.hostQueue[2].name, "player2"); + tu.assertHost('player3', lobby); + assert.equal(selector.hostQueue[0].name, 'player3'); + assert.equal(selector.hostQueue[1].name, 'player1'); + assert.equal(selector.hostQueue[2].name, 'player2'); }); }); - describe("skip tests", function () { - it("should change host when changed map -> changed host -> map change -> match start", async () => { + describe('skip tests', function () { + it('should change host when changed map -> changed host -> map change -> match start', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); await ircClient.emulateChangeMapAsync(0); - await ircClient.emulateRemovePlayerAsync("player2"); - assertStateIs("hn", selector); - tu.assertHost("player3", lobby); + await ircClient.emulateRemovePlayerAsync('player2'); + assertStateIs('hn', selector); + tu.assertHost('player3', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player3", lobby); + assertStateIs('hr', selector); + tu.assertHost('player3', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); }); - it("should not change host when changed map -> changed host -> started match", async () => { + it('should not change host when changed map -> changed host -> started match', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); await ircClient.emulateMatchAsync(0); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); await ircClient.emulateChangeMapAsync(0); - await ircClient.emulateRemovePlayerAsync("player2"); - assertStateIs("hn", selector); - tu.assertHost("player3", lobby); + await ircClient.emulateRemovePlayerAsync('player2'); + assertStateIs('hn', selector); + tu.assertHost('player3', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player3", lobby); + assertStateIs('hr', selector); + tu.assertHost('player3', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); }); }); - describe("match abort tests", function () { - it("should not change host if match is aborted before any player finished", async () => { + describe('match abort tests', function () { + it('should not change host if match is aborted before any player finished', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateMatchAndAbortAsync(); - assertStateIs("hn", selector); - tu.assertHost("player1", lobby); + assertStateIs('hn', selector); + tu.assertHost('player1', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); }); - it("should change host when match is aborted after some players finished", async () => { + it('should change host when match is aborted after some players finished', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateMatchAndAbortAsync(0, 1); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player3", lobby); + assertStateIs('hr', selector); + tu.assertHost('player3', lobby); }); - it("should change host when match start -> abort -> map change", async () => { + it('should change host when match start -> abort -> map change', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); await ircClient.emulateMatchAndAbortAsync(); - assertStateIs("hn", selector); - tu.assertHost("player1", lobby); + assertStateIs('hn', selector); + tu.assertHost('player1', lobby); await ircClient.emulateChangeMapAsync(); - assertStateIs("hn", selector); - tu.assertHost("player2", lobby); + assertStateIs('hn', selector); + tu.assertHost('player2', lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); - tu.assertHost("player2", lobby); + assertStateIs('hr', selector); + tu.assertHost('player2', lobby); }); - it("should change host and be remainable when map change -> match start -> host left -> match abort", async () => { + it('should change host and be remainable when map change -> match start -> host left -> match abort', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const players = await tu.AddPlayersAsync(5, ircClient); await ircClient.emulateMatchAsync(0); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); + assertStateIs('hr', selector); tu.assertHost(players[1], lobby); - let t = ircClient.emulateMatchAsync(60); + const t = ircClient.emulateMatchAsync(60); await tu.delayAsync(1); await ircClient.emulateRemovePlayerAsync(players[1]); - assertStateIs("m", selector); + assertStateIs('m', selector); assert.isNull(lobby.host); lobby.AbortMatch(); await tu.delayAsync(1); - assertStateIs("hn", selector); + assertStateIs('hn', selector); tu.assertHost(players[2], lobby); await ircClient.emulateMatchAsync(0); - assertStateIs("hr", selector); + assertStateIs('hr', selector); tu.assertHost(players[2], lobby); }); - it("should not change host when -> match start -> host left -> match abort -> map change", async () => { + it('should not change host when -> match start -> host left -> match abort -> map change', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const players = await tu.AddPlayersAsync(5, ircClient); await ircClient.emulateMatchAsync(0); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); + assertStateIs('hr', selector); tu.assertHost(players[1], lobby); - let t = ircClient.emulateMatchAsync(30); + const t = ircClient.emulateMatchAsync(30); await tu.delayAsync(1); await ircClient.emulateRemovePlayerAsync(players[1]); - assertStateIs("m", selector); + assertStateIs('m', selector); assert.isNull(lobby.host); lobby.AbortMatch(); await tu.delayAsync(1); - assertStateIs("hn", selector); + assertStateIs('hn', selector); tu.assertHost(players[2], lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); + assertStateIs('hr', selector); tu.assertHost(players[2], lobby); }); - it("should change host when -> match start -> host left -> player finish -> match abort -> map change", async () => { + it('should change host when -> match start -> host left -> player finish -> match abort -> map change', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - const players = await tu.AddPlayersAsync(["a", "b", "c", "d"], ircClient); + const players = await tu.AddPlayersAsync(['a', 'b', 'c', 'd'], ircClient); await ircClient.emulateMatchAsync(0); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("b", lobby); - let t = ircClient.emulateMatchAndAbortAsync(10, ["a", "c", "d"]); + assertStateIs('hr', selector); + tu.assertHost('b', lobby); + const t = ircClient.emulateMatchAndAbortAsync(10, ['a', 'c', 'd']); await tu.delayAsync(1); - await ircClient.emulateRemovePlayerAsync("b"); - assertStateIs("m", selector); + await ircClient.emulateRemovePlayerAsync('b'); + assertStateIs('m', selector); assert.isNull(lobby.host); await t; - assertStateIs("hr", selector); - tu.assertHost("c", lobby); + assertStateIs('hr', selector); + tu.assertHost('c', lobby); await ircClient.emulateChangeMapAsync(0); - assertStateIs("hr", selector); - tu.assertHost("c", lobby); + assertStateIs('hr', selector); + tu.assertHost('c', lobby); }); }); - describe("mp settings tests", function () { - it("empty lobby case1_1", async () => { + describe('mp settings tests', function () { + it('empty lobby case1_1', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const c = MpSettingsCases.case1_1; - const q = ["p1", "p2", "p3", "p4", "p5"]; + const q = ['p1', 'p2', 'p3', 'p4', 'p5']; ircClient.emulateMpSettings(c); for (let i = 0; i < selector.hostQueue.length; i++) { assert.equal(selector.hostQueue[i].name, q[i]); } }); - it("empty lobby case1_2", async () => { + it('empty lobby case1_2', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const c = MpSettingsCases.case1_2; - const q = ["p3", "p4", "p5", "p1", "p2"]; + const q = ['p3', 'p4', 'p5', 'p1', 'p2']; ircClient.emulateMpSettings(c); for (let i = 0; i < selector.hostQueue.length; i++) { assert.equal(selector.hostQueue[i].name, q[i]); } }); - it("change host test", async () => { + it('change host test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const c = MpSettingsCases.case1_1; - const q1 = ["p1", "p2", "p3", "p4", "p5"]; - const q2 = ["p3", "p4", "p5", "p1", "p2"]; + const q1 = ['p1', 'p2', 'p3', 'p4', 'p5']; + const q2 = ['p3', 'p4', 'p5', 'p1', 'p2']; ircClient.emulateMpSettings(c); for (let i = 0; i < selector.hostQueue.length; i++) { assert.equal(selector.hostQueue[i].name, q1[i]); } - selector.SkipTo("p3"); + selector.SkipTo('p3'); for (let i = 0; i < selector.hostQueue.length; i++) { assert.equal(selector.hostQueue[i].name, q2[i]); } if (lobby.host == null) return; assert.isTrue(lobby.host.isHost); - assert.equal(lobby.host.name, "p3"); + assert.equal(lobby.host.name, 'p3'); ircClient.emulateMpSettings(c); for (let i = 0; i < selector.hostQueue.length; i++) { assert.equal(selector.hostQueue[i].name, q1[i]); } - assert.equal(lobby.host.name, "p1"); + assert.equal(lobby.host.name, 'p1'); }); - it("mod queue test", async () => { + it('mod queue test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const c1 = MpSettingsCases.case1_1; const c3 = MpSettingsCases.case1_3; - const q1 = ["p1", "p2", "p3", "p4", "p5"]; - const q2 = ["p4", "p5", "p6", "p7", "p2"]; + const q1 = ['p1', 'p2', 'p3', 'p4', 'p5']; + const q2 = ['p4', 'p5', 'p6', 'p7', 'p2']; ircClient.emulateMpSettings(c1); for (let i = 0; i < selector.hostQueue.length; i++) { assert.equal(selector.hostQueue[i].name, q1[i]); @@ -674,19 +674,19 @@ describe("AutoHostSelectorTest", function () { } if (lobby.host == null) assert.fail(); - else assert.equal(lobby.host.name, "p4"); + else assert.equal(lobby.host.name, 'p4'); }); - it("reset queue test", async () => { + it('reset queue test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const c1 = MpSettingsCases.case1_1; - const q1 = ["p1", "p2", "p3", "p4", "p5"]; - const q2 = ["p4", "p5", "p6", "p7", "p2"]; + const q1 = ['p1', 'p2', 'p3', 'p4', 'p5']; + const q2 = ['p4', 'p5', 'p6', 'p7', 'p2']; ircClient.emulateMpSettings(c1); for (let i = 0; i < selector.hostQueue.length; i++) { assert.equal(selector.hostQueue[i].name, q1[i]); } - ircClient.emulateRemovePlayerAsync("p1"); - selector.SkipTo("p3"); + ircClient.emulateRemovePlayerAsync('p1'); + selector.SkipTo('p3'); ircClient.emulateMpSettings(c1); for (let i = 0; i < selector.hostQueue.length; i++) { @@ -694,104 +694,104 @@ describe("AutoHostSelectorTest", function () { } if (lobby.host == null) assert.fail(); - else assert.equal(lobby.host.name, "p1"); + else assert.equal(lobby.host.name, 'p1'); }); }); - describe("reoder tests", function () { - it("reaoder", async () => { + describe('reoder tests', function () { + it('reaoder', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const players = await tu.AddPlayersAsync(5, ircClient); - const od = ["p3", "p1", "p2", "p4", "p0"]; - selector.Reorder(od.join(",")); + const od = ['p3', 'p1', 'p2', 'p4', 'p0']; + selector.Reorder(od.join(',')); await tu.delayAsync(1); - tu.assertHost("p3", lobby); + tu.assertHost('p3', lobby); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); } }); - it("disguised string", async () => { + it('disguised string', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const players = await tu.AddPlayersAsync(5, ircClient); - const disguised = "p​0, p​1, p​2, p​3, p​4"; - const od = ["p0", "p1", "p2", "p3", "p4"]; - selector.SkipTo("p3"); + const disguised = 'p​0, p​1, p​2, p​3, p​4'; + const od = ['p0', 'p1', 'p2', 'p3', 'p4']; + selector.SkipTo('p3'); await tu.delayAsync(1); selector.Reorder(disguised); await tu.delayAsync(1); - tu.assertHost("p0", lobby); + tu.assertHost('p0', lobby); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); } }); - it("no change", async () => { + it('no change', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const players = await tu.AddPlayersAsync(5, ircClient); - const odtxt = "p​0, p​1, p​2, p​3, p​4"; - const od = ["p0", "p1", "p2", "p3", "p4"]; + const odtxt = 'p​0, p​1, p​2, p​3, p​4'; + const od = ['p0', 'p1', 'p2', 'p3', 'p4']; selector.Reorder(odtxt); await tu.delayAsync(1); - tu.assertHost("p0", lobby); + tu.assertHost('p0', lobby); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); } }); - it("partially specify", async () => { + it('partially specify', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const players = await tu.AddPlayersAsync(5, ircClient); - const odtxt = "p​3, p​4, p2"; - const od = ["p3", "p4", "p2", "p0", "p1"]; + const odtxt = 'p​3, p​4, p2'; + const od = ['p3', 'p4', 'p2', 'p0', 'p1']; selector.Reorder(odtxt); await tu.delayAsync(1); - tu.assertHost("p3", lobby); + tu.assertHost('p3', lobby); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); } }); - it("extra specify", async () => { + it('extra specify', async () => { const { selector, lobby, ircClient } = await prepareSelector(); const players = await tu.AddPlayersAsync(5, ircClient); - const odtxt = "p3, p6, p4, p2, p5, p0, p1"; - const od = ["p3", "p4", "p2", "p0", "p1"]; + const odtxt = 'p3, p6, p4, p2, p5, p0, p1'; + const od = ['p3', 'p4', 'p2', 'p0', 'p1']; selector.Reorder(odtxt); await tu.delayAsync(1); - tu.assertHost("p3", lobby); + tu.assertHost('p3', lobby); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); } }); - it("from custom command", async () => { + it('from custom command', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - lobby.option.authorized_users = ["p0"]; + lobby.option.authorized_users = ['p0']; const players = await tu.AddPlayersAsync(5, ircClient); - const odtxt = "*reorder p​0, p​1, p​2, p​3, p​4"; - const od = ["p0", "p1", "p2", "p3", "p4"]; - selector.SkipTo("p3"); - tu.assertHost("p3", lobby); + const odtxt = '*reorder p​0, p​1, p​2, p​3, p​4'; + const od = ['p0', 'p1', 'p2', 'p3', 'p4']; + selector.SkipTo('p3'); + tu.assertHost('p3', lobby); await tu.delayAsync(1); - await ircClient.emulateMessageAsync("p0", ircClient.channel, odtxt); + await ircClient.emulateMessageAsync('p0', ircClient.channel, odtxt); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); } }); - it("invalid custom command", async () => { + it('invalid custom command', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - lobby.option.authorized_users = ["p0"]; + lobby.option.authorized_users = ['p0']; const players = await tu.AddPlayersAsync(5, ircClient); - let odtxt = "*reorder"; - const od = ["p3", "p4", "p0", "p1", "p2"]; - selector.SkipTo("p3"); - tu.assertHost("p3", lobby); + let odtxt = '*reorder'; + const od = ['p3', 'p4', 'p0', 'p1', 'p2']; + selector.SkipTo('p3'); + tu.assertHost('p3', lobby); await tu.delayAsync(1); - await ircClient.emulateMessageAsync("p0", ircClient.channel, odtxt); + await ircClient.emulateMessageAsync('p0', ircClient.channel, odtxt); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); } - odtxt = "*reorder asdfsafasdf"; + odtxt = '*reorder asdfsafasdf'; await tu.delayAsync(1); - await ircClient.emulateMessageAsync("p0", ircClient.channel, odtxt); + await ircClient.emulateMessageAsync('p0', ircClient.channel, odtxt); for (let i = 0; i < od.length; i++) { assert.equal(selector.hostQueue[i].name, od[i]); @@ -799,389 +799,389 @@ describe("AutoHostSelectorTest", function () { }); }); - describe("cleared host tests", function () { - it("clearhost and match", async () => { + describe('cleared host tests', function () { + it('clearhost and match', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); - lobby.SendMessage("!mp clearhost"); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); + lobby.SendMessage('!mp clearhost'); assert.isTrue(lobby.isClearedHost); assert.isNull(lobby.host); await ircClient.emulateMatchAsync(); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); }); - it("plugin skip test", async () => { + it('plugin skip test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - await tu.AddPlayersAsync(["player1", "player2", "player3"], ircClient); - assertStateIs("hr", selector); - tu.assertHost("player1", lobby); - lobby.SendMessage("!mp clearhost"); + await tu.AddPlayersAsync(['player1', 'player2', 'player3'], ircClient); + assertStateIs('hr', selector); + tu.assertHost('player1', lobby); + lobby.SendMessage('!mp clearhost'); assert.isTrue(lobby.isClearedHost); assert.isNull(lobby.host); - selector.SendPluginMessage("skip"); + selector.SendPluginMessage('skip'); await tu.delayAsync(5); - tu.assertHost("player2", lobby); + tu.assertHost('player2', lobby); }); }); - describe("denylist tests", function () { - it("denied player should ignore test", async () => { + describe('denylist tests', function () { + it('denied player should ignore test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p3")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p3')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(selector.hostQueue.length, 4); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p1")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p2")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p5")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p1')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p2')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p5')); lobby.destroy(); }); - it("transfer host to denied player test", async () => { + it('transfer host to denied player test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p4")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p4')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(selector.hostQueue.length, 4); - tu.assertHost("p1", lobby); - await ircClient.emulateChangeHost("p4"); - tu.assertHost("p2", lobby); - await ircClient.emulateChangeHost("p4"); - tu.assertHost("p3", lobby); - await ircClient.emulateChangeHost("p4"); - tu.assertHost("p5", lobby); - await ircClient.emulateChangeHost("p1"); - tu.assertHost("p1", lobby); + tu.assertHost('p1', lobby); + await ircClient.emulateChangeHost('p4'); + tu.assertHost('p2', lobby); + await ircClient.emulateChangeHost('p4'); + tu.assertHost('p3', lobby); + await ircClient.emulateChangeHost('p4'); + tu.assertHost('p5', lobby); + await ircClient.emulateChangeHost('p1'); + tu.assertHost('p1', lobby); lobby.destroy(); }); - it("only denied player test", async () => { + it('only denied player test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p4")); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p5")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p4')); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p5')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(selector.hostQueue.length, 3); - tu.assertHost("p1", lobby); - await ircClient.emulateRemovePlayerAsync("p1"); - tu.assertHost("p2", lobby); - await ircClient.emulateRemovePlayerAsync("p3"); - tu.assertHost("p2", lobby); - await ircClient.emulateRemovePlayerAsync("p2"); + tu.assertHost('p1', lobby); + await ircClient.emulateRemovePlayerAsync('p1'); + tu.assertHost('p2', lobby); + await ircClient.emulateRemovePlayerAsync('p3'); + tu.assertHost('p2', lobby); + await ircClient.emulateRemovePlayerAsync('p2'); assert.equal(selector.hostQueue.length, 0); assert.isNull(lobby.host); - await ircClient.emulateRemovePlayerAsync("p4"); + await ircClient.emulateRemovePlayerAsync('p4'); assert.equal(selector.hostQueue.length, 0); assert.isNull(lobby.host); lobby.destroy(); }); - it("only denied player -> join someone test", async () => { + it('only denied player -> join someone test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p4")); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p5")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p4')); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p5')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(selector.hostQueue.length, 3); - await ircClient.emulateRemovePlayerAsync("p1"); - await ircClient.emulateRemovePlayerAsync("p2"); - await ircClient.emulateRemovePlayerAsync("p3"); + await ircClient.emulateRemovePlayerAsync('p1'); + await ircClient.emulateRemovePlayerAsync('p2'); + await ircClient.emulateRemovePlayerAsync('p3'); assert.equal(selector.hostQueue.length, 0); assert.isNull(lobby.host); - await ircClient.emulateAddPlayerAsync("p6"); - tu.assertHost("p6", lobby); + await ircClient.emulateAddPlayerAsync('p6'); + tu.assertHost('p6', lobby); lobby.destroy(); }); - it("skipto command test", async () => { + it('skipto command test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p4")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p4')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); - selector.SendPluginMessage("skipto", ["p3"]); - tu.assertHost("p3", lobby); - selector.SendPluginMessage("skipto", ["p4"]); - tu.assertHost("p3", lobby); + selector.SendPluginMessage('skipto', ['p3']); + tu.assertHost('p3', lobby); + selector.SendPluginMessage('skipto', ['p4']); + tu.assertHost('p3', lobby); lobby.destroy(); }); - it("add player to denylist test", async () => { + it('add player to denylist test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); - tu.assertHost("p1", lobby); + tu.assertHost('p1', lobby); assert.equal(selector.hostQueue.length, 5); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p3")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p3')); assert.equal(selector.hostQueue.length, 4); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p1")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p2")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p5")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p1')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p2')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p5')); lobby.destroy(); }); - it("add host to denylist test", async () => { + it('add host to denylist test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); - tu.assertHost("p1", lobby); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p1")); - tu.assertHost("p2", lobby); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p2")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p3")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p5")); + tu.assertHost('p1', lobby); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p1')); + tu.assertHost('p2', lobby); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p2')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p3')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p5')); lobby.destroy(); }); - it("add last player to denylist test", async () => { + it('add last player to denylist test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); - tu.assertHost("p1", lobby); + tu.assertHost('p1', lobby); assert.equal(selector.hostQueue.length, 5); - await ircClient.emulateRemovePlayerAsync("p1"); - await ircClient.emulateRemovePlayerAsync("p2"); - await ircClient.emulateRemovePlayerAsync("p3"); + await ircClient.emulateRemovePlayerAsync('p1'); + await ircClient.emulateRemovePlayerAsync('p2'); + await ircClient.emulateRemovePlayerAsync('p3'); - tu.assertHost("p4", lobby); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p5")); - tu.assertHost("p4", lobby); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p4")); + tu.assertHost('p4', lobby); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p5')); + tu.assertHost('p4', lobby); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p4')); assert.equal(selector.hostQueue.length, 0); assert.isNull(lobby.host); lobby.destroy(); }); - it("remove player from denlylist test", async () => { + it('remove player from denlylist test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p3")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p3')); - tu.assertHost("p1", lobby); + tu.assertHost('p1', lobby); assert.equal(selector.hostQueue.length, 4); - DENY_LIST.removePlayer(lobby.GetOrMakePlayer("p3")); + DENY_LIST.removePlayer(lobby.GetOrMakePlayer('p3')); assert.equal(selector.hostQueue.length, 5); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p1")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p2")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p5")); - assert.equal(selector.hostQueue[4], lobby.GetOrMakePlayer("p3")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p1')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p2')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p5')); + assert.equal(selector.hostQueue[4], lobby.GetOrMakePlayer('p3')); lobby.destroy(); }); - it("remove player from denlylist test - no one in queue", async () => { + it('remove player from denlylist test - no one in queue', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p1")); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p2")); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p3")); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p4")); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p5")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p1')); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p2')); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p3')); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p4')); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p5')); assert.equal(selector.hostQueue.length, 0); - DENY_LIST.removePlayer(lobby.GetOrMakePlayer("p3")); + DENY_LIST.removePlayer(lobby.GetOrMakePlayer('p3')); assert.equal(selector.hostQueue.length, 1); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p3")); - tu.assertHost("p3", lobby); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p3')); + tu.assertHost('p3', lobby); lobby.destroy(); }); - it("slotbase reoder test1", async () => { + it('slotbase reoder test1', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p3")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p3')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(selector.hostQueue.length, 4); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p1")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p2")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p5")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p1')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p2')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p5')); lobby.destroy(); }); - it("slotbase reoder test2", async () => { + it('slotbase reoder test2', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p4")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p4')); await ircClient.emulateMpSettings(MpSettingsCases.case1_2); assert.equal(selector.hostQueue.length, 4); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p3")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p5")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p1")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p2")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p3')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p5')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p1')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p2')); lobby.destroy(); }); - it("slotbase reoder test - host is denied", async () => { + it('slotbase reoder test - host is denied', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p3")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p3')); await ircClient.emulateMpSettings(MpSettingsCases.case1_2); assert.equal(selector.hostQueue.length, 4); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p1")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p2")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p5")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p1')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p2')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p5')); lobby.destroy(); }); - it("modify order test - stay", async () => { + it('modify order test - stay', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p5")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p5')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); await ircClient.emulateMpSettings(MpSettingsCases.case1_3); assert.equal(selector.hostQueue.length, 4); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p6")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p7")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p2")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p6')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p7')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p2')); lobby.destroy(); }); - it("modify order test - leave", async () => { + it('modify order test - leave', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p1")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p1')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); await ircClient.emulateMpSettings(MpSettingsCases.case1_3); assert.equal(selector.hostQueue.length, 5); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p5")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p6")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p7")); - assert.equal(selector.hostQueue[4], lobby.GetOrMakePlayer("p2")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p5')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p6')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p7')); + assert.equal(selector.hostQueue[4], lobby.GetOrMakePlayer('p2')); lobby.destroy(); }); - it("modify order test - join", async () => { + it('modify order test - join', async () => { const { selector, lobby, ircClient } = await prepareSelector(); - DENY_LIST.addPlayer(lobby.GetOrMakePlayer("p7")); + DENY_LIST.addPlayer(lobby.GetOrMakePlayer('p7')); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); await ircClient.emulateMpSettings(MpSettingsCases.case1_3); assert.equal(selector.hostQueue.length, 4); - assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer("p4")); - assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer("p5")); - assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer("p6")); - assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer("p2")); + assert.equal(selector.hostQueue[0], lobby.GetOrMakePlayer('p4')); + assert.equal(selector.hostQueue[1], lobby.GetOrMakePlayer('p5')); + assert.equal(selector.hostQueue[2], lobby.GetOrMakePlayer('p6')); + assert.equal(selector.hostQueue[3], lobby.GetOrMakePlayer('p2')); lobby.destroy(); }); - describe("denylist command tests", () => { - it("add test", async () => { + describe('denylist command tests', () => { + it('add test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(DENY_LIST.players.size, 0); - tu.sendMessageAsOwner(lobby, "*denylist add p1"); + tu.sendMessageAsOwner(lobby, '*denylist add p1'); assert.equal(DENY_LIST.players.size, 1); - assert.include(DENY_LIST.players, "p1"); + assert.include(DENY_LIST.players, 'p1'); - tu.sendMessageAsOwner(lobby, "*denylist add p2 sfd"); + tu.sendMessageAsOwner(lobby, '*denylist add p2 sfd'); assert.equal(DENY_LIST.players.size, 2); - assert.include(DENY_LIST.players, escapeUserName("p2 sfd")); + assert.include(DENY_LIST.players, escapeUserName('p2 sfd')); - tu.sendMessageAsOwner(lobby, "*denylist add"); + tu.sendMessageAsOwner(lobby, '*denylist add'); assert.equal(DENY_LIST.players.size, 2); - let un = "asdf hello"; - tu.sendMessageAsOwner(lobby, "*denylist add " + un); + const un = 'asdf hello'; + tu.sendMessageAsOwner(lobby, '*denylist add ' + un); assert.equal(DENY_LIST.players.size, 3); assert.include(DENY_LIST.players, escapeUserName(un)); lobby.destroy(); }); - it("add twice test", async () => { + it('add twice test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(DENY_LIST.players.size, 0); - tu.sendMessageAsOwner(lobby, "*denylist add p1"); + tu.sendMessageAsOwner(lobby, '*denylist add p1'); assert.equal(DENY_LIST.players.size, 1); - assert.include(DENY_LIST.players, "p1"); + assert.include(DENY_LIST.players, 'p1'); - tu.sendMessageAsOwner(lobby, "*denylist add p1"); + tu.sendMessageAsOwner(lobby, '*denylist add p1'); assert.equal(DENY_LIST.players.size, 1); - assert.include(DENY_LIST.players, "p1"); + assert.include(DENY_LIST.players, 'p1'); lobby.destroy(); }); - it("remove test", async () => { + it('remove test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(DENY_LIST.players.size, 0); - tu.sendMessageAsOwner(lobby, "*denylist add p1"); - tu.sendMessageAsOwner(lobby, "*denylist add p2 piyo"); - tu.sendMessageAsOwner(lobby, "*denylist add p3 HOGE"); + tu.sendMessageAsOwner(lobby, '*denylist add p1'); + tu.sendMessageAsOwner(lobby, '*denylist add p2 piyo'); + tu.sendMessageAsOwner(lobby, '*denylist add p3 HOGE'); assert.equal(DENY_LIST.players.size, 3); - assert.include(DENY_LIST.players, escapeUserName("p1")); - assert.include(DENY_LIST.players, escapeUserName("p2 piyo")); - assert.include(DENY_LIST.players, escapeUserName("p3 HOGE")); + assert.include(DENY_LIST.players, escapeUserName('p1')); + assert.include(DENY_LIST.players, escapeUserName('p2 piyo')); + assert.include(DENY_LIST.players, escapeUserName('p3 HOGE')); - tu.sendMessageAsOwner(lobby, "*denylist remove p1"); + tu.sendMessageAsOwner(lobby, '*denylist remove p1'); assert.equal(DENY_LIST.players.size, 2); - assert.notInclude(DENY_LIST.players, escapeUserName("p1")); - assert.include(DENY_LIST.players, escapeUserName("p2 piyo")); - assert.include(DENY_LIST.players, escapeUserName("p3 HOGE")); + assert.notInclude(DENY_LIST.players, escapeUserName('p1')); + assert.include(DENY_LIST.players, escapeUserName('p2 piyo')); + assert.include(DENY_LIST.players, escapeUserName('p3 HOGE')); - tu.sendMessageAsOwner(lobby, "*denylist remove p2 piyo"); + tu.sendMessageAsOwner(lobby, '*denylist remove p2 piyo'); assert.equal(DENY_LIST.players.size, 1); - assert.notInclude(DENY_LIST.players, escapeUserName("p1")); - assert.notInclude(DENY_LIST.players, escapeUserName("p2 piyo")); - assert.include(DENY_LIST.players, escapeUserName("p3 HOGE")); + assert.notInclude(DENY_LIST.players, escapeUserName('p1')); + assert.notInclude(DENY_LIST.players, escapeUserName('p2 piyo')); + assert.include(DENY_LIST.players, escapeUserName('p3 HOGE')); - tu.sendMessageAsOwner(lobby, "*denylist remove p3 hoge"); + tu.sendMessageAsOwner(lobby, '*denylist remove p3 hoge'); assert.equal(DENY_LIST.players.size, 0); - assert.notInclude(DENY_LIST.players, escapeUserName("p1")); - assert.notInclude(DENY_LIST.players, escapeUserName("p2 piyo")); - assert.notInclude(DENY_LIST.players, escapeUserName("p3 HOGE")); + assert.notInclude(DENY_LIST.players, escapeUserName('p1')); + assert.notInclude(DENY_LIST.players, escapeUserName('p2 piyo')); + assert.notInclude(DENY_LIST.players, escapeUserName('p3 HOGE')); lobby.destroy(); }); - it("remove twice test", async () => { + it('remove twice test', async () => { const { selector, lobby, ircClient } = await prepareSelector(); await ircClient.emulateMpSettings(MpSettingsCases.case1_1); assert.equal(DENY_LIST.players.size, 0); - tu.sendMessageAsOwner(lobby, "*denylist add p1"); - tu.sendMessageAsOwner(lobby, "*denylist add p2"); - tu.sendMessageAsOwner(lobby, "*denylist add p3"); + tu.sendMessageAsOwner(lobby, '*denylist add p1'); + tu.sendMessageAsOwner(lobby, '*denylist add p2'); + tu.sendMessageAsOwner(lobby, '*denylist add p3'); assert.equal(DENY_LIST.players.size, 3); - assert.include(DENY_LIST.players, escapeUserName("p1")); - assert.include(DENY_LIST.players, escapeUserName("p2")); - assert.include(DENY_LIST.players, escapeUserName("p3")); + assert.include(DENY_LIST.players, escapeUserName('p1')); + assert.include(DENY_LIST.players, escapeUserName('p2')); + assert.include(DENY_LIST.players, escapeUserName('p3')); - tu.sendMessageAsOwner(lobby, "*denylist remove p1"); - tu.sendMessageAsOwner(lobby, "*denylist remove p1"); + tu.sendMessageAsOwner(lobby, '*denylist remove p1'); + tu.sendMessageAsOwner(lobby, '*denylist remove p1'); assert.equal(DENY_LIST.players.size, 2); - assert.notInclude(DENY_LIST.players, escapeUserName("p1")); - assert.include(DENY_LIST.players, escapeUserName("p2")); - assert.include(DENY_LIST.players, escapeUserName("p3")); + assert.notInclude(DENY_LIST.players, escapeUserName('p1')); + assert.include(DENY_LIST.players, escapeUserName('p2')); + assert.include(DENY_LIST.players, escapeUserName('p3')); lobby.destroy(); }); }); - it("multi lobby tests", async () => { + it('multi lobby tests', async () => { const a = await prepareSelector(); const b = await prepareSelector(); @@ -1192,32 +1192,32 @@ describe("AutoHostSelectorTest", function () { assert.equal(a.selector.hostQueue.length, 5); assert.equal(b.selector.hostQueue.length, 5); - DENY_LIST.addPlayer(a.lobby.GetOrMakePlayer("p1")); + DENY_LIST.addPlayer(a.lobby.GetOrMakePlayer('p1')); assert.equal(DENY_LIST.players.size, 1); assert.equal(a.selector.hostQueue.length, 4); assert.equal(b.selector.hostQueue.length, 5); - DENY_LIST.addPlayer(a.lobby.GetOrMakePlayer("p2")); + DENY_LIST.addPlayer(a.lobby.GetOrMakePlayer('p2')); assert.equal(DENY_LIST.players.size, 2); assert.equal(a.selector.hostQueue.length, 3); assert.equal(b.selector.hostQueue.length, 4); - assert.equal(a.selector.hostQueue[0], a.lobby.GetOrMakePlayer("p3")); - assert.equal(a.selector.hostQueue[1], a.lobby.GetOrMakePlayer("p4")); - assert.equal(a.selector.hostQueue[2], a.lobby.GetOrMakePlayer("p5")); + assert.equal(a.selector.hostQueue[0], a.lobby.GetOrMakePlayer('p3')); + assert.equal(a.selector.hostQueue[1], a.lobby.GetOrMakePlayer('p4')); + assert.equal(a.selector.hostQueue[2], a.lobby.GetOrMakePlayer('p5')); - assert.equal(b.selector.hostQueue[0], b.lobby.GetOrMakePlayer("p4")); - assert.equal(b.selector.hostQueue[1], b.lobby.GetOrMakePlayer("p5")); - assert.equal(b.selector.hostQueue[2], b.lobby.GetOrMakePlayer("p7")); - assert.equal(b.selector.hostQueue[3], b.lobby.GetOrMakePlayer("p6")); + assert.equal(b.selector.hostQueue[0], b.lobby.GetOrMakePlayer('p4')); + assert.equal(b.selector.hostQueue[1], b.lobby.GetOrMakePlayer('p5')); + assert.equal(b.selector.hostQueue[2], b.lobby.GetOrMakePlayer('p7')); + assert.equal(b.selector.hostQueue[3], b.lobby.GetOrMakePlayer('p6')); a.lobby.destroy(); b.lobby.destroy(); }); }); - describe("tests for issues", () => { + describe('tests for issues', () => { - }) + }); }); diff --git a/src/tests/AutoStartTimerTest.ts b/src/tests/AutoStartTimerTest.ts index 784a245d..59916d79 100644 --- a/src/tests/AutoStartTimerTest.ts +++ b/src/tests/AutoStartTimerTest.ts @@ -5,7 +5,7 @@ import { DummyIrcClient } from '../dummies/DummyIrcClient'; import { AutoStartTimer, AutoStartTimerOption } from '../plugins/AutoStartTimer'; import tu from './TestUtils'; -describe("AutoStartTimerTest", function () { +describe('AutoStartTimerTest', function () { before(function () { tu.configMochaAsSilent(); }); @@ -17,26 +17,26 @@ describe("AutoStartTimerTest", function () { enabled: enabled, doClearHost: doClearHost, waitingTime: waitingTime - } + }; const players = await tu.AddPlayersAsync(3, li.ircClient); - const astimer = new AutoStartTimer(li.lobby, option) + const astimer = new AutoStartTimer(li.lobby, option); return { astimer, players, ...li }; } - describe("auto start tests", function () { - it("normal operation test", async () => { + describe('auto start tests', function () { + it('normal operation test', async () => { const { lobby, ircClient } = await prepare(true, true, 60); let c = 0, d = 0; lobby.SentMessage.on(a => { - assert.equal(a.message, "!mp clearhost"); + assert.equal(a.message, '!mp clearhost'); c++; }); lobby.PluginMessage.on(a => { if (d == 0) { - assert.equal(a.type, "mp_abort_start"); + assert.equal(a.type, 'mp_abort_start'); } else if (d == 1) { - assert.equal(a.type, "mp_start"); - assert.equal(a.args[0], "60"); + assert.equal(a.type, 'mp_start'); + assert.equal(a.args[0], '60'); } d++; }); @@ -44,19 +44,19 @@ describe("AutoStartTimerTest", function () { assert.equal(c, 1); assert.equal(d, 2); }); - it("no clearhost test", async () => { + it('no clearhost test', async () => { const { lobby, ircClient } = await prepare(true, false, 60); let c = 0, d = 0; lobby.SentMessage.on(a => { - assert.equal(a.message, "!mp clearhost"); + assert.equal(a.message, '!mp clearhost'); c++; }); lobby.PluginMessage.on(a => { if (d == 0) { - assert.equal(a.type, "mp_abort_start"); + assert.equal(a.type, 'mp_abort_start'); } else if (d == 1) { - assert.equal(a.type, "mp_start"); - assert.equal(a.args[0], "60"); + assert.equal(a.type, 'mp_start'); + assert.equal(a.args[0], '60'); } d++; }); @@ -64,7 +64,7 @@ describe("AutoStartTimerTest", function () { assert.equal(c, 0); assert.equal(d, 2); }); - it("disabled test", async () => { + it('disabled test', async () => { const { lobby, ircClient } = await prepare(false, false, 60); let c = 0; lobby.SentMessage.on(a => { @@ -73,15 +73,15 @@ describe("AutoStartTimerTest", function () { await ircClient.emulateChangeMapAsync(); assert.equal(c, 0); }); - it("timer cancel test", async () => { + it('timer cancel test', async () => { const { lobby, ircClient } = await prepare(true, false, 60); let d = 0; lobby.PluginMessage.on(a => { if (d == 0 || d == 2) { - assert.equal(a.type, "mp_abort_start"); + assert.equal(a.type, 'mp_abort_start'); } else if (d == 1 || d == 3) { - assert.equal(a.type, "mp_start"); - assert.equal(a.args[0], "60"); + assert.equal(a.type, 'mp_start'); + assert.equal(a.args[0], '60'); } d++; }); @@ -89,21 +89,21 @@ describe("AutoStartTimerTest", function () { await ircClient.emulateChangeMapAsync(); assert.equal(d, 4); }); - it("timer will cancel when host changed", async () => { + it('timer will cancel when host changed', async () => { const { players, lobby, ircClient } = await prepare(true, true, 60); let c = 0; lobby.SentMessage.on(a => { if (c == 2 || c == 5) { - assert.equal(a.message, "!mp clearhost"); + assert.equal(a.message, '!mp clearhost'); } c++; }); lobby.PluginMessage.on(a => { if (c == 0 || c == 3) { - assert.equal(a.type, "mp_abort_start"); + assert.equal(a.type, 'mp_abort_start'); } else if (c == 1 || c == 4) { - assert.equal(a.type, "mp_start"); - assert.equal(a.args[0], "60"); + assert.equal(a.type, 'mp_start'); + assert.equal(a.args[0], '60'); } c++; }); @@ -113,29 +113,29 @@ describe("AutoStartTimerTest", function () { assert.equal(c, 6); }); }); - describe("option tests", function () { + describe('option tests', function () { function assertOptions(astimer: AutoStartTimer, enabled: boolean, doClearHost: boolean, waitingTime: number): void { assert.equal(astimer.option.enabled, enabled); assert.equal(astimer.option.doClearHost, doClearHost); assert.equal(astimer.option.waitingTime, waitingTime); } - it("option setting test", async () => { + it('option setting test', async () => { const { astimer, lobby, ircClient } = await prepare(true, false, 60); assertOptions(astimer, true, false, 60); - const p1 = lobby.GetOrMakePlayer("p1"); + const p1 = lobby.GetOrMakePlayer('p1'); p1.setRole(Roles.Authorized); - lobby.RaiseReceivedChatCommand(p1, "*autostart_disable"); + lobby.RaiseReceivedChatCommand(p1, '*autostart_disable'); assertOptions(astimer, false, false, 60); - lobby.RaiseReceivedChatCommand(p1, "*autostart_enable"); + lobby.RaiseReceivedChatCommand(p1, '*autostart_enable'); assertOptions(astimer, true, false, 60); - lobby.RaiseReceivedChatCommand(p1, "*autostart_clearhost_enable"); + lobby.RaiseReceivedChatCommand(p1, '*autostart_clearhost_enable'); assertOptions(astimer, true, true, 60); - lobby.RaiseReceivedChatCommand(p1, "*atuostart_clearhost_disable"); + lobby.RaiseReceivedChatCommand(p1, '*atuostart_clearhost_disable'); assertOptions(astimer, true, false, 60); - lobby.RaiseReceivedChatCommand(p1, "*autostart_time 50"); + lobby.RaiseReceivedChatCommand(p1, '*autostart_time 50'); assertOptions(astimer, true, false, 50); - lobby.RaiseReceivedChatCommand(p1, "*autostart_time -50"); + lobby.RaiseReceivedChatCommand(p1, '*autostart_time -50'); assertOptions(astimer, true, false, 15); }); }); diff --git a/src/tests/BeatmapRepositoryTest.ts b/src/tests/BeatmapRepositoryTest.ts index 1c3199c9..a98b59a1 100644 --- a/src/tests/BeatmapRepositoryTest.ts +++ b/src/tests/BeatmapRepositoryTest.ts @@ -7,321 +7,321 @@ import tu from './TestUtils'; import fs from 'fs/promises'; -describe("BeatmapRepository Tests", function () { +describe('BeatmapRepository Tests', function () { + before(function () { + tu.configMochaAsSilent(); + }); + + afterEach(function () { + BeatmapRepository.maps.clear(); + }); + + describe.skip('fetch beatmap form osu.ppy.sh tests', () => { before(function () { - tu.configMochaAsSilent(); - }); - - afterEach(function () { - BeatmapRepository.maps.clear(); - }); - - describe.skip("fetch beatmap form osu.ppy.sh tests", () => { - before(function () { - BeatmapRepository.fetcher = BeatmapRepository.websiteFetcher; - }); - - it("parse website test", async () => { - const bufSrc = await fs.readFile("./src/tests/cases/3182198.html"); - const src = bufSrc.toString(); - const reg = new RegExp('', "ms"); - const match = reg.exec(src); - if (match) { - console.log(match[1]); - const json = JSON.parse(match[1]); - console.log(json); - } else { - assert.fail(); - } + BeatmapRepository.fetcher = BeatmapRepository.websiteFetcher; + }); + + it('parse website test', async () => { + const bufSrc = await fs.readFile('./src/tests/cases/3182198.html'); + const src = bufSrc.toString(); + const reg = new RegExp('', 'ms'); + const match = reg.exec(src); + if (match) { + console.log(match[1]); + const json = JSON.parse(match[1]); + console.log(json); + } else { + assert.fail(); + } - }); - - it("fetch osu map", async () => { - const mapid = 3182198; - const b = await BeatmapRepository.getBeatmap(mapid); - assert.equal(b.mode, "osu"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "aquamarine"); - }); - - it("fetch invalid map id", async () => { - const mapid = 737157; - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.NotFound); - } else { - assert.fail(); - } - } - }); - - it("fetch taiko map", async () => { - const mapid = 2938202; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); - assert.equal(b.mode, "taiko"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "The Old Blood"); - }); - - it("fetch fruits map", async () => { - const mapid = 3175483; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.CatchTheBeat); - assert.equal(b.mode, "fruits"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "Otter Pop (feat. Hollis)"); - }); - - it("fetch mania map", async () => { - const mapid = 3259543; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.OsuMania); - assert.equal(b.mode, "mania"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "Hanshoku-ki (Cut Ver.)"); - }); - - it("fetch converted taiko map", async () => { - const mapid = 3182198; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, true); - assert.equal(b.mode, "taiko"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "aquamarine"); - }); - - it("fail to fetch taiko map", async () => { - const mapid = 3182198; - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); - } else { - assert.fail(); - } - } - }); - - it("fail to fetch osu map", async () => { - const mapid = 2938202; - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Osu); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); - } else { - assert.fail(); - } - } - }); - - it("cache test", async () => { - const mapid = 3182198; - BeatmapRepository.maps.clear(); - const b1 = await BeatmapRepository.getBeatmap(mapid); - assert.equal(BeatmapRepository.maps.get(BeatmapRepository.genKey(mapid, PlayMode.Osu)), b1) - const b2 = await BeatmapRepository.getBeatmap(mapid); - assert.equal(b1, b2); - }) - }); - - describe.skip("fetch beatmap form api tests", () => { - before(function () { - BeatmapRepository.fetcher = WebApiClient; - }); - after(function () { - BeatmapRepository.fetcher = BeatmapRepository.websiteFetcher; - }); - - it("fetch osu map", async () => { - const mapid = 3182198; - const b = await BeatmapRepository.getBeatmap(mapid); - assert.equal(b.mode, "osu"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "aquamarine"); - }); - - it("fetch invalid map id", async () => { - const mapid = 737157; - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.NotFound); - } else { - assert.fail(); - } - } - }); - - it("fetch taiko map", async () => { - const mapid = 2938202; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); - assert.equal(b.mode, "taiko"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "The Old Blood"); - }); - - it("fetch fruits map", async () => { - const mapid = 3175483; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.CatchTheBeat); - assert.equal(b.mode, "fruits"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "Otter Pop (feat. Hollis)"); - }); - - it("fetch mania map", async () => { - const mapid = 3259543; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.OsuMania); - assert.equal(b.mode, "mania"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "Hanshoku-ki (Cut Ver.)"); - }); - - it("fetch converted taiko map", async () => { - const mapid = 3182198; - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, true); - assert.equal(b.mode, "taiko"); - assert.equal(b.id, mapid); - assert.equal(b.beatmapset?.title, "aquamarine"); - }); - - it("fail to fetch taiko map", async () => { - const mapid = 3182198; - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); - } else { - assert.fail(); - } - } - }); - - it("fail to fetch osu map", async () => { - const mapid = 2938202; - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Osu); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); - } else { - assert.fail(); - } - } - }); - - it("cache test", async () => { - const mapid = 3182198; - BeatmapRepository.maps.clear(); - const b1 = await BeatmapRepository.getBeatmap(mapid); - assert.equal(BeatmapRepository.maps.get(BeatmapRepository.genKey(mapid, PlayMode.Osu)), b1) - const b2 = await BeatmapRepository.getBeatmap(mapid); - assert.equal(b1, b2); - }) - }); - - describe("fetch beatmap form fakes tests", () => { - const originalFetcher = BeatmapRepository.fetcher; - const fakeFetcher = new FakeBeatmapFetcher(); - before(function () { - BeatmapRepository.fetcher = fakeFetcher; - }); - after(function () { - BeatmapRepository.fetcher = originalFetcher; - }); - - it("fetch osu map", async () => { - const mapid = 3182198; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.Osu, 100, 5); - const b = await BeatmapRepository.getBeatmap(mapid); - assert.equal(b.mode, "osu"); - assert.equal(b.id, mapid); - }); - - it("fetch invalid map id", async () => { - const mapid = 1000; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.Osu, 100, 5); - try { - const b = await BeatmapRepository.getBeatmap(500, PlayMode.Taiko); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.NotFound); - } else { - assert.fail(); - } - } - }); - - it("fetch taiko map", async () => { - const mapid = 2938202; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.Taiko, 100, 5); - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); - assert.equal(b.mode, "taiko"); - assert.equal(b.id, mapid); - }); - - it("fetch fruits map", async () => { - const mapid = 3175483; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.CatchTheBeat, 100, 5); - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.CatchTheBeat, false); - assert.equal(b.mode, "fruits"); - assert.equal(b.id, mapid); - }); - - it("fetch mania map", async () => { - const mapid = 3259543; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.OsuMania, 100, 5); - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.OsuMania, false); - assert.equal(b.mode, "mania"); - assert.equal(b.id, mapid); - }); - - it("fetch converted taiko map", async () => { - const mapid = 3182198; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.Osu, 100, 5); - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, true); - assert.equal(b.mode, "taiko"); - assert.equal(b.id, mapid); - }); - - it("fail to fetch taiko map", async () => { - const mapid = 3182198; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.Osu, 100, 5); - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); - } else { - assert.fail(); - } - } - }); - - it("fail to fetch osu map", async () => { - const mapid = 2938202; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.Taiko, 100, 5); - try { - const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Osu); - assert.fail(); - } catch (e: any) { - if (e instanceof FetchBeatmapError) { - assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); - } else { - assert.fail(); - } - } - }); + }); + + it('fetch osu map', async () => { + const mapid = 3182198; + const b = await BeatmapRepository.getBeatmap(mapid); + assert.equal(b.mode, 'osu'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'aquamarine'); + }); + + it('fetch invalid map id', async () => { + const mapid = 737157; + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.NotFound); + } else { + assert.fail(); + } + } + }); + + it('fetch taiko map', async () => { + const mapid = 2938202; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); + assert.equal(b.mode, 'taiko'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'The Old Blood'); + }); + + it('fetch fruits map', async () => { + const mapid = 3175483; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.CatchTheBeat); + assert.equal(b.mode, 'fruits'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'Otter Pop (feat. Hollis)'); + }); + + it('fetch mania map', async () => { + const mapid = 3259543; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.OsuMania); + assert.equal(b.mode, 'mania'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'Hanshoku-ki (Cut Ver.)'); + }); + + it('fetch converted taiko map', async () => { + const mapid = 3182198; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, true); + assert.equal(b.mode, 'taiko'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'aquamarine'); + }); + + it('fail to fetch taiko map', async () => { + const mapid = 3182198; + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); + } else { + assert.fail(); + } + } + }); + + it('fail to fetch osu map', async () => { + const mapid = 2938202; + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Osu); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); + } else { + assert.fail(); + } + } + }); + + it('cache test', async () => { + const mapid = 3182198; + BeatmapRepository.maps.clear(); + const b1 = await BeatmapRepository.getBeatmap(mapid); + assert.equal(BeatmapRepository.maps.get(BeatmapRepository.genKey(mapid, PlayMode.Osu)), b1); + const b2 = await BeatmapRepository.getBeatmap(mapid); + assert.equal(b1, b2); + }); + }); + + describe.skip('fetch beatmap form api tests', () => { + before(function () { + BeatmapRepository.fetcher = WebApiClient; + }); + after(function () { + BeatmapRepository.fetcher = BeatmapRepository.websiteFetcher; + }); + + it('fetch osu map', async () => { + const mapid = 3182198; + const b = await BeatmapRepository.getBeatmap(mapid); + assert.equal(b.mode, 'osu'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'aquamarine'); + }); + + it('fetch invalid map id', async () => { + const mapid = 737157; + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.NotFound); + } else { + assert.fail(); + } + } + }); + + it('fetch taiko map', async () => { + const mapid = 2938202; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko); + assert.equal(b.mode, 'taiko'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'The Old Blood'); + }); + + it('fetch fruits map', async () => { + const mapid = 3175483; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.CatchTheBeat); + assert.equal(b.mode, 'fruits'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'Otter Pop (feat. Hollis)'); + }); + + it('fetch mania map', async () => { + const mapid = 3259543; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.OsuMania); + assert.equal(b.mode, 'mania'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'Hanshoku-ki (Cut Ver.)'); + }); + + it('fetch converted taiko map', async () => { + const mapid = 3182198; + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, true); + assert.equal(b.mode, 'taiko'); + assert.equal(b.id, mapid); + assert.equal(b.beatmapset?.title, 'aquamarine'); + }); + + it('fail to fetch taiko map', async () => { + const mapid = 3182198; + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); + } else { + assert.fail(); + } + } + }); + + it('fail to fetch osu map', async () => { + const mapid = 2938202; + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Osu); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); + } else { + assert.fail(); + } + } + }); + + it('cache test', async () => { + const mapid = 3182198; + BeatmapRepository.maps.clear(); + const b1 = await BeatmapRepository.getBeatmap(mapid); + assert.equal(BeatmapRepository.maps.get(BeatmapRepository.genKey(mapid, PlayMode.Osu)), b1); + const b2 = await BeatmapRepository.getBeatmap(mapid); + assert.equal(b1, b2); + }); + }); + + describe('fetch beatmap form fakes tests', () => { + const originalFetcher = BeatmapRepository.fetcher; + const fakeFetcher = new FakeBeatmapFetcher(); + before(function () { + BeatmapRepository.fetcher = fakeFetcher; + }); + after(function () { + BeatmapRepository.fetcher = originalFetcher; + }); + + it('fetch osu map', async () => { + const mapid = 3182198; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.Osu, 100, 5); + const b = await BeatmapRepository.getBeatmap(mapid); + assert.equal(b.mode, 'osu'); + assert.equal(b.id, mapid); + }); + + it('fetch invalid map id', async () => { + const mapid = 1000; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.Osu, 100, 5); + try { + const b = await BeatmapRepository.getBeatmap(500, PlayMode.Taiko); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.NotFound); + } else { + assert.fail(); + } + } + }); + + it('fetch taiko map', async () => { + const mapid = 2938202; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.Taiko, 100, 5); + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); + assert.equal(b.mode, 'taiko'); + assert.equal(b.id, mapid); + }); + + it('fetch fruits map', async () => { + const mapid = 3175483; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.CatchTheBeat, 100, 5); + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.CatchTheBeat, false); + assert.equal(b.mode, 'fruits'); + assert.equal(b.id, mapid); + }); + + it('fetch mania map', async () => { + const mapid = 3259543; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.OsuMania, 100, 5); + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.OsuMania, false); + assert.equal(b.mode, 'mania'); + assert.equal(b.id, mapid); + }); + + it('fetch converted taiko map', async () => { + const mapid = 3182198; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.Osu, 100, 5); + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, true); + assert.equal(b.mode, 'taiko'); + assert.equal(b.id, mapid); + }); + + it('fail to fetch taiko map', async () => { + const mapid = 3182198; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.Osu, 100, 5); + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Taiko, false); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); + } else { + assert.fail(); + } + } + }); + it('fail to fetch osu map', async () => { + const mapid = 2938202; + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.Taiko, 100, 5); + try { + const b = await BeatmapRepository.getBeatmap(mapid, PlayMode.Osu); + assert.fail(); + } catch (e: any) { + if (e instanceof FetchBeatmapError) { + assert.equal(e.reason, FetchBeatmapErrorReason.PlayModeMismatched); + } else { + assert.fail(); + } + } }); + + }); }); diff --git a/src/tests/CommandParserTest.ts b/src/tests/CommandParserTest.ts index 44a7e68e..074e350b 100644 --- a/src/tests/CommandParserTest.ts +++ b/src/tests/CommandParserTest.ts @@ -3,472 +3,472 @@ import { Teams } from '../Player'; import { parser, BanchoResponseType } from '../parsers/CommandParser'; import log4js from 'log4js'; -describe("CommandParserTest", function () { +describe('CommandParserTest', function () { before(function () { - log4js.configure("config/log_mocha_silent.json"); + log4js.configure('config/log_mocha_silent.json'); }); - it("make lobby message parse test", () => { - let message = "Created the tournament match https://osu.ppy.sh/mp/52612489 irctestroom"; - let v = parser.ParseMpMakeResponse("BanchoBot", message); + it('make lobby message parse test', () => { + let message = 'Created the tournament match https://osu.ppy.sh/mp/52612489 irctestroom'; + let v = parser.ParseMpMakeResponse('BanchoBot', message); assert.isNotNull(v); if (v == null) { assert.fail(); } else { - assert.equal(v.id, "52612489"); - assert.equal(v.title, "irctestroom"); + assert.equal(v.id, '52612489'); + assert.equal(v.title, 'irctestroom'); } - message = "Created the tournament match https://osu.ppy.sh/mp/52849259 irctest_room^^"; - v = parser.ParseMpMakeResponse("BanchoBot", message); + message = 'Created the tournament match https://osu.ppy.sh/mp/52849259 irctest_room^^'; + v = parser.ParseMpMakeResponse('BanchoBot', message); if (v == null) { assert.fail(); } else { - assert.equal(v.id, "52849259"); - assert.equal(v.title, "irctest_room^^"); + assert.equal(v.id, '52849259'); + assert.equal(v.title, 'irctest_room^^'); } - message = "Created the tournament match https://osu.ppy.sh/mp/52849326 irc test room 1"; - v = parser.ParseMpMakeResponse("BanchoBot", message); + message = 'Created the tournament match https://osu.ppy.sh/mp/52849326 irc test room 1'; + v = parser.ParseMpMakeResponse('BanchoBot', message); if (v == null) { assert.fail(); } else { - assert.equal(v.id, "52849326"); - assert.equal(v.title, "irc test room 1"); + assert.equal(v.id, '52849326'); + assert.equal(v.title, 'irc test room 1'); } }); - it("ParseMPCommandTest", () => { - let message = "!mp host xxx"; + it('ParseMPCommandTest', () => { + let message = '!mp host xxx'; let v = parser.ParseMPCommand(message); if (v == null) { assert.fail(); } else { - assert.equal(v.command, "host"); - assert.equal(v.arg, "xxx"); + assert.equal(v.command, 'host'); + assert.equal(v.arg, 'xxx'); } - message = "!mp make xxx"; + message = '!mp make xxx'; v = parser.ParseMPCommand(message); if (v == null) { assert.fail(); } else { - assert.equal(v.command, "make"); - assert.equal(v.arg, "xxx"); + assert.equal(v.command, 'make'); + assert.equal(v.arg, 'xxx'); } - message = "xx!mp make xxx"; + message = 'xx!mp make xxx'; v = parser.ParseMPCommand(message); if (v != null) { assert.fail(); } }); - describe("ParseBanchoResponse tests", () => { - it("player joined parse test", () => { - let message = "Swgciai joined in slot 4."; + describe('ParseBanchoResponse tests', () => { + it('player joined parse test', () => { + let message = 'Swgciai joined in slot 4.'; let v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerJoined); - assert.equal(v.params[0], "Swgciai"); + assert.equal(v.params[0], 'Swgciai'); assert.equal(v.params[1], 4); assert.equal(v.params[2], Teams.None); - message = "Foet_Mnagyo joined in slot 1."; + message = 'Foet_Mnagyo joined in slot 1.'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerJoined); - assert.equal(v.params[0], "Foet_Mnagyo"); + assert.equal(v.params[0], 'Foet_Mnagyo'); assert.equal(v.params[1], 1); assert.equal(v.params[2], Teams.None); - message = "- Cylcl joined in slot 5."; + message = '- Cylcl joined in slot 5.'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerJoined); - assert.equal(v.params[0], "- Cylcl"); + assert.equal(v.params[0], '- Cylcl'); assert.equal(v.params[1], 5); assert.equal(v.params[2], Teams.None); }); - it("player joined team mode test", () => { - let v = parser.ParseBanchoResponse("Cartist joined in slot 7 for team blue."); + it('player joined team mode test', () => { + let v = parser.ParseBanchoResponse('Cartist joined in slot 7 for team blue.'); assert.equal(v.type, BanchoResponseType.PlayerJoined); - assert.equal(v.params[0], "Cartist"); + assert.equal(v.params[0], 'Cartist'); assert.equal(v.params[1], 7); assert.equal(v.params[2], Teams.Blue); - v = parser.ParseBanchoResponse("hmelevsky joined in slot 8 for team red."); + v = parser.ParseBanchoResponse('hmelevsky joined in slot 8 for team red.'); assert.equal(v.type, BanchoResponseType.PlayerJoined); - assert.equal(v.params[0], "hmelevsky"); + assert.equal(v.params[0], 'hmelevsky'); assert.equal(v.params[1], 8); assert.equal(v.params[2], Teams.Red); - v = parser.ParseBanchoResponse("Xiux joined in slot 2 for team red."); + v = parser.ParseBanchoResponse('Xiux joined in slot 2 for team red.'); assert.equal(v.type, BanchoResponseType.PlayerJoined); - assert.equal(v.params[0], "Xiux"); + assert.equal(v.params[0], 'Xiux'); assert.equal(v.params[1], 2); assert.equal(v.params[2], Teams.Red); }); - it("player left parse test", () => { - let message = "Swgciai left the game."; + it('player left parse test', () => { + let message = 'Swgciai left the game.'; let v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerLeft); - assert.equal(v.params[0], "Swgciai"); + assert.equal(v.params[0], 'Swgciai'); - message = "Foet_Mnagyo left the game."; + message = 'Foet_Mnagyo left the game.'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerLeft); - assert.equal(v.params[0], "Foet_Mnagyo"); + assert.equal(v.params[0], 'Foet_Mnagyo'); - message = "- Cylcl left the game."; + message = '- Cylcl left the game.'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerLeft); - assert.equal(v.params[0], "- Cylcl"); + assert.equal(v.params[0], '- Cylcl'); }); - it("map changing test", () => { - let message = "Host is changing map..."; - let v = parser.ParseBanchoResponse(message); + it('map changing test', () => { + const message = 'Host is changing map...'; + const v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.BeatmapChanging); }); - it("map changed test", () => { - let message = "Beatmap changed to: Noah - Celestial stinger [apl's EXHAUST] (https://osu.ppy.sh/b/1454083)"; + it('map changed test', () => { + let message = 'Beatmap changed to: Noah - Celestial stinger [apl\'s EXHAUST] (https://osu.ppy.sh/b/1454083)'; let v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.BeatmapChanged); - assert.equal(v.params[0], "1454083"); + assert.equal(v.params[0], '1454083'); - message = "Beatmap changed to: Paul Bazooka - DrunkenSteiN [bor's Insane] (https://osu.ppy.sh/b/1913126)"; + message = 'Beatmap changed to: Paul Bazooka - DrunkenSteiN [bor\'s Insane] (https://osu.ppy.sh/b/1913126)'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.BeatmapChanged); - assert.equal(v.params[0], "1913126"); + assert.equal(v.params[0], '1913126'); - message = "Beatmap changed to: supercell - Hoshi ga Matataku Konna Yoru ni [Sharlo's Insane] (https://osu.ppy.sh/b/670743)"; + message = 'Beatmap changed to: supercell - Hoshi ga Matataku Konna Yoru ni [Sharlo\'s Insane] (https://osu.ppy.sh/b/670743)'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.BeatmapChanged); - assert.equal(v.params[0], "670743"); + assert.equal(v.params[0], '670743'); - message = "Beatmap changed to: Lil Boom - \"Already Dead \" instrumental (Omae Wa Mou) (https://osu.ppy.sh/b/2122318)"; + message = 'Beatmap changed to: Lil Boom - "Already Dead " instrumental (Omae Wa Mou) (https://osu.ppy.sh/b/2122318)'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.BeatmapChanged); - assert.equal(v.params[0], "2122318"); + assert.equal(v.params[0], '2122318'); }); - it("mp map changed test", () => { - let message = "Changed beatmap to https://osu.ppy.sh/b/2145701 Camellia feat. Nanahira - NANI THE FUCK!!"; - let v = parser.ParseBanchoResponse(message); + it('mp map changed test', () => { + const message = 'Changed beatmap to https://osu.ppy.sh/b/2145701 Camellia feat. Nanahira - NANI THE FUCK!!'; + const v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.MpBeatmapChanged); - assert.equal(v.params[0], "2145701"); + assert.equal(v.params[0], '2145701'); }); - it("mpInvalidMapId test", () => { - let message = "Invalid map ID provided"; - let v = parser.ParseBanchoResponse(message); + it('mpInvalidMapId test', () => { + const message = 'Invalid map ID provided'; + const v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.MpInvalidMapId); }); - it("host change test", () => { - let message = "Swgciai became the host."; + it('host change test', () => { + let message = 'Swgciai became the host.'; let v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.HostChanged); - assert.equal(v.params[0], "Swgciai"); + assert.equal(v.params[0], 'Swgciai'); - message = "Foet_Mnagyo became the host."; + message = 'Foet_Mnagyo became the host.'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.HostChanged); - assert.equal(v.params[0], "Foet_Mnagyo"); + assert.equal(v.params[0], 'Foet_Mnagyo'); - message = "- Cylcl became the host."; + message = '- Cylcl became the host.'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.HostChanged); - assert.equal(v.params[0], "- Cylcl"); + assert.equal(v.params[0], '- Cylcl'); }); - it("match test", () => { - let v = parser.ParseBanchoResponse("The match has started!"); + it('match test', () => { + let v = parser.ParseBanchoResponse('The match has started!'); assert.equal(v.type, BanchoResponseType.MatchStarted); - let message = "Swgciai finished playing (Score: 18048202, PASSED)."; + let message = 'Swgciai finished playing (Score: 18048202, PASSED).'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerFinished); - assert.equal(v.params[0], "Swgciai"); + assert.equal(v.params[0], 'Swgciai'); assert.equal(v.params[1], 18048202); assert.equal(v.params[2], true); - message = "Foet_Mnagyo finished playing (Score: 290043, FAILED)."; + message = 'Foet_Mnagyo finished playing (Score: 290043, FAILED).'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerFinished); - assert.equal(v.params[0], "Foet_Mnagyo"); + assert.equal(v.params[0], 'Foet_Mnagyo'); assert.equal(v.params[1], 290043); assert.equal(v.params[2], false); - message = "- Cylcl finished playing (Score: 2095838, PASSED)."; + message = '- Cylcl finished playing (Score: 2095838, PASSED).'; v = parser.ParseBanchoResponse(message); assert.equal(v.type, BanchoResponseType.PlayerFinished); - assert.equal(v.params[0], "- Cylcl"); + assert.equal(v.params[0], '- Cylcl'); assert.equal(v.params[1], 2095838); assert.equal(v.params[2], true); - v = parser.ParseBanchoResponse("The match has finished!"); + v = parser.ParseBanchoResponse('The match has finished!'); assert.equal(v.type, BanchoResponseType.MatchFinished); - v = parser.ParseBanchoResponse("Closed the match"); + v = parser.ParseBanchoResponse('Closed the match'); assert.equal(v.type, BanchoResponseType.ClosedMatch); }); - it("match abort test", () => { - let v = parser.ParseBanchoResponse("Aborted the match"); + it('match abort test', () => { + let v = parser.ParseBanchoResponse('Aborted the match'); assert.equal(v.type, BanchoResponseType.AbortedMatch); - v = parser.ParseBanchoResponse("The match is not in progress"); + v = parser.ParseBanchoResponse('The match is not in progress'); assert.equal(v.type, BanchoResponseType.AbortMatchFailed); }); - it("PlayerMovedSlot test", () => { - let v = parser.ParseBanchoResponse("azi03 moved to slot 6"); + it('PlayerMovedSlot test', () => { + const v = parser.ParseBanchoResponse('azi03 moved to slot 6'); assert.equal(v.type, BanchoResponseType.PlayerMovedSlot); - assert.equal(v.params[0], "azi03"); + assert.equal(v.params[0], 'azi03'); assert.equal(v.params[1], 6); }); - it("MpHostChanged test", () => { - let v = parser.ParseBanchoResponse("Changed match host to Brena_Pia"); + it('MpHostChanged test', () => { + const v = parser.ParseBanchoResponse('Changed match host to Brena_Pia'); assert.equal(v.type, BanchoResponseType.MpHostChanged); - assert.equal(v.params[0], "Brena_Pia"); + assert.equal(v.params[0], 'Brena_Pia'); }); - it("MpMatchStarted test", () => { - let v = parser.ParseBanchoResponse("Started the match"); + it('MpMatchStarted test', () => { + const v = parser.ParseBanchoResponse('Started the match'); assert.equal(v.type, BanchoResponseType.MpMatchStarted); }); - it("MpMatchAlreadyStarted test", () => { - let v = parser.ParseBanchoResponse("The match has already been started"); + it('MpMatchAlreadyStarted test', () => { + const v = parser.ParseBanchoResponse('The match has already been started'); assert.equal(v.type, BanchoResponseType.MpMatchAlreadyStarted); }); - it("PasswordChanged test", () => { - let v = parser.ParseBanchoResponse("Changed the match password"); + it('PasswordChanged test', () => { + const v = parser.ParseBanchoResponse('Changed the match password'); assert.equal(v.type, BanchoResponseType.PasswordChanged); }); - it("PasswordRemoved test", () => { - let v = parser.ParseBanchoResponse("Removed the match password"); + it('PasswordRemoved test', () => { + const v = parser.ParseBanchoResponse('Removed the match password'); assert.equal(v.type, BanchoResponseType.PasswordRemoved); }); - it("AddedReferee test", () => { - let v = parser.ParseBanchoResponse("Added damn to the match referees"); + it('AddedReferee test', () => { + const v = parser.ParseBanchoResponse('Added damn to the match referees'); assert.equal(v.type, BanchoResponseType.AddedReferee); - assert.equal(v.params[0], "damn"); + assert.equal(v.params[0], 'damn'); }); - it("RemovedReferee test", () => { - let v = parser.ParseBanchoResponse("Removed damn from the match referees"); + it('RemovedReferee test', () => { + const v = parser.ParseBanchoResponse('Removed damn from the match referees'); assert.equal(v.type, BanchoResponseType.RemovedReferee); - assert.equal(v.params[0], "damn"); + assert.equal(v.params[0], 'damn'); }); - it("kick player test", () => { - let v = parser.ParseBanchoResponse("Kicked damn from the match"); + it('kick player test', () => { + const v = parser.ParseBanchoResponse('Kicked damn from the match'); assert.equal(v.type, BanchoResponseType.KickedPlayer); - assert.equal(v.params[0], "damn"); + assert.equal(v.params[0], 'damn'); }); - it("CountedTimer test", () => { - let v = parser.ParseBanchoResponse("Match starts in 10 seconds"); + it('CountedTimer test', () => { + let v = parser.ParseBanchoResponse('Match starts in 10 seconds'); assert.equal(v.type, BanchoResponseType.CounteddownTimer); assert.equal(v.params[0], 10); - v = parser.ParseBanchoResponse("Match starts in 2 minutes and 40 seconds"); + v = parser.ParseBanchoResponse('Match starts in 2 minutes and 40 seconds'); assert.equal(v.type, BanchoResponseType.CounteddownTimer); assert.equal(v.params[0], 160); - v = parser.ParseBanchoResponse("Match starts in 2 minutes"); + v = parser.ParseBanchoResponse('Match starts in 2 minutes'); assert.equal(v.type, BanchoResponseType.CounteddownTimer); assert.equal(v.params[0], 120); - v = parser.ParseBanchoResponse("Match starts in 1 minute and 1 second"); + v = parser.ParseBanchoResponse('Match starts in 1 minute and 1 second'); assert.equal(v.type, BanchoResponseType.CounteddownTimer); assert.equal(v.params[0], 61); }); - it("BeganStartTimer test", () => { - let v = parser.ParseBanchoResponse("Queued the match to start in 30 seconds"); + it('BeganStartTimer test', () => { + let v = parser.ParseBanchoResponse('Queued the match to start in 30 seconds'); assert.equal(v.type, BanchoResponseType.BeganStartTimer); assert.equal(v.params[0], 30); - v = parser.ParseBanchoResponse("Queued the match to start in 1 second"); + v = parser.ParseBanchoResponse('Queued the match to start in 1 second'); assert.equal(v.type, BanchoResponseType.BeganStartTimer); assert.equal(v.params[0], 1); - v = parser.ParseBanchoResponse("Queued the match to start in 5 minutes and 40 seconds"); + v = parser.ParseBanchoResponse('Queued the match to start in 5 minutes and 40 seconds'); assert.equal(v.type, BanchoResponseType.BeganStartTimer); assert.equal(v.params[0], 340); }); - it("FinishStartTimer test", () => { - let v = parser.ParseBanchoResponse("Good luck, have fun!"); + it('FinishStartTimer test', () => { + const v = parser.ParseBanchoResponse('Good luck, have fun!'); assert.equal(v.type, BanchoResponseType.FinishStartTimer); }); - it("AbortedStartTimer test", () => { - let v = parser.ParseBanchoResponse("Countdown aborted"); + it('AbortedStartTimer test', () => { + const v = parser.ParseBanchoResponse('Countdown aborted'); assert.equal(v.type, BanchoResponseType.AbortedStartTimer); }); - it("mp settings test", () => { - let v = parser.ParseBanchoResponse("Room name: 4* auto host rotation test, History: https://osu.ppy.sh/mp/xxxxxxx"); + it('mp settings test', () => { + let v = parser.ParseBanchoResponse('Room name: 4* auto host rotation test, History: https://osu.ppy.sh/mp/xxxxxxx'); assert.equal(v.type, BanchoResponseType.Settings); - v = parser.ParseBanchoResponse("Beatmap: https://osu.ppy.sh/b/xxxxxx DJ Genericname - Dear You [Dear Rue]"); + v = parser.ParseBanchoResponse('Beatmap: https://osu.ppy.sh/b/xxxxxx DJ Genericname - Dear You [Dear Rue]'); assert.equal(v.type, BanchoResponseType.Settings); - v = parser.ParseBanchoResponse("Team mode: HeadToHead, Win condition: Score"); + v = parser.ParseBanchoResponse('Team mode: HeadToHead, Win condition: Score'); assert.equal(v.type, BanchoResponseType.Settings); - v = parser.ParseBanchoResponse("Active mods: Freemod"); + v = parser.ParseBanchoResponse('Active mods: Freemod'); assert.equal(v.type, BanchoResponseType.Settings); - v = parser.ParseBanchoResponse("Players: 2"); + v = parser.ParseBanchoResponse('Players: 2'); assert.equal(v.type, BanchoResponseType.Settings); - v = parser.ParseBanchoResponse("Slot 1 Not Ready https://osu.ppy.sh/u/xxxxxxxx xxxx [Host]"); + v = parser.ParseBanchoResponse('Slot 1 Not Ready https://osu.ppy.sh/u/xxxxxxxx xxxx [Host]'); assert.equal(v.type, BanchoResponseType.Settings); }); - it("roll test", () => { - let v = parser.ParseBanchoResponse("Natu rolls 13 point(s)"); + it('roll test', () => { + let v = parser.ParseBanchoResponse('Natu rolls 13 point(s)'); assert.equal(v.type, BanchoResponseType.Rolled); - assert.equal(v.params[0], "Natu"); + assert.equal(v.params[0], 'Natu'); assert.equal(v.params[1], 13); - v = parser.ParseBanchoResponse("gurdil203 rolls 1 point(s)"); + v = parser.ParseBanchoResponse('gurdil203 rolls 1 point(s)'); assert.equal(v.type, BanchoResponseType.Rolled); - assert.equal(v.params[0], "gurdil203"); + assert.equal(v.params[0], 'gurdil203'); assert.equal(v.params[1], 1); - v = parser.ParseBanchoResponse("DAE rolls rolls 46 point(s)"); + v = parser.ParseBanchoResponse('DAE rolls rolls 46 point(s)'); assert.equal(v.type, BanchoResponseType.Rolled); - assert.equal(v.params[0], "DAE rolls"); + assert.equal(v.params[0], 'DAE rolls'); assert.equal(v.params[1], 46); }); - it("stats test", () => { - let v = parser.ParseBanchoResponse("Stats for (DAEVOTAKU)[https://osu.ppy.sh/u/10933699] is Multiplayer:"); + it('stats test', () => { + let v = parser.ParseBanchoResponse('Stats for (DAEVOTAKU)[https://osu.ppy.sh/u/10933699] is Multiplayer:'); assert.equal(v.type, BanchoResponseType.Stats); - v = parser.ParseBanchoResponse("Score: 906,297,690 (#203086)"); + v = parser.ParseBanchoResponse('Score: 906,297,690 (#203086)'); assert.equal(v.type, BanchoResponseType.Stats); - v = parser.ParseBanchoResponse("Plays: 3874 (lv76)"); + v = parser.ParseBanchoResponse('Plays: 3874 (lv76)'); assert.equal(v.type, BanchoResponseType.Stats); - v = parser.ParseBanchoResponse("Accuracy: 90.06%"); + v = parser.ParseBanchoResponse('Accuracy: 90.06%'); assert.equal(v.type, BanchoResponseType.Stats); }); - it("team change test", () => { - let v = parser.ParseBanchoResponse("a6387534 changed to Red"); + it('team change test', () => { + let v = parser.ParseBanchoResponse('a6387534 changed to Red'); assert.equal(v.type, BanchoResponseType.TeamChanged); - assert.equal(v.params[0], "a6387534"); + assert.equal(v.params[0], 'a6387534'); assert.equal(v.params[1], Teams.Red); - v = parser.ParseBanchoResponse("milisaurus changed to Blue"); + v = parser.ParseBanchoResponse('milisaurus changed to Blue'); assert.equal(v.type, BanchoResponseType.TeamChanged); - assert.equal(v.params[0], "milisaurus"); + assert.equal(v.params[0], 'milisaurus'); assert.equal(v.params[1], Teams.Blue); }); - it("lobby size changed test", () => { - let v = parser.ParseBanchoResponse("Changed match to size 8"); + it('lobby size changed test', () => { + let v = parser.ParseBanchoResponse('Changed match to size 8'); assert.equal(v.type, BanchoResponseType.LobbySizeChanged); assert.equal(v.params[0], 8); - v = parser.ParseBanchoResponse("Changed match to size 16"); + v = parser.ParseBanchoResponse('Changed match to size 16'); assert.equal(v.type, BanchoResponseType.LobbySizeChanged); assert.equal(v.params[0], 16); }); }); - it("ensure channel test", () => { - let v = parser.EnsureMpChannelId("123"); - assert.equal(v, "#mp_123"); + it('ensure channel test', () => { + let v = parser.EnsureMpChannelId('123'); + assert.equal(v, '#mp_123'); - v = parser.EnsureMpChannelId("#mp_123"); - assert.equal(v, "#mp_123"); + v = parser.EnsureMpChannelId('#mp_123'); + assert.equal(v, '#mp_123'); - v = parser.EnsureMpChannelId("https://osu.ppy.sh/mp/123"); - assert.equal(v, "#mp_123"); + v = parser.EnsureMpChannelId('https://osu.ppy.sh/mp/123'); + assert.equal(v, '#mp_123'); }); - it("SplitCliCommand test", () => { - let v = parser.SplitCliCommand("a abcdefg"); - assert.equal(v.command, "a"); - assert.equal(v.arg, "abcdefg"); + it('SplitCliCommand test', () => { + let v = parser.SplitCliCommand('a abcdefg'); + assert.equal(v.command, 'a'); + assert.equal(v.arg, 'abcdefg'); - v = parser.SplitCliCommand("a b c"); - assert.equal(v.command, "a"); - assert.equal(v.arg, "b c"); + v = parser.SplitCliCommand('a b c'); + assert.equal(v.command, 'a'); + assert.equal(v.arg, 'b c'); - v = parser.SplitCliCommand("a"); - assert.equal(v.command, "a"); - assert.equal(v.arg, ""); + v = parser.SplitCliCommand('a'); + assert.equal(v.command, 'a'); + assert.equal(v.arg, ''); }); - describe("parse chat command tests", function () { - it("IsChatCommand?", () => { - const valids = ["!aioie", "!a", "!123", "!a ", "!v x", "!vv x y[v]", "*abc"]; - const invalids = ["!", "*", " !asa", "!!ss", "*!v", "abc", "abc !abc"]; - const used = ["!help", "!Help", "!info", "!skip", "!SKIP", "!queue", "!q", "*skip", "*stipto"]; - const reservedInvalid = ["!mp", "!roll", "!roll 100", "!where abc", "!faq", "!report", "!request", "!stat", "!stats"]; - const mpredirect = ["!mp x", "!mp start", "!mp start 20"]; + describe('parse chat command tests', function () { + it('IsChatCommand?', () => { + const valids = ['!aioie', '!a', '!123', '!a ', '!v x', '!vv x y[v]', '*abc']; + const invalids = ['!', '*', ' !asa', '!!ss', '*!v', 'abc', 'abc !abc']; + const used = ['!help', '!Help', '!info', '!skip', '!SKIP', '!queue', '!q', '*skip', '*stipto']; + const reservedInvalid = ['!mp', '!roll', '!roll 100', '!where abc', '!faq', '!report', '!request', '!stat', '!stats']; + const mpredirect = ['!mp x', '!mp start', '!mp start 20']; valids.forEach(c => assert.isTrue(parser.IsChatCommand(c), c)); invalids.forEach(c => assert.isFalse(parser.IsChatCommand(c), c)); used.forEach(c => assert.isTrue(parser.IsChatCommand(c), c)); reservedInvalid.forEach(c => assert.isFalse(parser.IsChatCommand(c), c)); mpredirect.forEach(c => assert.isTrue(parser.IsChatCommand(c), c)); }); - it("ParseChatCommand", () => { - let v = parser.ParseChatCommand("!abc"); - assert.equal(v.command, "!abc"); - assert.equal(v.param, ""); - - v = parser.ParseChatCommand("!a a"); - assert.equal(v.command, "!a"); - assert.equal(v.param, "a"); - - v = parser.ParseChatCommand("!a a "); - assert.equal(v.command, "!a"); - assert.equal(v.param, "a"); - - v = parser.ParseChatCommand("!a a b"); - assert.equal(v.command, "!a"); - assert.equal(v.param, "a b"); - - v = parser.ParseChatCommand("!a a b "); - assert.equal(v.command, "!a"); - assert.equal(v.param, "a b"); - }); - it("Case insensitive check", () => { - assert.isTrue(parser.IsChatCommand("!abc")); - let v = parser.ParseChatCommand("!abc"); - assert.equal(v.command, "!abc"); - assert.equal(v.param, ""); - - assert.isTrue(parser.IsChatCommand("!Abc")); - v = parser.ParseChatCommand("!Abc"); - assert.equal(v.command, "!abc"); - assert.equal(v.param, ""); - - assert.isTrue(parser.IsChatCommand("!ABC")); - v = parser.ParseChatCommand("!ABC"); - assert.equal(v.command, "!abc"); - assert.equal(v.param, ""); - - assert.isTrue(parser.IsChatCommand("!AbC aiueo AIUEO")); - v = parser.ParseChatCommand("!AbC aiueo AIUEO"); - assert.equal(v.command, "!abc"); - assert.equal(v.param, "aiueo AIUEO"); - }); - it("!mp redirect", () => { - assert.isFalse(parser.IsChatCommand("!mp")); - assert.isFalse(parser.IsChatCommand("!mp ")); - assert.isTrue(parser.IsChatCommand("!mp start")); - let v = parser.ParseChatCommand("!mp start"); - assert.equal(v.command, "!start"); - assert.equal(v.param, ""); - - assert.isTrue(parser.IsChatCommand("!mp start 30")); - v = parser.ParseChatCommand("!mp start 30"); - assert.equal(v.command, "!start"); - assert.equal(v.param, "30"); - - assert.isTrue(parser.IsChatCommand("!mp start 30 xx ")); - v = parser.ParseChatCommand("!mp start 30 xx "); - assert.equal(v.command, "!start"); - assert.equal(v.param, "30 xx"); + it('ParseChatCommand', () => { + let v = parser.ParseChatCommand('!abc'); + assert.equal(v.command, '!abc'); + assert.equal(v.param, ''); + + v = parser.ParseChatCommand('!a a'); + assert.equal(v.command, '!a'); + assert.equal(v.param, 'a'); + + v = parser.ParseChatCommand('!a a '); + assert.equal(v.command, '!a'); + assert.equal(v.param, 'a'); + + v = parser.ParseChatCommand('!a a b'); + assert.equal(v.command, '!a'); + assert.equal(v.param, 'a b'); + + v = parser.ParseChatCommand('!a a b '); + assert.equal(v.command, '!a'); + assert.equal(v.param, 'a b'); + }); + it('Case insensitive check', () => { + assert.isTrue(parser.IsChatCommand('!abc')); + let v = parser.ParseChatCommand('!abc'); + assert.equal(v.command, '!abc'); + assert.equal(v.param, ''); + + assert.isTrue(parser.IsChatCommand('!Abc')); + v = parser.ParseChatCommand('!Abc'); + assert.equal(v.command, '!abc'); + assert.equal(v.param, ''); + + assert.isTrue(parser.IsChatCommand('!ABC')); + v = parser.ParseChatCommand('!ABC'); + assert.equal(v.command, '!abc'); + assert.equal(v.param, ''); + + assert.isTrue(parser.IsChatCommand('!AbC aiueo AIUEO')); + v = parser.ParseChatCommand('!AbC aiueo AIUEO'); + assert.equal(v.command, '!abc'); + assert.equal(v.param, 'aiueo AIUEO'); + }); + it('!mp redirect', () => { + assert.isFalse(parser.IsChatCommand('!mp')); + assert.isFalse(parser.IsChatCommand('!mp ')); + assert.isTrue(parser.IsChatCommand('!mp start')); + let v = parser.ParseChatCommand('!mp start'); + assert.equal(v.command, '!start'); + assert.equal(v.param, ''); + + assert.isTrue(parser.IsChatCommand('!mp start 30')); + v = parser.ParseChatCommand('!mp start 30'); + assert.equal(v.command, '!start'); + assert.equal(v.param, '30'); + + assert.isTrue(parser.IsChatCommand('!mp start 30 xx ')); + v = parser.ParseChatCommand('!mp start 30 xx '); + assert.equal(v.command, '!start'); + assert.equal(v.param, '30 xx'); }); }); }); diff --git a/src/tests/DummyIrcClientTest.ts b/src/tests/DummyIrcClientTest.ts index 21c0f3d4..d23083d8 100644 --- a/src/tests/DummyIrcClientTest.ts +++ b/src/tests/DummyIrcClientTest.ts @@ -3,21 +3,21 @@ import { DummyIrcClient } from '../dummies/DummyIrcClient'; import { parser, BanchoResponseType } from '../parsers/CommandParser'; import log4js from 'log4js'; -describe("DummyIrcClientTest", function () { +describe('DummyIrcClientTest', function () { before(function () { - log4js.configure("config/log_mocha_silent.json"); + log4js.configure('config/log_mocha_silent.json'); }); // ロビー作成テスト - it("make lobby test", (done) => { - const client = new DummyIrcClient("osu_irc_server", "owner"); - const lobbyTitle = "testlobby"; + it('make lobby test', (done) => { + const client = new DummyIrcClient('osu_irc_server', 'owner'); + const lobbyTitle = 'testlobby'; let f_joined = 0; let f_make_res = 0; let f_registered = 0; //logIrcEvent(client); client.on('registered', function (message) { f_registered++; - client.say("BanchoBot", "!mp make " + lobbyTitle); + client.say('BanchoBot', '!mp make ' + lobbyTitle); }); client.on('pm', function (nick, message) { const v = parser.ParseMpMakeResponse(nick, message); @@ -32,7 +32,7 @@ describe("DummyIrcClientTest", function () { client.on('join', function (channel, who) { f_joined++; setTimeout(() => { - client.say(channel, "!mp close"); + client.say(channel, '!mp close'); }, 10); }); client.on('part', function (channel, who, reason) { @@ -43,19 +43,19 @@ describe("DummyIrcClientTest", function () { }); }); - it("match test", (done) => { - const client = new DummyIrcClient("osu_irc_server", "owner"); - const lobbyTitle = "testlobby"; - const players = ["p1", "p2", "p3"]; + it('match test', (done) => { + const client = new DummyIrcClient('osu_irc_server', 'owner'); + const lobbyTitle = 'testlobby'; + const players = ['p1', 'p2', 'p3']; //logIrcEvent(client); client.on('registered', function (message) { - client.say("BanchoBot", "!mp make " + lobbyTitle); + client.say('BanchoBot', '!mp make ' + lobbyTitle); }); client.on('join', function (channel, who) { players.forEach((v, i, a) => client.emulateAddPlayerAsync(v)); setTimeout(() => { - client.say(channel, "!mp close"); + client.say(channel, '!mp close'); }, 10); }); client.on('part', function (channel, who, reason) { @@ -63,36 +63,36 @@ describe("DummyIrcClientTest", function () { }); }); - it("make noname lobby test", (done) => { - const client = new DummyIrcClient("osu_irc_server", "owner"); + it('make noname lobby test', (done) => { + const client = new DummyIrcClient('osu_irc_server', 'owner'); //logIrcEvent(client); - const lobbyTitle = ""; + const lobbyTitle = ''; client.on('registered', function (message) { - client.say("BanchoBot", "!mp make " + lobbyTitle); + client.say('BanchoBot', '!mp make ' + lobbyTitle); }); client.on('pm', function (nick, message) { - assert.equal(message, "No name provided"); + assert.equal(message, 'No name provided'); done(); }); }); - it("mphost user not found test", (done) => { - const client = new DummyIrcClient("osu_irc_server", "owner"); - const lobbyTitle = "testlobby"; - const players = ["p1", "p2", "p3"]; + it('mphost user not found test', (done) => { + const client = new DummyIrcClient('osu_irc_server', 'owner'); + const lobbyTitle = 'testlobby'; + const players = ['p1', 'p2', 'p3']; //logIrcEvent(client); client.on('registered', function (message) { - client.say("BanchoBot", "!mp make " + lobbyTitle); + client.say('BanchoBot', '!mp make ' + lobbyTitle); }); client.on('join', function (channel, who) { players.forEach((v, i, a) => client.emulateAddPlayerAsync(v)); setTimeout(() => { - client.say(channel, "!mp host p4"); + client.say(channel, '!mp host p4'); }, 10); }); client.on('message', function (from, to, msg) { - let r = parser.ParseBanchoResponse(msg); + const r = parser.ParseBanchoResponse(msg); if (r.type == BanchoResponseType.UserNotFound) { done(); } diff --git a/src/tests/HistoryRepositryTest.ts b/src/tests/HistoryRepositryTest.ts index 93aeb3d8..a7896d85 100644 --- a/src/tests/HistoryRepositryTest.ts +++ b/src/tests/HistoryRepositryTest.ts @@ -4,112 +4,112 @@ import { HistoryRepository } from '../webapi/HistoryRepository'; import { EventType } from '../webapi/HistoryTypes'; import tu from './TestUtils'; -describe("History repositry Tests", () => { +describe('History repositry Tests', () => { before(function () { tu.configMochaAsSilent(); }); - describe("dummy fetcher test", () => { - it("simple fetch test", async () => { + describe('dummy fetcher test', () => { + it('simple fetch test', async () => { const d = new DummyHistoryFetcher(1); - let h1 = await d.fetchHistory(5, null, null); + const h1 = await d.fetchHistory(5, null, null); assert.equal(h1.events.length, 2); assert.equal(h1.users[0].id, 1); - assert.equal(h1.users[0].username, "user1"); + assert.equal(h1.users[0].username, 'user1'); assert.equal(h1.events[0].id, 0); assert.equal(h1.events[1].id, 1); - d.addEvent("player-joined", 2); // event 2 - d.addEvent("player-joined", 3); // event 3 - d.addEvent("player-joined", 4); // event 4 + d.addEvent('player-joined', 2); // event 2 + d.addEvent('player-joined', 3); // event 3 + d.addEvent('player-joined', 4); // event 4 - let h2 = await d.fetchHistory(10, null, null, 0); + const h2 = await d.fetchHistory(10, null, null, 0); assert.equal(h2.events.length, 5); assert.equal(h2.events[0].id, 0); assert.equal(h2.events[1].id, 1); assert.equal(h2.users.length, 4); - assert.equal(h2.users[1].username, "user2"); + assert.equal(h2.users[1].username, 'user2'); }); - it("before test", async () => { + it('before test', async () => { const d = new DummyHistoryFetcher(1); - d.addEvent("player-joined", 2); // event 2 - d.addEvent("player-joined", 3); // event 3 - d.addEvent("player-joined", 4); // event 4 + d.addEvent('player-joined', 2); // event 2 + d.addEvent('player-joined', 3); // event 3 + d.addEvent('player-joined', 4); // event 4 - let h1 = await d.fetchHistory(10, 2, null, 0); + const h1 = await d.fetchHistory(10, 2, null, 0); assert.equal(h1.events.length, 2); assert.equal(h1.events[0].id, 0); - let h2 = await d.fetchHistory(1, 3, null, 0); + const h2 = await d.fetchHistory(1, 3, null, 0); assert.equal(h2.events.length, 1); assert.equal(h2.events[0].id, 2); }); - it("impolite before test", async () => { + it('impolite before test', async () => { const d = new DummyHistoryFetcher(1); - d.addEvent("player-joined", 2); // event 2 - d.addEvent("player-joined", 3); // event 3 - d.addEvent("player-joined", 4); // event 4 + d.addEvent('player-joined', 2); // event 2 + d.addEvent('player-joined', 3); // event 3 + d.addEvent('player-joined', 4); // event 4 - let h1 = await d.fetchHistory(-10, 2, null, 0); + const h1 = await d.fetchHistory(-10, 2, null, 0); assert.equal(h1.events.length, 1); assert.equal(h1.events[0].id, 1); - let h2 = await d.fetchHistory(10, 100, null, 0); + const h2 = await d.fetchHistory(10, 100, null, 0); assert.equal(h2.events.length, 5); assert.equal(h2.events[0].id, 0); - let h3 = await d.fetchHistory(10, -100, null, 0); + const h3 = await d.fetchHistory(10, -100, null, 0); assert.equal(h3.events.length, 0); - let h4 = await d.fetchHistory(2, 100, null, 0); + const h4 = await d.fetchHistory(2, 100, null, 0); assert.equal(h4.events.length, 2); assert.equal(h4.events[0].id, 3); - let h5 = await d.fetchHistory(2, -100, null, 0); + const h5 = await d.fetchHistory(2, -100, null, 0); assert.equal(h5.events.length, 0); }); - it("after test", async () => { + it('after test', async () => { const d = new DummyHistoryFetcher(1); - d.addEvent("player-joined", 2); // event 2 - d.addEvent("player-joined", 3); // event 3 - d.addEvent("player-joined", 4); // event 4 + d.addEvent('player-joined', 2); // event 2 + d.addEvent('player-joined', 3); // event 3 + d.addEvent('player-joined', 4); // event 4 - let h1 = await d.fetchHistory(10, null, 2, 0); + const h1 = await d.fetchHistory(10, null, 2, 0); assert.equal(h1.events.length, 2); assert.equal(h1.events[0].id, 3); - let h2 = await d.fetchHistory(1, null, 3, 0); + const h2 = await d.fetchHistory(1, null, 3, 0); assert.equal(h2.events.length, 1); assert.equal(h2.events[0].id, 4); }); - it("impolite after test", async () => { + it('impolite after test', async () => { const d = new DummyHistoryFetcher(1); - d.addEvent("player-joined", 2); // event 2 - d.addEvent("player-joined", 3); // event 3 - d.addEvent("player-joined", 4); // event 4 + d.addEvent('player-joined', 2); // event 2 + d.addEvent('player-joined', 3); // event 3 + d.addEvent('player-joined', 4); // event 4 - let h1 = await d.fetchHistory(-10, null, 2, 0); + const h1 = await d.fetchHistory(-10, null, 2, 0); assert.equal(h1.events.length, 1); assert.equal(h1.events[0].id, 3); - let h2 = await d.fetchHistory(2, null, 100, 0); + const h2 = await d.fetchHistory(2, null, 100, 0); assert.equal(h2.events.length, 0); - let h3 = await d.fetchHistory(2, null, -100, 0); + const h3 = await d.fetchHistory(2, null, -100, 0); assert.equal(h3.events.length, 2); assert.equal(h3.events[0].id, 0); - let h4 = await d.fetchHistory(100, null, 100, 0); + const h4 = await d.fetchHistory(100, null, 100, 0); assert.equal(h4.events.length, 0); - let h5 = await d.fetchHistory(100, null, -100, 0); + const h5 = await d.fetchHistory(100, null, -100, 0); assert.equal(h5.events.length, 5); assert.equal(h5.events[0].id, 0); }); - it("add game test", async () => { + it('add game test', async () => { const d = new DummyHistoryFetcher(1); for (let i = 0; i < 5; i++) { - d.addEvent("player-joined", i + 2); + d.addEvent('player-joined', i + 2); } assert.equal(d.users.length, 6); assert.equal(d.events.length, 7); @@ -118,7 +118,7 @@ describe("History repositry Tests", () => { assert.equal(d.users.length, 6); assert.equal(d.events.length, 8); const ge = d.events[7]; - assert.equal(ge.detail.type, "other"); + assert.equal(ge.detail.type, 'other'); assert.equal(ge.game?.scores[0].user_id, 1); }); }); @@ -126,16 +126,16 @@ describe("History repositry Tests", () => { function buildJoinEventFetcher(count: number): DummyHistoryFetcher { const df = new DummyHistoryFetcher(1); for (let i = 2; i < count; i++) { - df.addEvent("player-joined", i); + df.addEvent('player-joined', i); } return df; } - describe("HistoryRepository tests with dummyfetcher", () => { + describe('HistoryRepository tests with dummyfetcher', () => { before(() => { HistoryRepository.COOL_TIME = 0; }); - it("basic updateToLatest test", async () => { + it('basic updateToLatest test', async () => { const df = buildJoinEventFetcher(16); const hr = new HistoryRepository(1, df); await hr.updateToLatest(); @@ -144,46 +144,46 @@ describe("History repositry Tests", () => { assert.isTrue(15 in hr.users); assert.isFalse(16 in hr.users); assert.equal(hr.events.length, 16); - assert.equal(hr.events[0].detail.type, "match-created"); - assert.equal(hr.events[15].detail.type, "player-joined"); + assert.equal(hr.events[0].detail.type, 'match-created'); + assert.equal(hr.events[15].detail.type, 'player-joined'); assert.equal(hr.events[15].user_id, 15); }); - it("size limited updateToLatest test", async () => { + it('size limited updateToLatest test', async () => { const df = buildJoinEventFetcher(16); df.limit = 3; const hr = new HistoryRepository(1, df); await hr.updateToLatest(); assert.equal(hr.events.length, 3); - assert.equal(hr.events[0].detail.type, "player-joined"); + assert.equal(hr.events[0].detail.type, 'player-joined'); assert.equal(hr.events[0].id, 13); - assert.equal(hr.events[1].detail.type, "player-joined"); + assert.equal(hr.events[1].detail.type, 'player-joined'); assert.equal(hr.events[1].id, 14); - assert.equal(hr.events[2].detail.type, "player-joined"); + assert.equal(hr.events[2].detail.type, 'player-joined'); assert.equal(hr.events[2].id, 15); - assert.equal(hr.events[2].detail.type, "player-joined"); + assert.equal(hr.events[2].detail.type, 'player-joined'); for (let i = 0; i < 16; i++) { - df.addEvent("host-changed", i); + df.addEvent('host-changed', i); } await hr.updateToLatest(); assert.equal(hr.events.length, 19); - assert.equal(hr.events[18].detail.type, "host-changed"); + assert.equal(hr.events[18].detail.type, 'host-changed'); assert.equal(hr.events[18].id, 31); assert.equal(hr.latestEventId, 31); }); - it("fetch test", async () => { + it('fetch test', async () => { const df = buildJoinEventFetcher(16); df.limit = 3; const hr = new HistoryRepository(1, df); - let r = await hr.fetch(); + const r = await hr.fetch(); assert.equal(r.count, 3); assert.equal(r.filled, true); assert.equal(r.isRewind, false); assert.equal(hr.events.length, 3); assert.equal(hr.events[0].id, 13); }); - it("rewind fetch test", async () => { + it('rewind fetch test', async () => { const df = buildJoinEventFetcher(16); df.limit = 3; const hr = new HistoryRepository(1, df); @@ -201,7 +201,7 @@ describe("History repositry Tests", () => { assert.equal(hr.events.length, 6); assert.equal(hr.events[0].id, 10); }); - it("back and go test", async () => { + it('back and go test', async () => { const df = buildJoinEventFetcher(16); df.limit = 3; const hr = new HistoryRepository(1, df); @@ -220,121 +220,121 @@ describe("History repositry Tests", () => { assert.equal(hr.events[0].id, 13); }); - it("basic order test", async () => { + it('basic order test', async () => { const df = buildJoinEventFetcher(16); const hr = new HistoryRepository(1, df); const o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); }); - it("basic host-change order test", async () => { + it('basic host-change order test', async () => { const df = new DummyHistoryFetcher(1); - df.addEvent("player-joined", 2); - df.addEvent("player-joined", 3); - df.addEvent("player-joined", 4); - df.addEvent("player-joined", 5); - df.addEvent("player-left", 3); - df.addEvent("player-left", 5); + df.addEvent('player-joined', 2); + df.addEvent('player-joined', 3); + df.addEvent('player-joined', 4); + df.addEvent('player-joined', 5); + df.addEvent('player-left', 3); + df.addEvent('player-left', 5); const hr = new HistoryRepository(1, df); let o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [1, 2, 4]); - df.addEvent("host-changed", 2); + df.addEvent('host-changed', 2); o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [2, 4, 1]); }); - it("host-change order test", async () => { + it('host-change order test', async () => { const df = new DummyHistoryFetcher(1); - df.addEvent("player-joined", 2); - df.addEvent("player-joined", 3); - df.addEvent("host-changed", 2); - df.addEvent("player-joined", 4); - df.addEvent("host-changed", 3); + df.addEvent('player-joined', 2); + df.addEvent('player-joined', 3); + df.addEvent('host-changed', 2); + df.addEvent('player-joined', 4); + df.addEvent('host-changed', 3); const hr = new HistoryRepository(1, df); let o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [3, 1, 4, 2]); - df.addEvent("host-changed", 4); + df.addEvent('host-changed', 4); o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [4, 1, 2, 3]); - df.addEvent("player-joined", 5); - df.addEvent("host-changed", 5); + df.addEvent('player-joined', 5); + df.addEvent('host-changed', 5); o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [5, 1, 2, 3, 4]); }); - it("player-left order test", async () => { + it('player-left order test', async () => { const df = new DummyHistoryFetcher(1); - df.addEvent("player-joined", 2); - df.addEvent("player-joined", 3); - df.addEvent("player-joined", 4); - df.addEvent("player-joined", 5); - df.addEvent("player-left", 3); - df.addEvent("player-left", 5); - df.addEvent("host-changed", 2); - df.addEvent("player-joined", 6); - df.addEvent("player-joined", 5); // rejoin 5 + df.addEvent('player-joined', 2); + df.addEvent('player-joined', 3); + df.addEvent('player-joined', 4); + df.addEvent('player-joined', 5); + df.addEvent('player-left', 3); + df.addEvent('player-left', 5); + df.addEvent('host-changed', 2); + df.addEvent('player-joined', 6); + df.addEvent('player-joined', 5); // rejoin 5 const hr = new HistoryRepository(1, df); - let o = await hr.calcCurrentOrderAsID(); + const o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [2, 4, 1, 6, 5]); }); - it("lots of event order test", async () => { + it('lots of event order test', async () => { const df = new DummyHistoryFetcher(1); const hr = new HistoryRepository(1, df); for (let i = 2; i < 500; i++) { - df.addEvent("player-joined", i); - df.addEvent("player-left", i); + df.addEvent('player-joined', i); + df.addEvent('player-left', i); } - let o = await hr.calcCurrentOrderAsID(); + const o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [1]); assert.isAbove(hr.events.length, 300); }); - it("lots of event and game test 1", async () => { + it('lots of event and game test 1', async () => { const df = new DummyHistoryFetcher(1); const hr = new HistoryRepository(1, df); for (let i = 2; i < 500; i++) { - df.addEvent("player-joined", i); - df.addEvent("player-left", i); + df.addEvent('player-joined', i); + df.addEvent('player-left', i); } df.addGameEvent([1]); - let o = await hr.calcCurrentOrderAsID(); + const o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [1]); assert.isAbove(hr.events.length, 300); }); - it("lots of event and game test 2", async () => { + it('lots of event and game test 2', async () => { const df = new DummyHistoryFetcher(1); for (let i = 2; i < 500; i++) { - df.addEvent("player-joined", i); - df.addEvent("player-left", i); + df.addEvent('player-joined', i); + df.addEvent('player-left', i); } - df.addEvent("player-joined", 2); - df.addEvent("player-joined", 3); - df.addEvent("player-joined", 4); - df.addEvent("player-left", 1); + df.addEvent('player-joined', 2); + df.addEvent('player-joined', 3); + df.addEvent('player-joined', 4); + df.addEvent('player-left', 1); for (let i = 0; i < HistoryRepository.ESC_CRITERIA - 1; i++) { const hr = new HistoryRepository(1, df); df.addGameEvent([2, 3, 4]); - let o = await hr.calcCurrentOrderAsID(); + const o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [2, 3, 4]); assert.isAbove(hr.events.length, 300); } { const hr = new HistoryRepository(1, df); df.addGameEvent([2, 3, 4]); - let o = await hr.calcCurrentOrderAsID(); + const o = await hr.calcCurrentOrderAsID(); assert.sameOrderedMembers(o, [2, 3, 4]); assert.isBelow(hr.events.length, 300); } }); - it("gotUserProfile event test", async () => { + it('gotUserProfile event test', async () => { const df = buildJoinEventFetcher(16); const hr = new HistoryRepository(1, df); let count = 0; - let t = tu.assertEventFire(hr.gotUserProfile, (e) => { + const t = tu.assertEventFire(hr.gotUserProfile, (e) => { count++; return count == 15; }, 100); await hr.updateToLatest(); await t; }); - it("changedLobbyName event test", async () => { + it('changedLobbyName event test', async () => { const df = buildJoinEventFetcher(16); const hr = new HistoryRepository(1, df); let a = 0; // aが0の間はイベント発生しない @@ -345,15 +345,15 @@ describe("History repositry Tests", () => { assert.fail(); case 1: b++; - assert.equal(e.newName, "newname 1"); + assert.equal(e.newName, 'newname 1'); assert.equal(e.oldName, hr.matchInfo?.name); break; case 2: assert.fail(); case 3: b++; - assert.equal(e.newName, "newname 2"); - assert.equal(e.oldName, "newname 1"); + assert.equal(e.newName, 'newname 2'); + assert.equal(e.oldName, 'newname 1'); break; } }); @@ -361,14 +361,14 @@ describe("History repositry Tests", () => { df.addGameEvent([1, 2, 3]); await hr.updateToLatest(); a = 1; - df.addGameEvent([1, 2, 3], "newname 1"); + df.addGameEvent([1, 2, 3], 'newname 1'); await hr.updateToLatest(); assert.equal(b, 1); a = 2; - df.addGameEvent([1, 2, 3], "newname 1"); + df.addGameEvent([1, 2, 3], 'newname 1'); await hr.updateToLatest(); a = 3; - df.addGameEvent([1, 2, 3], "newname 2"); + df.addGameEvent([1, 2, 3], 'newname 2'); await hr.updateToLatest(); assert.equal(b, 2); }); diff --git a/src/tests/HostSkipperTest.ts b/src/tests/HostSkipperTest.ts index d010c909..0d2e9473 100644 --- a/src/tests/HostSkipperTest.ts +++ b/src/tests/HostSkipperTest.ts @@ -7,7 +7,7 @@ import tu from './TestUtils'; import { HostSkipper, HostSkipperOption } from '../plugins/HostSkipper'; import { StatResult, StatStatuses } from '../parsers/StatParser'; -describe("HostSkipperTest", function () { +describe('HostSkipperTest', function () { before(function () { tu.configMochaAsSilent(); }); @@ -23,51 +23,51 @@ describe("HostSkipperTest", function () { afk_check_interval_first_ms: timer_delay, afk_check_interval_ms: timer_delay, afk_check_do_skip: true - } - const skipper = new HostSkipper(li.lobby, option) + }; + const skipper = new HostSkipper(li.lobby, option); return { skipper, ...li }; } async function resolveSkipAsync(lobby: Lobby, callback: (() => void) | null = null): Promise { - const t = tu.assertEventFire(lobby.PluginMessage, a => a.type == "skip"); + const t = tu.assertEventFire(lobby.PluginMessage, a => a.type == 'skip'); if (callback != null) { t.then(a => { callback(); return a; - }) + }); } return t; } async function rejectSkipAsync(lobby: Lobby, timeout: number): Promise { - return tu.assertEventNeverFire(lobby.PluginMessage, a => a.type == "skip", timeout); + return tu.assertEventNeverFire(lobby.PluginMessage, a => a.type == 'skip', timeout); } async function resolveSkiptoAsync(lobby: Lobby, userid: string): Promise { - return tu.assertEventFire(lobby.PluginMessage, a => a.type == "skipto" && a.args[0] == userid); + return tu.assertEventFire(lobby.PluginMessage, a => a.type == 'skipto' && a.args[0] == userid); } async function rejectSkiptoAsync(lobby: Lobby, timeout: number): Promise { - return tu.assertEventNeverFire(lobby.PluginMessage, a => a.type == "skipto", timeout); + return tu.assertEventNeverFire(lobby.PluginMessage, a => a.type == 'skipto', timeout); } - describe("construction test", () => { - it("default", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + describe('construction test', () => { + it('default', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); const lobby = new Lobby(ircClient); - await lobby.MakeLobbyAsync("test"); + await lobby.MakeLobbyAsync('test'); const skipper = new HostSkipper(lobby); - const option = config.get("HostSkipper"); + const option = config.get('HostSkipper'); assert.deepEqual(skipper.option, option); }); - it("with option partial", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('with option partial', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); const lobby = new Lobby(ircClient); - await lobby.MakeLobbyAsync("test"); + await lobby.MakeLobbyAsync('test'); const option = { vote_rate: 2, - } - const defaultOption = config.get("HostSkipper"); + }; + const defaultOption = config.get('HostSkipper'); const skipper = new HostSkipper(lobby, option); assert.equal(skipper.option.vote_min, defaultOption.vote_min); assert.notEqual(skipper.option.vote_rate, defaultOption.vote_rate); @@ -75,16 +75,16 @@ describe("HostSkipperTest", function () { assert.equal(skipper.option.afk_check_interval_ms, defaultOption.afk_check_interval_ms); skipper.StopTimer(); }); - it("prepare function", async () => { + it('prepare function', async () => { const { skipper, lobby, ircClient } = await prepare(10); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - lobby.TransferHost(lobby.GetPlayer("p1") as Player); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + lobby.TransferHost(lobby.GetPlayer('p1') as Player); assert.isNotNull(lobby.host); - tu.assertHost("p1", lobby); + tu.assertHost('p1', lobby); skipper.StopTimer(); }); }); - describe("skip timer test", function () { + describe('skip timer test', function () { let dslow = 0; before(function () { dslow = this.slow(); @@ -94,56 +94,56 @@ describe("HostSkipperTest", function () { this.slow(dslow); }); - it("skip 10ms", async () => { + it('skip 10ms', async () => { const { skipper, lobby, ircClient } = await prepare(10); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); assert.isUndefined(skipper.afkTimer); - await tu.changeHostAsync("p1", lobby); + await tu.changeHostAsync('p1', lobby); assert.isDefined(skipper.afkTimer); assert.equal(skipper.voting.count, 0); await resolveSkipAsync(lobby); skipper.StopTimer(); }); - it("skip time check", async () => { + it('skip time check', async () => { const { skipper, lobby, ircClient } = await prepare(10); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); - let test = async (waitTime: number) => { + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); + const test = async (waitTime: number) => { skipper.option.afk_check_interval_first_ms = waitTime; skipper.option.afk_check_interval_ms = waitTime; skipper.Reset(); - const startTime = await tu.changeHostAsync("p1", lobby); + const startTime = await tu.changeHostAsync('p1', lobby); const endTime = await resolveSkipAsync(lobby); const elapsed = endTime - startTime; assert.closeTo(elapsed, waitTime, 20); skipper.StopTimer(); - } + }; await test(10); await test(50); await test(100); }); - it("timer reset when host changed", async function () { + it('timer reset when host changed', async function () { const { skipper, lobby, ircClient } = await prepare(30); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); - ircClient.SetStat(new StatResult("p2", 0, StatStatuses.Afk)); - const startTime = await tu.changeHostAsync("p1", lobby); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); + ircClient.SetStat(new StatResult('p2', 0, StatStatuses.Afk)); + const startTime = await tu.changeHostAsync('p1', lobby); const rt = resolveSkipAsync(lobby); - tu.assertHost("p1", lobby); + tu.assertHost('p1', lobby); await tu.delayAsync(10); - await tu.changeHostAsync("p2", lobby); + await tu.changeHostAsync('p2', lobby); const endTime = await rt; - tu.assertHost("p2", lobby); + tu.assertHost('p2', lobby); const elapsed = endTime - startTime; assert.closeTo(elapsed, 10 + 30, 50); skipper.StopTimer(); }); - it("timer reset when host changing map", async () => { + it('timer reset when host changing map', async () => { const { skipper, lobby, ircClient } = await prepare(10); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); - const startTime = await tu.changeHostAsync("p1", lobby); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); + const startTime = await tu.changeHostAsync('p1', lobby); const t = rejectSkipAsync(lobby, 10); await tu.delayAsync(5); assert.isDefined(skipper.afkTimer); @@ -152,56 +152,56 @@ describe("HostSkipperTest", function () { await resolveSkipAsync(lobby); skipper.StopTimer(); }); - it("timer stop when host chated", async () => { + it('timer stop when host chated', async () => { const { skipper, lobby, ircClient } = await prepare(10); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); - const startTime = await tu.changeHostAsync("p1", lobby); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); + const startTime = await tu.changeHostAsync('p1', lobby); const t = rejectSkipAsync(lobby, 10); await tu.delayAsync(5); assert.isDefined(skipper.afkTimer); - await ircClient.emulateMessageAsync("p1", ircClient.channel, "hello"); + await ircClient.emulateMessageAsync('p1', ircClient.channel, 'hello'); await t; await resolveSkipAsync(lobby); skipper.StopTimer(); }); - it("if delay time is 0, timer dosent work", async () => { + it('if delay time is 0, timer dosent work', async () => { const { skipper, lobby, ircClient } = await prepare(0); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); - await tu.changeHostAsync("p1", lobby); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); + await tu.changeHostAsync('p1', lobby); assert.isUndefined(skipper.afkTimer); await tu.delayAsync(10); assert.isUndefined(skipper.afkTimer); await rejectSkipAsync(lobby, 30); skipper.StopTimer(); }); - it("dosent skip if option is false", async () => { + it('dosent skip if option is false', async () => { const { skipper, lobby, ircClient } = await prepare(10); skipper.option.afk_check_do_skip = false; - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); - await tu.AddPlayersAsync(["p1", "p2", "p3"], ircClient); - await tu.changeHostAsync("p1", lobby); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], ircClient); + await tu.changeHostAsync('p1', lobby); await rejectSkipAsync(lobby, 15); skipper.StopTimer(); }); - it("skip afk host when a player join", async () => { + it('skip afk host when a player join', async () => { const { skipper, lobby, ircClient } = await prepare(10); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Afk)); - await tu.AddPlayersAsync(["p1"], ircClient); - await tu.changeHostAsync("p1", lobby); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Afk)); + await tu.AddPlayersAsync(['p1'], ircClient); + await tu.changeHostAsync('p1', lobby); await resolveSkipAsync(lobby); const t = resolveSkipAsync(lobby); let n = Date.now(); - await tu.AddPlayersAsync(["p2"], ircClient); + await tu.AddPlayersAsync(['p2'], ircClient); n = (await t) - n; assert.isBelow(n, 10); skipper.StopTimer(); }); }); - describe("skip vote test", function () { - it("vote required check", async () => { + describe('skip vote test', function () { + it('vote required check', async () => { const { skipper, lobby, ircClient } = await prepare(); assert.equal(skipper.voting.required, 2); await tu.AddPlayersAsync(1, ircClient); @@ -221,265 +221,265 @@ describe("HostSkipperTest", function () { await tu.AddPlayersAsync(1, ircClient); assert.equal(skipper.voting.required, 4); }); - it("host skip", async () => { + it('host skip', async () => { const { skipper, lobby, ircClient } = await prepare(0, 0); await tu.AddPlayersAsync(3, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); const rt = resolveSkipAsync(lobby); - ircClient.emulateMessage("p0", ircClient.channel, "!skip"); + ircClient.emulateMessage('p0', ircClient.channel, '!skip'); await rt; }); - it("host skip should be ignored during cool time", async () => { + it('host skip should be ignored during cool time', async () => { const { skipper, lobby, ircClient } = await prepare(0, 10000); await tu.AddPlayersAsync(3, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); const r = rejectSkipAsync(lobby, 20); - ircClient.emulateMessage("p0", ircClient.channel, "!skip"); + ircClient.emulateMessage('p0', ircClient.channel, '!skip'); await r; }); - it("host invalid skip", async () => { + it('host invalid skip', async () => { const { skipper, lobby, ircClient } = await prepare(0, 0); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p0", ircClient.channel, "!skipaaaaa"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p0', ircClient.channel, '!skipaaaaa'); await rejectSkipAsync(lobby, 10); }); - it("skip by players", async () => { + it('skip by players', async () => { const { skipper, lobby, ircClient } = await prepare(0, 0); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); let skipped = false; const task = resolveSkipAsync(lobby, () => skipped = true); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 1); assert.isFalse(skipped); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 2); assert.isFalse(skipped); - ircClient.emulateMessage("p3", ircClient.channel, "!skip"); + ircClient.emulateMessage('p3', ircClient.channel, '!skip'); await tu.delayAsync(10); await task; assert.equal(skipper.voting.count, 3); assert.isTrue(skipped); }); - it("ignored vote when cooltime", async () => { + it('ignored vote when cooltime', async () => { const { skipper, lobby, ircClient } = await prepare(0, 30); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); const task = rejectSkipAsync(lobby, 30); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); - ircClient.emulateMessage("p3", ircClient.channel, "!skip"); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); + ircClient.emulateMessage('p3', ircClient.channel, '!skip'); await task; assert.equal(skipper.voting.count, 0); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); await tu.delayAsync(1); assert.equal(skipper.voting.count, 1); }); - it("duplicate vote", async () => { + it('duplicate vote', async () => { const { skipper, lobby, ircClient } = await prepare(0, 0); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 2); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 2); }); - it("vote can valid after mapchanging", async () => { + it('vote can valid after mapchanging', async () => { const { skipper, lobby, ircClient } = await prepare(0, 0); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); let skipped = false; const task = resolveSkipAsync(lobby, () => skipped = true); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.isFalse(skipped); ircClient.emulateChangeMapAsync(0); await tu.delayAsync(10); - ircClient.emulateMessage("p3", ircClient.channel, "!skip"); + ircClient.emulateMessage('p3', ircClient.channel, '!skip'); await tu.delayAsync(10); await task; assert.equal(skipper.voting.count, 3); assert.isTrue(skipped); }); - it("vote reject when match", async () => { + it('vote reject when match', async () => { const { skipper, lobby, ircClient } = await prepare(0); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); await tu.delayAsync(10); ircClient.emulateMatchAsync(10); await tu.delayAsync(1); - ircClient.emulateMessage("p3", ircClient.channel, "!skip"); - ircClient.emulateMessage("p4", ircClient.channel, "!skip"); + ircClient.emulateMessage('p3', ircClient.channel, '!skip'); + ircClient.emulateMessage('p4', ircClient.channel, '!skip'); await tu.delayAsync(1); assert.equal(skipper.voting.count, 0); await tu.delayAsync(10); assert.equal(skipper.voting.count, 0); }); - it("is lots of vote ignored", async () => { + it('is lots of vote ignored', async () => { const { skipper, lobby, ircClient } = await prepare(0); const numplayers = 16; await tu.AddPlayersAsync(numplayers, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); let skipped = false; const task = resolveSkipAsync(lobby, () => skipped = true); for (let i = 1; i < numplayers; i++) { - ircClient.emulateMessage("p" + i, ircClient.channel, "!skip"); + ircClient.emulateMessage('p' + i, ircClient.channel, '!skip'); await tu.delayAsync(1); assert.equal(skipper.voting.count, Math.min(i, skipper.voting.required)); assert.equal(skipped, skipper.voting.required <= i); } }); - it("accept !skip with host id", async () => { + it('accept !skip with host id', async () => { const { skipper, lobby, ircClient } = await prepare(); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "!skip p0"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '!skip p0'); //assert.equal(skipper.voting.count, 1); }); - it("accept !skip with complex host id", async () => { + it('accept !skip with complex host id', async () => { const { skipper, lobby, ircClient } = await prepare(); - const players = ["abc xxx[aaui]", "a", "b", "c"]; + const players = ['abc xxx[aaui]', 'a', 'b', 'c']; await tu.AddPlayersAsync(players, ircClient); await tu.changeHostAsync(players[0], lobby); - ircClient.emulateMessage(players[1], ircClient.channel, "!skip " + players[0]); + ircClient.emulateMessage(players[1], ircClient.channel, '!skip ' + players[0]); assert.equal(skipper.voting.count, 1); }); - it("accept !skip with space", async () => { + it('accept !skip with space', async () => { const { skipper, lobby, ircClient } = await prepare(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); - ircClient.emulateMessage(players[1], ircClient.channel, "!skip "); + ircClient.emulateMessage(players[1], ircClient.channel, '!skip '); assert.equal(skipper.voting.count, 1); }); - it("ignore !skip if none host player targeted", async () => { + it('ignore !skip if none host player targeted', async () => { const { skipper, lobby, ircClient } = await prepare(); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "!skip abc"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '!skip abc'); assert.equal(skipper.voting.count, 0); }); }); - describe("custom command tests", function () { - it("*skip by authorized user test", async () => { + describe('custom command tests', function () { + it('*skip by authorized user test', async () => { const { skipper, lobby, ircClient } = await prepare(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); - var t = resolveSkipAsync(lobby); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); + const t = resolveSkipAsync(lobby); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "*skip"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '*skip'); await t; }); - it("*skip by authorized user with param test", async () => { + it('*skip by authorized user with param test', async () => { const { skipper, lobby, ircClient } = await prepare(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); - var t = resolveSkipAsync(lobby); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); + const t = resolveSkipAsync(lobby); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "*skip aaa"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '*skip aaa'); await t; }); - it("*skip by Unauthorized test", async () => { + it('*skip by Unauthorized test', async () => { const { skipper, lobby, ircClient } = await prepare(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); - var t = rejectSkipAsync(lobby, 25); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); + const t = rejectSkipAsync(lobby, 25); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p2", ircClient.channel, "*skip"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p2', ircClient.channel, '*skip'); await t; }); - it("*skipto test", async () => { + it('*skipto test', async () => { const { skipper, lobby, ircClient } = await prepare(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); - var t = resolveSkiptoAsync(lobby, "p3"); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); + const t = resolveSkiptoAsync(lobby, 'p3'); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "*skipto p3"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '*skipto p3'); await t; }); - it("failed *skipto if param isn't userid", async () => { + it('failed *skipto if param isn\'t userid', async () => { const { skipper, lobby, ircClient } = await prepare(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); - var t = rejectSkiptoAsync(lobby, 25); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); + const t = rejectSkiptoAsync(lobby, 25); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - ircClient.emulateMessage("p1", ircClient.channel, "*skipto pvv3 asdv"); + await tu.changeHostAsync('p0', lobby); + ircClient.emulateMessage('p1', ircClient.channel, '*skipto pvv3 asdv'); await t; }); }); - describe("cleared host tests", function () { - it("skip vote", async () => { + describe('cleared host tests', function () { + it('skip vote', async () => { const { skipper, lobby, ircClient } = await prepare(0, 0); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); let skipped = false; const task = resolveSkipAsync(lobby, () => skipped = true); - lobby.SendMessage("!mp clearhost"); + lobby.SendMessage('!mp clearhost'); assert.isTrue(lobby.isClearedHost); assert.isNull(lobby.host); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 1); assert.isFalse(skipped); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 2); assert.isFalse(skipped); - ircClient.emulateMessage("p3", ircClient.channel, "!skip"); + ircClient.emulateMessage('p3', ircClient.channel, '!skip'); await tu.delayAsync(10); await task; assert.equal(skipper.voting.count, 3); assert.isTrue(skipped); }); - it("skip vote and clearhost on the way", async () => { + it('skip vote and clearhost on the way', async () => { const { skipper, lobby, ircClient } = await prepare(0, 0); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); + await tu.changeHostAsync('p0', lobby); let skipped = false; const task = resolveSkipAsync(lobby, () => skipped = true); - ircClient.emulateMessage("p1", ircClient.channel, "!skip"); + ircClient.emulateMessage('p1', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 1); assert.isFalse(skipped); - lobby.SendMessage("!mp clearhost"); + lobby.SendMessage('!mp clearhost'); assert.isTrue(lobby.isClearedHost); assert.isNull(lobby.host); - ircClient.emulateMessage("p2", ircClient.channel, "!skip"); + ircClient.emulateMessage('p2', ircClient.channel, '!skip'); await tu.delayAsync(10); assert.equal(skipper.voting.count, 2); assert.isFalse(skipped); - ircClient.emulateMessage("p3", ircClient.channel, "!skip"); + ircClient.emulateMessage('p3', ircClient.channel, '!skip'); await tu.delayAsync(10); await task; assert.equal(skipper.voting.count, 3); assert.isTrue(skipped); }); - it("*skip by authorized user test", async () => { + it('*skip by authorized user test', async () => { const { skipper, lobby, ircClient } = await prepare(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); - var t = resolveSkipAsync(lobby); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); + const t = resolveSkipAsync(lobby); await tu.AddPlayersAsync(5, ircClient); - await tu.changeHostAsync("p0", lobby); - lobby.SendMessage("!mp clearhost"); + await tu.changeHostAsync('p0', lobby); + lobby.SendMessage('!mp clearhost'); assert.isTrue(lobby.isClearedHost); assert.isNull(lobby.host); - ircClient.emulateMessage("p1", ircClient.channel, "*skip"); + ircClient.emulateMessage('p1', ircClient.channel, '*skip'); await t; }); }); diff --git a/src/tests/InOutLoggerTest.ts b/src/tests/InOutLoggerTest.ts index 2a6162fa..ebf94577 100644 --- a/src/tests/InOutLoggerTest.ts +++ b/src/tests/InOutLoggerTest.ts @@ -1,12 +1,12 @@ import { InOutLogger } from '../plugins/InOutLogger'; import tu from './TestUtils'; -describe.skip("In Out Logger Tests", function () { +describe.skip('In Out Logger Tests', function () { before(function () { tu.configMochaVerbosely(); }); - it("test", async () => { + it('test', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); const logger = new InOutLogger(lobby); const players = await tu.AddPlayersAsync(5, ircClient); @@ -15,17 +15,17 @@ describe.skip("In Out Logger Tests", function () { await ircClient.emulateRemovePlayerAsync(players[0]); await ircClient.emulateRemovePlayerAsync(players[1]); await ircClient.emulateRemovePlayerAsync(players[2]); - await ircClient.emulateAddPlayerAsync("a"); - await ircClient.emulateAddPlayerAsync("b"); - await ircClient.emulateAddPlayerAsync("c"); + await ircClient.emulateAddPlayerAsync('a'); + await ircClient.emulateAddPlayerAsync('b'); + await ircClient.emulateAddPlayerAsync('c'); const t = ircClient.emulateMatchAsync(10); await tu.delayAsync(1); - await ircClient.emulateRemovePlayerAsync("a"); - await ircClient.emulateAddPlayerAsync("d"); + await ircClient.emulateRemovePlayerAsync('a'); + await ircClient.emulateAddPlayerAsync('d'); await t; - await ircClient.emulateAddPlayerAsync("e"); + await ircClient.emulateAddPlayerAsync('e'); await ircClient.emulateMatchAsync(); - await ircClient.emulateRemovePlayerAsync("e"); + await ircClient.emulateRemovePlayerAsync('e'); await ircClient.emulateMatchAsync(); logger.logger.info(logger.GetPluginStatus()); }); diff --git a/src/tests/IntegratedPluginsTest.ts b/src/tests/IntegratedPluginsTest.ts index 4a1fc068..3febec67 100644 --- a/src/tests/IntegratedPluginsTest.ts +++ b/src/tests/IntegratedPluginsTest.ts @@ -10,23 +10,23 @@ import { HostSkipperOption } from '../plugins/HostSkipper'; import tu from './TestUtils'; -describe("Integrated Plugins Tests", function () { +describe('Integrated Plugins Tests', function () { before(function () { tu.configMochaAsSilent(); }); - describe("selector and skipper tests", function () { + describe('selector and skipper tests', function () { async function setup(selectorOption: Partial = {}, skipperOption: Partial = { afk_check_interval_ms: 0 }): Promise<{ selector: AutoHostSelector, skipper: HostSkipper, lobby: Lobby, ircClient: DummyIrcClient }> { const li = await tu.SetupLobbyAsync(); const selector = new AutoHostSelector(li.lobby, selectorOption); const skipper = new HostSkipper(li.lobby, skipperOption); return { selector, skipper, ...li }; - }; + } - it("skip to test", async () => { + it('skip to test', async () => { const { selector, skipper, lobby, ircClient } = await setup(); const ownerId = tu.ownerNickname; - await tu.AddPlayersAsync([ownerId, "p2", "p3", "p4"], ircClient); + await tu.AddPlayersAsync([ownerId, 'p2', 'p3', 'p4'], ircClient); let owner = lobby.GetPlayer(ownerId); assert.isNotNull(owner); owner = owner as Player; @@ -36,14 +36,14 @@ describe("Integrated Plugins Tests", function () { await ircClient.emulateMatchAsync(0); - tu.assertHost("p2", lobby); - let m = "*skipto p4"; + tu.assertHost('p2', lobby); + let m = '*skipto p4'; assert.isTrue(parser.IsChatCommand(m)); lobby.RaiseReceivedChatCommand(owner, m); await tu.delayAsync(10); - tu.assertHost("p4", lobby); + tu.assertHost('p4', lobby); - m = "*skipto " + owner.name; + m = '*skipto ' + owner.name; assert.isTrue(parser.IsChatCommand(m)); lobby.RaiseReceivedChatCommand(owner, m); await tu.delayAsync(10); diff --git a/src/tests/LobbyKeeperTest.ts b/src/tests/LobbyKeeperTest.ts index cc5d45e2..ad37547b 100644 --- a/src/tests/LobbyKeeperTest.ts +++ b/src/tests/LobbyKeeperTest.ts @@ -7,7 +7,7 @@ import { Mod, ScoreMode, TeamMode } from '../Modes'; import { LobbyKeeper, LobbyKeeperOption, SlotKeeper } from '../plugins/LobbyKeeper'; import tu from './TestUtils'; -describe("LobbyKeepserTest", function () { +describe('LobbyKeepserTest', function () { before(function () { tu.configMochaAsSilent(); @@ -29,11 +29,11 @@ describe("LobbyKeepserTest", function () { }; const li = await tu.SetupLobbyAsync(); const keeper = new LobbyKeeper(li.lobby, option); - await tu.AddPlayersAsync(["p1", "p2", "p3"], li.ircClient); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], li.ircClient); return { keeper, ...li }; } - describe("SlotKeeper tests", () => { + describe('SlotKeeper tests', () => { let clock: Sinon.SinonFakeTimers | undefined; before(function () { clock = Sinon.useFakeTimers(); @@ -42,9 +42,9 @@ describe("LobbyKeepserTest", function () { after(function () { clock?.restore(); }); - describe("size 4 test", () => { + describe('size 4 test', () => { - it("size over test", () => { + it('size over test', () => { const sk = new SlotKeeper(4); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -53,14 +53,14 @@ describe("LobbyKeepserTest", function () { assert.isTrue(sk.checkJoin(5)); }); - it("locked slot test", () => { + it('locked slot test', () => { const sk = new SlotKeeper(4); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); assert.isTrue(sk.checkJoin(4)); }); - it("leave slot test", () => { + it('leave slot test', () => { const sk = new SlotKeeper(4); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -77,7 +77,7 @@ describe("LobbyKeepserTest", function () { assert.isFalse(sk.checkJoin(1)); }); - it("move slot test", () => { + it('move slot test', () => { const sk = new SlotKeeper(4); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -88,7 +88,7 @@ describe("LobbyKeepserTest", function () { assert.isTrue(sk.checkMove(1, 5)); }); - it("move slot test", () => { + it('move slot test', () => { const sk = new SlotKeeper(4); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -99,7 +99,7 @@ describe("LobbyKeepserTest", function () { assert.isTrue(sk.checkMove(1, 5)); }); - it("check unused slot test", () => { + it('check unused slot test', () => { const sk = new SlotKeeper(4); assert.isFalse(sk.checkJoin(1)); @@ -114,8 +114,8 @@ describe("LobbyKeepserTest", function () { }); }); - describe("size 0 tests", () => { - it("size over test", () => { + describe('size 0 tests', () => { + it('size over test', () => { const sk = new SlotKeeper(0); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -124,14 +124,14 @@ describe("LobbyKeepserTest", function () { assert.isFalse(sk.checkJoin(5)); }); - it("locked slot test", () => { + it('locked slot test', () => { const sk = new SlotKeeper(0); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); assert.isFalse(sk.checkJoin(4)); }); - it("leave slot test", () => { + it('leave slot test', () => { const sk = new SlotKeeper(0); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -148,7 +148,7 @@ describe("LobbyKeepserTest", function () { assert.isFalse(sk.checkJoin(1)); }); - it("move slot test", () => { + it('move slot test', () => { const sk = new SlotKeeper(0); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -159,7 +159,7 @@ describe("LobbyKeepserTest", function () { assert.isFalse(sk.checkMove(1, 5)); }); - it("move slot test", () => { + it('move slot test', () => { const sk = new SlotKeeper(0); assert.isFalse(sk.checkJoin(1)); assert.isFalse(sk.checkJoin(2)); @@ -170,7 +170,7 @@ describe("LobbyKeepserTest", function () { assert.isFalse(sk.checkMove(1, 5)); }); - it("check unused slot test", () => { + it('check unused slot test', () => { const sk = new SlotKeeper(0); assert.isFalse(sk.checkJoin(1)); @@ -184,11 +184,11 @@ describe("LobbyKeepserTest", function () { assert.isFalse(sk.checkUnused()); }); - }) + }); }); - describe("option tests", () => { - it("null option check", async () => { + describe('option tests', () => { + it('null option check', async () => { const { keeper } = await setupAsync({ mode: null, hostkick_tolerance: 4, @@ -205,7 +205,7 @@ describe("LobbyKeepserTest", function () { assert.isNull(keeper.option.title); }); - it("mode option check", async () => { + it('mode option check', async () => { const { keeper } = await setupAsync({ mode: null, }); @@ -221,53 +221,53 @@ describe("LobbyKeepserTest", function () { keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.TagCoop, score: ScoreMode.Accuracy }); - keeper.option.mode = { team: "Head To Head", score: "Combo" } as any; + keeper.option.mode = { team: 'Head To Head', score: 'Combo' } as any; keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.HeadToHead, score: ScoreMode.Combo }); - keeper.option.mode = { team: "tagcoop", score: "scorev2" } as any; + keeper.option.mode = { team: 'tagcoop', score: 'scorev2' } as any; keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.TagCoop, score: ScoreMode.ScoreV2 }); - keeper.option.mode = "1 1" as any; + keeper.option.mode = '1 1' as any; keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.TagCoop, score: ScoreMode.Accuracy }); - keeper.option.mode = "TagTeamVs ScoreV2" as any; + keeper.option.mode = 'TagTeamVs ScoreV2' as any; keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.TagTeamVs, score: ScoreMode.ScoreV2 }); - keeper.option.mode = "Head To Head, Score V2" as any; + keeper.option.mode = 'Head To Head, Score V2' as any; keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.HeadToHead, score: ScoreMode.ScoreV2 }); - keeper.option.mode = "Head To Head" as any; + keeper.option.mode = 'Head To Head' as any; keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.HeadToHead, score: ScoreMode.Score }); - keeper.option.mode = "ScoreV2" as any; + keeper.option.mode = 'ScoreV2' as any; keeper.convertOptions(); assert.deepEqual(keeper.option.mode, { team: TeamMode.HeadToHead, score: ScoreMode.ScoreV2 }); }); - it("invalid mode option check", async () => { + it('invalid mode option check', async () => { const { keeper } = await setupAsync({ mode: null, }); assert.isNull(keeper.option.mode); - keeper.option.mode = "test" as any; + keeper.option.mode = 'test' as any; assert.throw(() => keeper.convertOptions()); - keeper.option.mode = { aaa: 12, team: "aaaa" } as any; + keeper.option.mode = { aaa: 12, team: 'aaaa' } as any; assert.throw(() => keeper.convertOptions()); keeper.option.mode = [1, 2] as any; assert.throw(() => keeper.convertOptions()); }); - it("mods option check", async () => { + it('mods option check', async () => { const { keeper } = await setupAsync({ mods: null, }); @@ -278,47 +278,47 @@ describe("LobbyKeepserTest", function () { keeper.convertOptions(); assert.isNull(keeper.option.mods); - keeper.option.mods = "None" as any; + keeper.option.mods = 'None' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, []); - keeper.option.mods = "" as any; + keeper.option.mods = '' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, []); - keeper.option.mods = "freemod" as any; + keeper.option.mods = 'freemod' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Freemod]); - keeper.option.mods = "HD" as any; + keeper.option.mods = 'HD' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Hidden]); - keeper.option.mods = "HD, Dt" as any; + keeper.option.mods = 'HD, Dt' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Hidden, Mod.DoubleTime]); - keeper.option.mods = "Hidden, DoubleTime" as any; + keeper.option.mods = 'Hidden, DoubleTime' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Hidden, Mod.DoubleTime]); - keeper.option.mods = "HD Dt" as any; + keeper.option.mods = 'HD Dt' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Hidden, Mod.DoubleTime]); - keeper.option.mods = "Freemod doubleTime Hidden" as any; + keeper.option.mods = 'Freemod doubleTime Hidden' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Freemod, Mod.DoubleTime]); - keeper.option.mods = "Freemod relax relax2" as any; + keeper.option.mods = 'Freemod relax relax2' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Freemod]); - keeper.option.mods = "relax relax2" as any; + keeper.option.mods = 'relax relax2' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Relax]); - keeper.option.mods = "[hd, hr]" as any; + keeper.option.mods = '[hd, hr]' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Hidden, Mod.HardRock]); @@ -342,49 +342,49 @@ describe("LobbyKeepserTest", function () { keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, []); - keeper.option.mods = ["None"] as any; + keeper.option.mods = ['None'] as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, []); - keeper.option.mods = ["Freemod"] as any; + keeper.option.mods = ['Freemod'] as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Freemod]); - keeper.option.mods = ["Freemod", "HardRock", "Relax", "Nightcore"] as any; + keeper.option.mods = ['Freemod', 'HardRock', 'Relax', 'Nightcore'] as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Freemod, Mod.DoubleTime, Mod.Nightcore]); }); - it("invalid mods option check", async () => { + it('invalid mods option check', async () => { const { keeper } = await setupAsync({ mods: null, }); assert.isNull(keeper.option.mods); - keeper.option.mods = "aaaaaa" as any; + keeper.option.mods = 'aaaaaa' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, []); - keeper.option.mods = "aaaaaa, bbbbbb, sdsfs" as any; + keeper.option.mods = 'aaaaaa, bbbbbb, sdsfs' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, []); - keeper.option.mods = "aaaaaa bbbbbb sdsfs" as any; + keeper.option.mods = 'aaaaaa bbbbbb sdsfs' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, []); - keeper.option.mods = "aaaaaa bbbbbb sdsfs hidden sdf" as any; + keeper.option.mods = 'aaaaaa bbbbbb sdsfs hidden sdf' as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Hidden]); - keeper.option.mods = ["adfs", "23fsd", "Relax", "xxxxxfds"] as any; + keeper.option.mods = ['adfs', '23fsd', 'Relax', 'xxxxxfds'] as any; keeper.convertOptions(); assert.sameMembers(keeper.option.mods as any, [Mod.Relax]); }); - it("size option check", async () => { + it('size option check', async () => { const { keeper } = await setupAsync({ size: 0, }); @@ -408,7 +408,7 @@ describe("LobbyKeepserTest", function () { assert.equal(keeper.option.size, 16); }); - it("invalid size option check", async () => { + it('invalid size option check', async () => { const { keeper } = await setupAsync({ size: 0, }); @@ -419,23 +419,23 @@ describe("LobbyKeepserTest", function () { keeper.option.size = -1000 as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "1000" as any; + keeper.option.size = '1000' as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "-1000" as any; + keeper.option.size = '-1000' as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "aaaaa" as any; + keeper.option.size = 'aaaaa' as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "NaN" as any; + keeper.option.size = 'NaN' as any; assert.throw(() => keeper.convertOptions()); keeper.option.size = new Date() as any; assert.throw(() => keeper.convertOptions()); }); - it("password option check", async () => { + it('password option check', async () => { const { keeper } = await setupAsync({ password: null, }); @@ -446,16 +446,16 @@ describe("LobbyKeepserTest", function () { keeper.option.size = -1000 as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "1000" as any; + keeper.option.size = '1000' as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "-1000" as any; + keeper.option.size = '-1000' as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "aaaaa" as any; + keeper.option.size = 'aaaaa' as any; assert.throw(() => keeper.convertOptions()); - keeper.option.size = "NaN" as any; + keeper.option.size = 'NaN' as any; assert.throw(() => keeper.convertOptions()); keeper.option.size = new Date() as any; @@ -463,370 +463,370 @@ describe("LobbyKeepserTest", function () { }); }); - describe("chat command tests", () => { - it("command test : mode", async () => { + describe('chat command tests', () => { + it('command test : mode', async () => { const { keeper, lobby, ircClient } = await setupAsync({ mode: null }); const defaultOpton = { team: TeamMode.HeadToHead, score: ScoreMode.Score }; - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode 0 1"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode 0 1'); let mode = keeper.option.mode; assert.notEqual(mode, defaultOpton); assert.equal(mode?.team, TeamMode.HeadToHead); assert.equal(mode?.score, ScoreMode.Accuracy); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode 1"); // specify only team + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode 1'); // specify only team mode = keeper.option.mode; assert.notEqual(mode, defaultOpton); assert.equal(mode?.team, TeamMode.TagCoop); assert.equal(mode?.score, ScoreMode.Score); // Inherit previous value keeper.option.mode.score = ScoreMode.Accuracy; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode 1");// specify only team + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode 1');// specify only team mode = keeper.option.mode; assert.notEqual(mode, defaultOpton); assert.equal(mode?.team, TeamMode.TagCoop); assert.equal(mode?.score, ScoreMode.Accuracy); // Inherit previous value keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode combo"); // specify only score + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode combo'); // specify only score mode = keeper.option.mode; assert.notEqual(mode, defaultOpton); assert.equal(mode?.team, TeamMode.HeadToHead); assert.equal(mode?.score, ScoreMode.Combo); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode head to head, accuracy"); // with space and comma + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode head to head, accuracy'); // with space and comma mode = keeper.option.mode; assert.notEqual(mode, defaultOpton); assert.equal(mode?.team, TeamMode.HeadToHead); assert.equal(mode?.score, ScoreMode.Accuracy); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode tag coop"); // team only, space + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode tag coop'); // team only, space mode = keeper.option.mode; assert.notEqual(mode, defaultOpton); assert.equal(mode?.team, TeamMode.TagCoop); assert.equal(mode?.score, ScoreMode.Score); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode null"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode null'); assert.isNull(keeper.option.mode); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*no keep mode"); + ircClient.emulateMessage('p1', ircClient.channel, '*no keep mode'); assert.isNull(keeper.option.mode); }); - it("invalid command test : mode", async () => { + it('invalid command test : mode', async () => { const { keeper, lobby, ircClient } = await setupAsync({ mode: null }); const defaultOpton = { team: TeamMode.HeadToHead, score: ScoreMode.Score }; - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode"); // no param + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode'); // no param assert.equal(keeper.option.mode, defaultOpton); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode aaaaa"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode aaaaa'); assert.equal(keeper.option.mode, defaultOpton); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode 100 400 500"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode 100 400 500'); assert.equal(keeper.option.mode, defaultOpton); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mode 112"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mode 112'); assert.equal(keeper.option.mode, defaultOpton); keeper.option.mode = defaultOpton; - ircClient.emulateMessage("p1", ircClient.channel, "*keepheadtohead"); // team only, witoutspace + ircClient.emulateMessage('p1', ircClient.channel, '*keepheadtohead'); // team only, witoutspace assert.equal(keeper.option.mode, defaultOpton); }); - it("command test : size", async () => { + it('command test : size', async () => { const defaultSize = 100; const { keeper, lobby, ircClient } = await setupAsync({ size: 4, }); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size 0"); - let size = keeper.option.size; + ircClient.emulateMessage('p1', ircClient.channel, '*keep size 0'); + const size = keeper.option.size; assert.isDefined(size); assert.equal(size, 0); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size 1"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size 1'); assert.equal(keeper.option.size, 1); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size 16"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size 16'); assert.equal(keeper.option.size, 16); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*no keep size"); + ircClient.emulateMessage('p1', ircClient.channel, '*no keep size'); assert.equal(keeper.option.size, 0); }); - it("invalid command test : size", async () => { + it('invalid command test : size', async () => { const defaultSize = 100; const { keeper, lobby, ircClient } = await setupAsync({ size: 4, }); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size'); assert.equal(keeper.option.size, defaultSize); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size aaaa"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size aaaa'); assert.equal(keeper.option.size, defaultSize); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size12213 1"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size12213 1'); assert.equal(keeper.option.size, defaultSize); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size -1"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size -1'); assert.equal(keeper.option.size, defaultSize); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size -100000"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size -100000'); assert.equal(keeper.option.size, defaultSize); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size NaN"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size NaN'); assert.equal(keeper.option.size, defaultSize); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep sizesdfc"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep sizesdfc'); assert.equal(keeper.option.size, defaultSize); keeper.option.size = defaultSize; - ircClient.emulateMessage("p1", ircClient.channel, "*keep size12"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep size12'); assert.equal(keeper.option.size, defaultSize); }); - it("command test : mods", async () => { + it('command test : mods', async () => { const defaultMods = [Mod.None]; // never match command reuslt const { keeper, lobby, ircClient } = await setupAsync({ mods: [], }); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mod hidden"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mod hidden'); assert.sameMembers(keeper.option.mods, [Mod.Hidden]); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mods hidden"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mods hidden'); assert.sameMembers(keeper.option.mods, [Mod.Hidden]); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mods HD"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mods HD'); assert.sameMembers(keeper.option.mods, [Mod.Hidden]); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mods HIDDEN"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mods HIDDEN'); assert.sameMembers(keeper.option.mods, [Mod.Hidden]); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mods None"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mods None'); assert.sameMembers(keeper.option.mods, []); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mods Freemod"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mods Freemod'); assert.sameMembers(keeper.option.mods, [Mod.Freemod]); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mods freemod hidden double"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mods freemod hidden double'); assert.sameMembers(keeper.option.mods, [Mod.Freemod, Mod.DoubleTime]); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*no keep mod"); + ircClient.emulateMessage('p1', ircClient.channel, '*no keep mod'); assert.isNull(keeper.option.mods); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*no keep mods"); + ircClient.emulateMessage('p1', ircClient.channel, '*no keep mods'); assert.isNull(keeper.option.mods); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mod null"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mod null'); assert.isNull(keeper.option.mods); }); - it("invalid command test : mods", async () => { + it('invalid command test : mods', async () => { const defaultMods = [Mod.None]; // never match command reuslt const { keeper, lobby, ircClient } = await setupAsync({ mods: [], }); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mods"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mods'); assert.equal(keeper.option.mods, defaultMods); keeper.option.mods = defaultMods; - ircClient.emulateMessage("p1", ircClient.channel, "*keep mod"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep mod'); assert.equal(keeper.option.mods, defaultMods); }); - it("command test : password", async () => { - const defaultPassword = "aaaaaa"; + it('command test : password', async () => { + const defaultPassword = 'aaaaaa'; const { keeper, lobby, ircClient } = await setupAsync({ password: null, }); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password testtest"); - assert.equal(keeper.option.password, "testtest"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password testtest'); + assert.equal(keeper.option.password, 'testtest'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password test test"); - assert.equal(keeper.option.password, "test test"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password test test'); + assert.equal(keeper.option.password, 'test test'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password t e s t"); - assert.equal(keeper.option.password, "t e s t"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password t e s t'); + assert.equal(keeper.option.password, 't e s t'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password t e s t "); - assert.equal(keeper.option.password, "t e s t"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password t e s t '); + assert.equal(keeper.option.password, 't e s t'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password"); - assert.equal(keeper.option.password, ""); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password'); + assert.equal(keeper.option.password, ''); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password "); - assert.equal(keeper.option.password, ""); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password '); + assert.equal(keeper.option.password, ''); }); - it("command test : password", async () => { - const defaultPassword = "aaaaaa"; + it('command test : password', async () => { + const defaultPassword = 'aaaaaa'; const { keeper, lobby, ircClient } = await setupAsync({ password: null, }); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password testtest"); - assert.equal(keeper.option.password, "testtest"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password testtest'); + assert.equal(keeper.option.password, 'testtest'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password test test"); - assert.equal(keeper.option.password, "test test"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password test test'); + assert.equal(keeper.option.password, 'test test'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password t e s t"); - assert.equal(keeper.option.password, "t e s t"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password t e s t'); + assert.equal(keeper.option.password, 't e s t'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password t e s t "); - assert.equal(keeper.option.password, "t e s t"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password t e s t '); + assert.equal(keeper.option.password, 't e s t'); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password"); - assert.equal(keeper.option.password, ""); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password'); + assert.equal(keeper.option.password, ''); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*keep password "); - assert.equal(keeper.option.password, ""); + ircClient.emulateMessage('p1', ircClient.channel, '*keep password '); + assert.equal(keeper.option.password, ''); keeper.option.password = defaultPassword; - ircClient.emulateMessage("p1", ircClient.channel, "*no keep password"); + ircClient.emulateMessage('p1', ircClient.channel, '*no keep password'); assert.isNull(keeper.option.password); }); - it("command test : title", async () => { - const defaultTitle = "aaaaaa"; + it('command test : title', async () => { + const defaultTitle = 'aaaaaa'; const { keeper, lobby, ircClient } = await setupAsync({ password: null, }); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*keep title testtest"); - assert.equal(keeper.option.title, "testtest"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep title testtest'); + assert.equal(keeper.option.title, 'testtest'); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*keep name testtest"); - assert.equal(keeper.option.title, "testtest"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep name testtest'); + assert.equal(keeper.option.title, 'testtest'); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*keep title test test"); - assert.equal(keeper.option.title, "test test"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep title test test'); + assert.equal(keeper.option.title, 'test test'); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*keep title t e s t"); - assert.equal(keeper.option.title, "t e s t"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep title t e s t'); + assert.equal(keeper.option.title, 't e s t'); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*keep title t e s t "); - assert.equal(keeper.option.title, "t e s t"); + ircClient.emulateMessage('p1', ircClient.channel, '*keep title t e s t '); + assert.equal(keeper.option.title, 't e s t'); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*keep title"); - assert.equal(keeper.option.title, ""); + ircClient.emulateMessage('p1', ircClient.channel, '*keep title'); + assert.equal(keeper.option.title, ''); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*keep title "); - assert.equal(keeper.option.title, ""); + ircClient.emulateMessage('p1', ircClient.channel, '*keep title '); + assert.equal(keeper.option.title, ''); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*no keep title"); + ircClient.emulateMessage('p1', ircClient.channel, '*no keep title'); assert.isNull(keeper.option.title); keeper.option.title = defaultTitle; - ircClient.emulateMessage("p1", ircClient.channel, "*no keep name"); + ircClient.emulateMessage('p1', ircClient.channel, '*no keep name'); assert.isNull(keeper.option.title); }); }); - describe("slotkeeper on lobbykeeper tests", () => { + describe('slotkeeper on lobbykeeper tests', () => { - it("size over test", async () => { + it('size over test', async () => { const { keeper, lobby, ircClient } = await setupAsync({ size: 4, }); const spy = Sinon.spy(lobby); - await ircClient.emulateAddPlayerAsync("player4"); + await ircClient.emulateAddPlayerAsync('player4'); }); - }) + }); }); diff --git a/src/tests/LobbyTerminatorTest.ts b/src/tests/LobbyTerminatorTest.ts index ce153d41..21078c56 100644 --- a/src/tests/LobbyTerminatorTest.ts +++ b/src/tests/LobbyTerminatorTest.ts @@ -5,7 +5,7 @@ import { DummyIrcClient } from '../dummies/DummyIrcClient'; import { LobbyTerminator } from '../plugins/LobbyTerminator'; import tu from './TestUtils'; -describe.skip("Lobby Terminator Tests", function () { +describe.skip('Lobby Terminator Tests', function () { before(function () { tu.configMochaVerbosely(); }); @@ -15,8 +15,8 @@ describe.skip("Lobby Terminator Tests", function () { terminator.multilimeMessageInterval = interval; return { terminator, lobby, ircClient }; } - it("CloseLobby time", async () => { + it('CloseLobby time', async () => { const { terminator, lobby, ircClient } = await setupAsync(); terminator.CloseLobby(100); - }) + }); }); diff --git a/src/tests/LobbyTest.ts b/src/tests/LobbyTest.ts index 1f1478d8..311e96b9 100644 --- a/src/tests/LobbyTest.ts +++ b/src/tests/LobbyTest.ts @@ -8,9 +8,9 @@ import { MpSettingsCases } from './cases/MpSettingsCases'; import log4js from 'log4js'; import tu from './TestUtils'; -describe("LobbyTest", function () { +describe('LobbyTest', function () { before(function () { - log4js.configure("config/log_mocha_silent.json"); + log4js.configure('config/log_mocha_silent.json'); }); interface LobbyTestBasicSet { ircClient: DummyIrcClient; @@ -20,12 +20,12 @@ describe("LobbyTest", function () { // テスト用にロビー作成済み、プレイヤー追加済みのロビーを作成する。 async function PrepareLobbyWith3Players(): Promise { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); const lobby = new Lobby(ircClient); - await lobby.MakeLobbyAsync("test"); - const pids = ["user1", "user2", "user3"]; + await lobby.MakeLobbyAsync('test'); + const pids = ['user1', 'user2', 'user3']; const players: Player[] = []; - for (let p of pids) { + for (const p of pids) { await ircClient.emulateAddPlayerAsync(p); players.push(lobby.GetOrMakePlayer(p)); } @@ -36,29 +36,29 @@ describe("LobbyTest", function () { }; } - describe("lobby management tests", function () { + describe('lobby management tests', function () { // ロビー作成、ロビー終了テスト - it("make&close lobby test", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('make&close lobby test', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); //logIrcEvent(ircClient); const lobby = new Lobby(ircClient); - const name = "test"; + const name = 'test'; const id = await lobby.MakeLobbyAsync(name); assert.equal(lobby.lobbyId, id); assert.equal(lobby.channel, ircClient.channel); assert.equal(lobby.lobbyName, name); assert.equal(lobby.status, LobbyStatus.Entered); - lobby.SendMessage("!mp password"); - lobby.SendMessage("!mp invite gnsksz"); + lobby.SendMessage('!mp password'); + lobby.SendMessage('!mp invite gnsksz'); await lobby.CloseLobbyAsync(); }); // 名前無しロビーの作成 - it("try to make no name lobby test", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('try to make no name lobby test', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); const lobby = new Lobby(ircClient); - const name = ""; + const name = ''; try { await lobby.MakeLobbyAsync(name); assert.fail(); @@ -66,19 +66,19 @@ describe("LobbyTest", function () { }); // ロビーを二回作成 - it("make lobby twice test", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('make lobby twice test', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); const lobby = new Lobby(ircClient); try { - lobby.MakeLobbyAsync("1"); - lobby.MakeLobbyAsync("2"); + lobby.MakeLobbyAsync('1'); + lobby.MakeLobbyAsync('2'); assert.fail(); } catch { } }); // 無効な状態でロビーを閉じる - it("close unopened lobby test", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('close unopened lobby test', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); const lobby = new Lobby(ircClient); try { await lobby.CloseLobbyAsync(); @@ -87,16 +87,16 @@ describe("LobbyTest", function () { }); }); - describe("join left tests", function () { + describe('join left tests', function () { // プレイヤーの入室 - it("player join test", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('player join test', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); //logIrcEvent(ircClient); const lobby = new Lobby(ircClient); - await lobby.MakeLobbyAsync("test"); + await lobby.MakeLobbyAsync('test'); // プレイヤー追加 - const players = ["user1", "user 2", "user_3"]; + const players = ['user1', 'user 2', 'user_3']; const joiningPlayers: Set = new Set(players); const jp = new Promise(resolve => { lobby.PlayerJoined.on(({ player, slot }) => { @@ -107,7 +107,7 @@ describe("LobbyTest", function () { } }); }); - for (let p of players) { + for (const p of players) { await ircClient.emulateAddPlayerAsync(p); } await jp; @@ -115,7 +115,7 @@ describe("LobbyTest", function () { // 参加人数を調べる assert.equal(players.length, lobby.players.size); - for (let p of lobby.players) { + for (const p of lobby.players) { // 参加者が一致しているか調べる assert.isTrue(players.includes(p.name)); @@ -131,7 +131,7 @@ describe("LobbyTest", function () { }); // プレイヤーの退出 一人 - it("player left test", async () => { + it('player left test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); // 一人だけ退出 @@ -152,12 +152,12 @@ describe("LobbyTest", function () { }); // 入退出 - it("player join&left test", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('player join&left test', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); //logIrcEvent(ircClient); const lobby = new Lobby(ircClient); - await lobby.MakeLobbyAsync("test"); - const players = ["user1", "user 2", "user_3"]; + await lobby.MakeLobbyAsync('test'); + const players = ['user1', 'user 2', 'user_3']; await ircClient.emulateAddPlayerAsync(players[0]); assert.isTrue(lobby.Includes(players[0])); @@ -174,25 +174,25 @@ describe("LobbyTest", function () { }); // 想定外の入室/退室 - it("unexpected join and left test", async () => { - const ircClient = new DummyIrcClient("osu_irc_server", "creator"); + it('unexpected join and left test', async () => { + const ircClient = new DummyIrcClient('osu_irc_server', 'creator'); const lobby = new Lobby(ircClient); - await lobby.MakeLobbyAsync("test"); + await lobby.MakeLobbyAsync('test'); let f = 0; lobby.UnexpectedAction.on(err => { f = f + 1; }); - await ircClient.emulateRemovePlayerAsync("unknown player"); + await ircClient.emulateRemovePlayerAsync('unknown player'); assert.equal(f, 1); f = 0; - ircClient.emulateAddPlayerAsync("tom"); - ircClient.emulateAddPlayerAsync("jim"); - ircClient.emulateAddPlayerAsync("tom"); + ircClient.emulateAddPlayerAsync('tom'); + ircClient.emulateAddPlayerAsync('jim'); + ircClient.emulateAddPlayerAsync('tom'); assert.equal(f, 1); }); - it("host change test", async () => { + it('host change test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); const assertHost = async (next: Player) => { return new Promise(resolve => { @@ -203,7 +203,7 @@ describe("LobbyTest", function () { resolve(player); }); }); - } + }; let nexthost = players[0]; let task = assertHost(nexthost); lobby.TransferHost(nexthost); @@ -216,21 +216,21 @@ describe("LobbyTest", function () { }); // ホスト任命後に離脱した場合 - it("host change & left test", async () => { + it('host change & left test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); const tr = tu.assertEventNeverFire(lobby.HostChanged, null, 10); //logIrcEvent(ircClient); - let nexthost = players[0]; - let taskLeft = ircClient.emulateRemovePlayerAsync(nexthost.name); + const nexthost = players[0]; + const taskLeft = ircClient.emulateRemovePlayerAsync(nexthost.name); lobby.TransferHost(nexthost); await taskLeft; await tr; }); }); - describe("match tests", function () { + describe('match tests', function () { // 試合テスト - it("match start test", async () => { + it('match start test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); //logIrcEvent(ircClient); let ms = false; @@ -251,7 +251,7 @@ describe("LobbyTest", function () { mf = true; assert.isTrue(ms); assert.equal(finishedplayers.size, players.length); - for (let p of players) { + for (const p of players) { assert.isTrue(finishedplayers.has(p)); } }); @@ -259,7 +259,7 @@ describe("LobbyTest", function () { }); // 試合中の退出テスト - it("match and left test", async () => { + it('match and left test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); //logIrcEvent(ircClient); let ms = false; @@ -289,7 +289,7 @@ describe("LobbyTest", function () { }); // 試合中断テスト - it("match and abort test", async () => { + it('match and abort test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); //logIrcEvent(ircClient); let ms = false; @@ -316,7 +316,7 @@ describe("LobbyTest", function () { assert.isTrue(ms); assert.isTrue(ma); }); - it("match aborted before some players finished", async () => { + it('match aborted before some players finished', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = false; lobby.AbortedMatch.on((a) => { @@ -329,7 +329,7 @@ describe("LobbyTest", function () { await p; assert.isTrue(ma); }); - it("match aborted after some players left", async () => { + it('match aborted after some players left', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = false; lobby.AbortedMatch.on((a) => { @@ -338,12 +338,12 @@ describe("LobbyTest", function () { assert.equal(a.playersInGame, 2); }); const p = ircClient.emulateMatchAsync(10); - await ircClient.emulateRemovePlayerAsync("user1"); + await ircClient.emulateRemovePlayerAsync('user1'); lobby.AbortMatch(); await p; assert.isTrue(ma); }); - it("match aborted after some players finished", async () => { + it('match aborted after some players finished', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = false; lobby.AbortedMatch.on((a) => { @@ -352,12 +352,12 @@ describe("LobbyTest", function () { assert.equal(a.playersInGame, 3); }); const p = ircClient.emulateMatchAsync(10); - await ircClient.emulatePlayerFinishAsync("user1"); + await ircClient.emulatePlayerFinishAsync('user1'); lobby.AbortMatch(); await p; assert.isTrue(ma); }); - it("match aborted after some players left and remainders finished", async () => { + it('match aborted after some players left and remainders finished', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = false; lobby.AbortedMatch.on((a) => { @@ -366,16 +366,16 @@ describe("LobbyTest", function () { assert.equal(a.playersInGame, 2); }); const p = ircClient.emulateMatchAsync(10); - await ircClient.emulatePlayerFinishAsync("user1"); - await ircClient.emulateRemovePlayerAsync("user2"); - await ircClient.emulatePlayerFinishAsync("user3"); + await ircClient.emulatePlayerFinishAsync('user1'); + await ircClient.emulateRemovePlayerAsync('user2'); + await ircClient.emulatePlayerFinishAsync('user3'); lobby.AbortMatch(); await p; assert.isTrue(ma); }); - it("player statuses count test", async () => { + it('player statuses count test', async () => { function assertPc(lobby: Lobby, total: number, inLobby: number, playing: number) { - let pc = lobby.CountPlayersStatus(); + const pc = lobby.CountPlayersStatus(); assert.equal(pc.inlobby, inLobby); assert.equal(pc.inGame, total - inLobby); assert.equal(pc.playing, playing); @@ -406,14 +406,14 @@ describe("LobbyTest", function () { await mt; assertPc(lobby, 4, 4, 0); - }) + }); }); - describe("message handling tests", function () { - it("send message test", async () => { + describe('message handling tests', function () { + it('send message test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = false; - const msg = "hello world"; + const msg = 'hello world'; lobby.SentMessage.once(({ message }) => { assert.equal(message, msg); ma = true; @@ -422,44 +422,44 @@ describe("LobbyTest", function () { await tu.delayAsync(10); assert.isTrue(ma); }); - it("SendMessageWithCoolTime test", async () => { + it('SendMessageWithCoolTime test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = 0; - const msg = "hello world"; + const msg = 'hello world'; lobby.SentMessage.on(({ message }) => { assert.equal(message, msg); ma = ma + 1; }); - assert.isTrue(lobby.SendMessageWithCoolTime(msg, "tag", 10)); + assert.isTrue(lobby.SendMessageWithCoolTime(msg, 'tag', 10)); assert.equal(ma, 1); - assert.isFalse(lobby.SendMessageWithCoolTime(msg, "tag", 10)); + assert.isFalse(lobby.SendMessageWithCoolTime(msg, 'tag', 10)); assert.equal(ma, 1); await tu.delayAsync(15); - assert.isTrue(lobby.SendMessageWithCoolTime(msg, "tag", 10)); + assert.isTrue(lobby.SendMessageWithCoolTime(msg, 'tag', 10)); assert.equal(ma, 2); - assert.isTrue(lobby.SendMessageWithCoolTime(msg, "tag2", 10)); + assert.isTrue(lobby.SendMessageWithCoolTime(msg, 'tag2', 10)); assert.equal(ma, 3); - assert.isFalse(lobby.SendMessageWithCoolTime(msg, "tag2", 10)); + assert.isFalse(lobby.SendMessageWithCoolTime(msg, 'tag2', 10)); assert.equal(ma, 3); }); - it("SendMessageWithCoolTime function type message", async () => { + it('SendMessageWithCoolTime function type message', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let mf = false; const msg = () => { - return "a" + "b" + "c"; + return 'a' + 'b' + 'c'; }; lobby.SentMessage.on(({ message }) => { assert.equal(message, msg()); mf = true; }); - assert.isTrue(lobby.SendMessageWithCoolTime(msg, "tag", 10)); + assert.isTrue(lobby.SendMessageWithCoolTime(msg, 'tag', 10)); await tu.delayAsync(10); assert.isTrue(mf); }); - it("PlayerChated event", (done) => { + it('PlayerChated event', (done) => { PrepareLobbyWith3Players().then(({ ircClient, lobby, players }) => { - const msg = "hello world"; - let mf = false; + const msg = 'hello world'; + const mf = false; lobby.PlayerChated.once(a => { assert.equal(a.player, players[0]); assert.equal(a.message, msg); @@ -474,10 +474,10 @@ describe("LobbyTest", function () { ircClient.emulateChatAsync(players[0].name, msg); }); }); - it("BanchoChated event", done => { + it('BanchoChated event', done => { PrepareLobbyWith3Players().then(({ ircClient, lobby, players }) => { - const msg = "hello world"; - let mf = false; + const msg = 'hello world'; + const mf = false; lobby.PlayerChated.once(a => { assert.fail(); }); @@ -491,10 +491,10 @@ describe("LobbyTest", function () { ircClient.emulateBanchoResponse(msg); }); }); - it("ReceivedChatCommand", async () => { + it('ReceivedChatCommand', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = 0; - let msg = "!hello world"; + const msg = '!hello world'; lobby.PlayerChated.once(a => { assert.equal(a.message, msg); @@ -504,8 +504,8 @@ describe("LobbyTest", function () { }); lobby.ReceivedChatCommand.once(a => { assert.isFalse(a.player.isHost); - assert.equal(a.command, "!hello"); - assert.equal(a.param, "world"); + assert.equal(a.command, '!hello'); + assert.equal(a.param, 'world'); assert.equal(a.player, players[0]); ma = 1; }); @@ -513,18 +513,18 @@ describe("LobbyTest", function () { await tu.delayAsync(5); assert.equal(ma, 1); }); - it("ReceivedChatCommand", async () => { + it('ReceivedChatCommand', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); let ma = 0; lobby.TransferHost(players[0]); - let msg = "!hoge piyo"; + const msg = '!hoge piyo'; lobby.PlayerChated.once(a => { assert.equal(a.message, msg); }); lobby.ReceivedChatCommand.once(a => { assert.isTrue(a.player.isHost); - assert.equal(a.command, "!hoge"); - assert.equal(a.param, "piyo"); + assert.equal(a.command, '!hoge'); + assert.equal(a.param, 'piyo'); assert.equal(a.player, players[0]); ma = 1; }); @@ -534,138 +534,138 @@ describe("LobbyTest", function () { }); }); - describe("message tests", function () { - it.skip("showInfoMessage test", async () => { + describe('message tests', function () { + it.skip('showInfoMessage test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); tu.configMochaVerbosely(); - lobby.RaiseReceivedChatCommand(lobby.GetOrMakePlayer("tester"), "!info"); + lobby.RaiseReceivedChatCommand(lobby.GetOrMakePlayer('tester'), '!info'); }); - it.skip("SendMessageWithDelayAsync test", async () => { + it.skip('SendMessageWithDelayAsync test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); tu.configMochaVerbosely(); - lobby.SendMessage("hello"); - lobby.SendMessageWithDelayAsync("world", 1000); + lobby.SendMessage('hello'); + lobby.SendMessageWithDelayAsync('world', 1000); }); - it.skip("SendMultilineMessageWithInterval test", async () => { + it.skip('SendMultilineMessageWithInterval test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); tu.configMochaVerbosely(); - lobby.SendMultilineMessageWithInterval(["a", "b", "c", "d"], 1000, "a", 100); - lobby.SendMultilineMessageWithInterval(["e", "f", "g", "h"], 1000, "a", 100); + lobby.SendMultilineMessageWithInterval(['a', 'b', 'c', 'd'], 1000, 'a', 100); + lobby.SendMultilineMessageWithInterval(['e', 'f', 'g', 'h'], 1000, 'a', 100); }); - it.skip("DeferMessage test", async () => { + it.skip('DeferMessage test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); tu.configMochaVerbosely(); - lobby.DeferMessage("a", "abc", 10, false); + lobby.DeferMessage('a', 'abc', 10, false); await tu.delayAsync(20); - lobby.DeferMessage("b", "abc", 10, false); + lobby.DeferMessage('b', 'abc', 10, false); await tu.delayAsync(5); - lobby.DeferMessage("c", "abc", 10, false); + lobby.DeferMessage('c', 'abc', 10, false); await tu.delayAsync(5); - lobby.DeferMessage("d", "abc", 10, false); + lobby.DeferMessage('d', 'abc', 10, false); await tu.delayAsync(5); - lobby.DeferMessage("e", "abc", 10, false); + lobby.DeferMessage('e', 'abc', 10, false); await tu.delayAsync(20); - lobby.DeferMessage("xa", "abc", 10, true); + lobby.DeferMessage('xa', 'abc', 10, true); await tu.delayAsync(20); - lobby.DeferMessage("xb", "abc", 10, true); + lobby.DeferMessage('xb', 'abc', 10, true); await tu.delayAsync(5); - lobby.DeferMessage("xc", "abc", 10, true); + lobby.DeferMessage('xc', 'abc', 10, true); await tu.delayAsync(5); - lobby.DeferMessage("xd", "abc", 10, true); + lobby.DeferMessage('xd', 'abc', 10, true); await tu.delayAsync(5); - lobby.DeferMessage("xe", "abc", 10, true); + lobby.DeferMessage('xe', 'abc', 10, true); await tu.delayAsync(20); }); }); - describe("mp settings load tests", function () { - it("empty lobby", async () => { + describe('mp settings load tests', function () { + it('empty lobby', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); const c1 = MpSettingsCases.case1_1; - await ircClient.emulateChatAsync(ircClient.nick, "!mp settings"); + await ircClient.emulateChatAsync(ircClient.nick, '!mp settings'); c1.texts.forEach(t => ircClient.emulateBanchoResponse(t)); tu.assertMpSettingsResult(lobby, c1.result); }); - it("change host", async () => { + it('change host', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); const c1_1 = MpSettingsCases.case1_1; const c1_2 = MpSettingsCases.case1_2; - await ircClient.emulateChatAsync(ircClient.nick, "!mp settings"); + await ircClient.emulateChatAsync(ircClient.nick, '!mp settings'); c1_1.texts.forEach(t => ircClient.emulateBanchoResponse(t)); tu.assertMpSettingsResult(lobby, c1_1.result); c1_2.texts.forEach(t => ircClient.emulateBanchoResponse(t)); tu.assertMpSettingsResult(lobby, c1_2.result); }); - it("resore", async () => { + it('resore', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); const c1_1 = MpSettingsCases.case1_1; const c1_2 = MpSettingsCases.case1_2; - await ircClient.emulateChatAsync(ircClient.nick, "!mp settings"); + await ircClient.emulateChatAsync(ircClient.nick, '!mp settings'); c1_1.texts.forEach(t => ircClient.emulateBanchoResponse(t)); tu.assertMpSettingsResult(lobby, c1_1.result); - await ircClient.emulateRemovePlayerAsync("p1"); - await ircClient.emulateRemovePlayerAsync("p2"); - await ircClient.emulateRemovePlayerAsync("p3"); - await ircClient.emulateAddPlayerAsync("p6"); - await ircClient.emulateAddPlayerAsync("p7"); - await ircClient.emulateAddPlayerAsync("p8"); + await ircClient.emulateRemovePlayerAsync('p1'); + await ircClient.emulateRemovePlayerAsync('p2'); + await ircClient.emulateRemovePlayerAsync('p3'); + await ircClient.emulateAddPlayerAsync('p6'); + await ircClient.emulateAddPlayerAsync('p7'); + await ircClient.emulateAddPlayerAsync('p8'); c1_2.texts.forEach(t => ircClient.emulateBanchoResponse(t)); tu.assertMpSettingsResult(lobby, c1_2.result); }); }); - describe("stat tests", function () { - it("send stat", async () => { + describe('stat tests', function () { + it('send stat', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); await tu.AddPlayersAsync([ircClient.nick], ircClient); const players = await tu.AddPlayersAsync(5, ircClient); const t = tu.assertEventFire(lobby.ParsedStat, null, 10); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Multiplayer)); - ircClient.emulateChatAsync("p1", "!stats p1"); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Multiplayer)); + ircClient.emulateChatAsync('p1', '!stats p1'); await t; }); - it("send stat invalid user", async () => { + it('send stat invalid user', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); await tu.AddPlayersAsync([ircClient.nick], ircClient); const players = await tu.AddPlayersAsync(5, ircClient); const t = tu.assertEventNeverFire(lobby.ParsedStat, null, 10); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Multiplayer)); - ircClient.emulateChatAsync("p1", "!stats p100"); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Multiplayer)); + ircClient.emulateChatAsync('p1', '!stats p100'); await t; }); - it("send stat pm", async () => { + it('send stat pm', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); await tu.AddPlayersAsync([ircClient.nick], ircClient); const players = await tu.AddPlayersAsync(5, ircClient); const t = tu.assertEventFire(lobby.ParsedStat, null, 10); - ircClient.SetStat(new StatResult("p1", 0, StatStatuses.Multiplayer)); - ircClient.emulateChatAsync(ircClient.nick, "!stats p1"); + ircClient.SetStat(new StatResult('p1', 0, StatStatuses.Multiplayer)); + ircClient.emulateChatAsync(ircClient.nick, '!stats p1'); await t; }); }); - it.skip("plugin test", async () => { + it.skip('plugin test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); const lp = new DummyLobbyPlugin(lobby); console.log(lobby.GetLobbyStatus()); }); // mpコマンドの実行状況に応じて変更される状態に関するテスト - describe("lobby commandflag tests", function () { - it("clear host test", async () => { + describe('lobby commandflag tests', function () { + it('clear host test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); assert.isFalse(lobby.isClearedHost); - lobby.SendMessage("!mp clearhost"); + lobby.SendMessage('!mp clearhost'); await tu.delayAsync(1); assert.isTrue(lobby.isClearedHost); lobby.TransferHost(players[1]); assert.isFalse(lobby.isClearedHost); }); - it("start timer test", async () => { + it('start timer test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); assert.isFalse(lobby.isStartTimerActive); - lobby.SendMessage("!mp start 20"); + lobby.SendMessage('!mp start 20'); await tu.delayAsync(1); assert.isTrue(lobby.isStartTimerActive); await ircClient.emulateMatchAsync(1); @@ -674,17 +674,17 @@ describe("LobbyTest", function () { }); // 実際に発生したバグを再現するテスト - describe("Bug reproduction tests", function () { - it("some chat cant handle as chat", async () => { + describe('Bug reproduction tests', function () { + it('some chat cant handle as chat', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); await tu.AddPlayersAsync(5, ircClient); - ircClient.emulateBanchoResponse("Omen de cobra joined in slot 2."); + ircClient.emulateBanchoResponse('Omen de cobra joined in slot 2.'); await tu.delayAsync(10); - assert.isTrue(lobby.Includes("Omen de cobra")); - assert.isTrue(lobby.Includes("Omen_de_cobra")); - ircClient.emulateChatAsync("Omen_de_cobra", " is this winnner rotation?"); + assert.isTrue(lobby.Includes('Omen de cobra')); + assert.isTrue(lobby.Includes('Omen_de_cobra')); + ircClient.emulateChatAsync('Omen_de_cobra', ' is this winnner rotation?'); }); - it("creator role check", async () => { + it('creator role check', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); await tu.AddPlayersAsync([tu.ownerNickname], ircClient); let p = lobby.GetPlayer(tu.ownerNickname); diff --git a/src/tests/MapCheckerTest.ts b/src/tests/MapCheckerTest.ts index a4018cb6..36be6b78 100644 --- a/src/tests/MapCheckerTest.ts +++ b/src/tests/MapCheckerTest.ts @@ -8,14 +8,14 @@ import { MapCheckerUncheckedOption, MapChecker } from '../plugins/MapChecker'; import { BeatmapRepository } from '../webapi/BeatmapRepository'; import tu from './TestUtils'; -describe("Map Checker Tests", function () { +describe('Map Checker Tests', function () { before(function () { tu.configMochaAsSilent(); }); afterEach(function () { BeatmapRepository.maps.clear(); - }) + }); async function setup(option?: MapCheckerUncheckedOption): Promise<{ checker: MapChecker, lobby: Lobby, ircClient: DummyIrcClient }> { @@ -25,7 +25,7 @@ describe("Map Checker Tests", function () { star_max: 7.00, length_min: 0, length_max: 600, - gamemode: "osu", + gamemode: 'osu', num_violations_allowed: 3, allow_convert: true }; @@ -34,11 +34,11 @@ describe("Map Checker Tests", function () { const li = await tu.SetupLobbyAsync(); const checker = new MapChecker(li.lobby, option); - await tu.AddPlayersAsync(["p1", "p2", "p3"], li.ircClient); + await tu.AddPlayersAsync(['p1', 'p2', 'p3'], li.ircClient); return { checker, ...li }; } - describe("mapchecker option tests", () => { - it("default option test", async () => { + describe('mapchecker option tests', () => { + it('default option test', async () => { const { checker, lobby, ircClient } = await setup(); assert.equal(checker.option.allow_convert, true); @@ -52,7 +52,7 @@ describe("Map Checker Tests", function () { }); - it("type matched option test", async () => { + it('type matched option test', async () => { const { checker, lobby, ircClient } = await setup({ allow_convert: false, enabled: true, @@ -75,16 +75,16 @@ describe("Map Checker Tests", function () { }); - it("type mismatched option test", async () => { + it('type mismatched option test', async () => { const { checker, lobby, ircClient } = await setup({ - allow_convert: "false", + allow_convert: 'false', enabled: 1, - gamemode: "fruits", - length_max: "0", - length_min: "100", - num_violations_allowed: "1", - star_max: "0", - star_min: "3" + gamemode: 'fruits', + length_max: '0', + length_min: '100', + num_violations_allowed: '1', + star_max: '0', + star_min: '3' }); assert.equal(checker.option.allow_convert, false); @@ -98,12 +98,12 @@ describe("Map Checker Tests", function () { }); - it("conflicted option test", async () => { + it('conflicted option test', async () => { const { checker, lobby, ircClient } = await setup({ - length_max: "20", - length_min: "50", - star_max: "3", - star_min: "5" + length_max: '20', + length_min: '50', + star_max: '3', + star_min: '5' }); assert.equal(checker.option.length_max, 20); @@ -112,12 +112,12 @@ describe("Map Checker Tests", function () { assert.equal(checker.option.star_min, 0); }); - it("no max cap option test (not conflicted)", async () => { + it('no max cap option test (not conflicted)', async () => { const { checker, lobby, ircClient } = await setup({ - length_max: "0", - length_min: "50", - star_max: "0", - star_min: "5" + length_max: '0', + length_min: '50', + star_max: '0', + star_min: '5' }); assert.equal(checker.option.length_max, 0); @@ -126,12 +126,12 @@ describe("Map Checker Tests", function () { assert.equal(checker.option.star_min, 5); }); - it("no min cap option test (not conflicted)", async () => { + it('no min cap option test (not conflicted)', async () => { const { checker, lobby, ircClient } = await setup({ - length_max: "50", - length_min: "0", - star_max: "5", - star_min: "0" + length_max: '50', + length_min: '0', + star_max: '5', + star_min: '0' }); assert.equal(checker.option.length_max, 50); @@ -141,7 +141,7 @@ describe("Map Checker Tests", function () { }); - it("abolished option test", async () => { + it('abolished option test', async () => { const { checker, lobby, ircClient } = await setup({ allowConvert: false, num_violations_to_skip: 10, @@ -151,11 +151,11 @@ describe("Map Checker Tests", function () { assert.equal(checker.option.num_violations_allowed, 10); }); - it("invalid option test : allow_convert", async () => { + it('invalid option test : allow_convert', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ - allow_convert: "aaaa" + allow_convert: 'aaaa' }); } catch (e) { threw = true; @@ -163,11 +163,11 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : enabled", async () => { + it('invalid option test : enabled', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ - enabled: "aaaa" + enabled: 'aaaa' }); } catch (e) { threw = true; @@ -175,11 +175,11 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : gamemode aaaa", async () => { + it('invalid option test : gamemode aaaa', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ - gamemode: "aaaa" + gamemode: 'aaaa' }); } catch (e) { threw = true; @@ -187,11 +187,11 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : gamemode dsflkjsd", async () => { + it('invalid option test : gamemode dsflkjsd', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ - gamemode: "dsflkjsd" + gamemode: 'dsflkjsd' }); } catch (e) { threw = true; @@ -199,7 +199,7 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : gamemode 123456", async () => { + it('invalid option test : gamemode 123456', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ @@ -211,7 +211,7 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : length_max", async () => { + it('invalid option test : length_max', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ @@ -223,7 +223,7 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : length_min", async () => { + it('invalid option test : length_min', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ @@ -235,7 +235,7 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : num_violations_allowed", async () => { + it('invalid option test : num_violations_allowed', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ @@ -247,7 +247,7 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : star_max", async () => { + it('invalid option test : star_max', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ @@ -259,7 +259,7 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : star_min", async () => { + it('invalid option test : star_min', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ @@ -271,7 +271,7 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : number NaN", async () => { + it('invalid option test : number NaN', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ @@ -283,11 +283,11 @@ describe("Map Checker Tests", function () { assert.isTrue(threw); }); - it("invalid option test : number string", async () => { + it('invalid option test : number string', async () => { let threw = false; try { const { checker, lobby, ircClient } = await setup({ - star_min: "aaaa" + star_min: 'aaaa' }); } catch (e) { threw = true; @@ -296,363 +296,363 @@ describe("Map Checker Tests", function () { }); }); - describe("owner command tests", () => { - it("command: enabled ", async () => { + describe('owner command tests', () => { + it('command: enabled ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.enabled = true; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation enabled"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation enabled'); assert.equal(checker.option.enabled, true); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation disabled"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation disabled'); assert.equal(checker.option.enabled, false); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation enable"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation enable'); assert.equal(checker.option.enabled, true); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation disable"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation disable'); assert.equal(checker.option.enabled, false); }); - it("command: num_violations_allowed ", async () => { + it('command: num_violations_allowed ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.num_violations_allowed = 1; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_allowed 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_allowed 3'); assert.equal(checker.option.num_violations_allowed, 3); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_allowed 10"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_allowed 10'); assert.equal(checker.option.num_violations_allowed, 10); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_to_skip 5"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_to_skip 5'); assert.equal(checker.option.num_violations_allowed, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_allowed 0"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_allowed 0'); assert.equal(checker.option.num_violations_allowed, 0); - checker.option.num_violations_allowed = 10 - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_allowed"); + checker.option.num_violations_allowed = 10; + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_allowed'); assert.equal(checker.option.num_violations_allowed, 10); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_allowed asf"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_allowed asf'); assert.equal(checker.option.num_violations_allowed, 10); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_allowed NaN"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_allowed NaN'); assert.equal(checker.option.num_violations_allowed, 10); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation num_violations_to_skip"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation num_violations_to_skip'); assert.equal(checker.option.num_violations_allowed, 10); }); - it("command: star_min ", async () => { + it('command: star_min ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.star_min = 1; checker.option.star_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_min 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_min 3'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_min 0"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_min 0'); assert.equal(checker.option.star_min, 0); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_min 10"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_min 10'); assert.equal(checker.option.star_min, 10); assert.equal(checker.option.star_max, 0); checker.option.star_min = 1; checker.option.star_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation starmin 5 "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation starmin 5 '); assert.equal(checker.option.star_min, 5); assert.equal(checker.option.star_max, 0); checker.option.star_min = 1; checker.option.star_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation difflow 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation difflow 3'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 5); checker.option.star_min = 1; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_min -3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_min -3'); assert.equal(checker.option.star_min, 1); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_min"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_min'); assert.equal(checker.option.star_min, 1); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_min "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_min '); assert.equal(checker.option.star_min, 1); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_min a"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_min a'); assert.equal(checker.option.star_min, 1); assert.equal(checker.option.star_max, 5); }); - it("command: star_max ", async () => { + it('command: star_max ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.star_min = 3; checker.option.star_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max 4"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max 4'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 4); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max 0"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max 0'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 0); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max 10"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max 10'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 10); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max 2"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max 2'); assert.equal(checker.option.star_min, 0); assert.equal(checker.option.star_max, 2); checker.option.star_min = 3; checker.option.star_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation starmax 5 "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation starmax 5 '); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation diffupperlimit 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation diffupperlimit 3'); assert.equal(checker.option.star_min, 0); assert.equal(checker.option.star_max, 3); checker.option.star_min = 3; checker.option.star_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max -3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max -3'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max '); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation star_max a"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation star_max a'); assert.equal(checker.option.star_min, 3); assert.equal(checker.option.star_max, 5); }); - it("command: length_min ", async () => { + it('command: length_min ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.length_min = 1; checker.option.length_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_min 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_min 3'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_min 0"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_min 0'); assert.equal(checker.option.length_min, 0); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_min 10"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_min 10'); assert.equal(checker.option.length_min, 10); assert.equal(checker.option.length_max, 0); checker.option.length_min = 1; checker.option.length_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation lenmin 5 "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation lenmin 5 '); assert.equal(checker.option.length_min, 5); assert.equal(checker.option.length_max, 0); checker.option.length_min = 1; checker.option.length_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation lenlower 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation lenlower 3'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 5); checker.option.length_min = 1; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_min -3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_min -3'); assert.equal(checker.option.length_min, 1); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_min"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_min'); assert.equal(checker.option.length_min, 1); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_min "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_min '); assert.equal(checker.option.length_min, 1); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_min a"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_min a'); assert.equal(checker.option.length_min, 1); assert.equal(checker.option.length_max, 5); }); - it("command: length_max ", async () => { + it('command: length_max ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.length_min = 3; checker.option.length_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max 4"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max 4'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 4); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max 0"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max 0'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 0); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max 10"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max 10'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 10); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max 2"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max 2'); assert.equal(checker.option.length_min, 0); assert.equal(checker.option.length_max, 2); checker.option.length_min = 3; checker.option.length_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation lenmax 5 "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation lenmax 5 '); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation lenupperlimit 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation lenupperlimit 3'); assert.equal(checker.option.length_min, 0); assert.equal(checker.option.length_max, 3); checker.option.length_min = 3; checker.option.length_max = 5; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max -3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max -3'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max '); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 5); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation length_max a"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation length_max a'); assert.equal(checker.option.length_min, 3); assert.equal(checker.option.length_max, 5); }); - it("command: gamemode ", async () => { + it('command: gamemode ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); let initialValue = PlayMode.OsuMania; checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode osu"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode osu'); assert.equal(checker.option.gamemode, PlayMode.Osu); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode Osu"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode Osu'); assert.equal(checker.option.gamemode, PlayMode.Osu); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode 0"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode 0'); assert.equal(checker.option.gamemode, PlayMode.Osu); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode taiko"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode taiko'); assert.equal(checker.option.gamemode, PlayMode.Taiko); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode TAIKO"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode TAIKO'); assert.equal(checker.option.gamemode, PlayMode.Taiko); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode 1"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode 1'); assert.equal(checker.option.gamemode, PlayMode.Taiko); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode CatchTheBeat"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode CatchTheBeat'); assert.equal(checker.option.gamemode, PlayMode.CatchTheBeat); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode fruits"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode fruits'); assert.equal(checker.option.gamemode, PlayMode.CatchTheBeat); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode catch"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode catch'); assert.equal(checker.option.gamemode, PlayMode.CatchTheBeat); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode 2"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode 2'); assert.equal(checker.option.gamemode, PlayMode.CatchTheBeat); initialValue = PlayMode.Osu; checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode OsuMania"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode OsuMania'); assert.equal(checker.option.gamemode, PlayMode.OsuMania); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode mania"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode mania'); assert.equal(checker.option.gamemode, PlayMode.OsuMania); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode 3"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode 3'); assert.equal(checker.option.gamemode, PlayMode.OsuMania); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode'); assert.equal(checker.option.gamemode, initialValue); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode boss"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode boss'); assert.equal(checker.option.gamemode, initialValue); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode asfsdf "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode asfsdf '); assert.equal(checker.option.gamemode, initialValue); checker.option.gamemode = initialValue; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation gamemode * fdssdflk lsdf lksdfl3342r "); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation gamemode * fdssdflk lsdf lksdfl3342r '); assert.equal(checker.option.gamemode, initialValue); }); - it("command: allow_convert ", async () => { + it('command: allow_convert ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.allow_convert = false; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation allow_convert"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation allow_convert'); assert.equal(checker.option.allow_convert, true); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation disallow_convert"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation disallow_convert'); assert.equal(checker.option.allow_convert, false); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation allow_convert true"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation allow_convert true'); assert.equal(checker.option.allow_convert, true); - ircClient.emulateMessage("p1", ircClient.channel, "*regulation allow_convert false"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation allow_convert false'); assert.equal(checker.option.allow_convert, false); }); - it("command statement ", async () => { + it('command statement ', async () => { const { checker, lobby, ircClient } = await setup(); - lobby.GetOrMakePlayer("p1").setRole(Roles.Authorized); + lobby.GetOrMakePlayer('p1').setRole(Roles.Authorized); checker.option.allow_convert = false; - ircClient.emulateMessage("p1", ircClient.channel, "*regulation starmax=10 starmin=1 maxlen=100 lenmin = 20 gamemode= osu"); + ircClient.emulateMessage('p1', ircClient.channel, '*regulation starmax=10 starmin=1 maxlen=100 lenmin = 20 gamemode= osu'); assert.equal(checker.option.gamemode, PlayMode.Osu); assert.equal(checker.option.star_max, 10); @@ -662,85 +662,85 @@ describe("Map Checker Tests", function () { }); }); - describe("description tests", () => { - it("default config", async () => { + describe('description tests', () => { + it('default config', async () => { const { checker, lobby, ircClient } = await setup({ enabled: false, star_min: 0, star_max: 7.00, length_min: 0, length_max: 600, - gamemode: "osu", + gamemode: 'osu', num_violations_allowed: 3, allow_convert: true }); - assert.equal(checker.getRegulationDescription(), "Disabled (difficulty <= 7.00, length <= 10:00, mode: osu!)"); + assert.equal(checker.getRegulationDescription(), 'Disabled (difficulty <= 7.00, length <= 10:00, mode: osu!)'); }); - it("config", async () => { + it('config', async () => { const { checker, lobby, ircClient } = await setup({ enabled: true, star_min: 0, star_max: 0, length_min: 0, length_max: 0, - gamemode: "osu", + gamemode: 'osu', allow_convert: true }); - assert.equal(checker.getRegulationDescription(), "mode: osu!"); + assert.equal(checker.getRegulationDescription(), 'mode: osu!'); checker.option.gamemode = PlayMode.Taiko; checker.option.allow_convert = true; - assert.equal(checker.getRegulationDescription(), "mode: osu!taiko (converts allowed)"); + assert.equal(checker.getRegulationDescription(), 'mode: osu!taiko (converts allowed)'); checker.option.allow_convert = false; - assert.equal(checker.getRegulationDescription(), "mode: osu!taiko (converts disallowed)"); + assert.equal(checker.getRegulationDescription(), 'mode: osu!taiko (converts disallowed)'); checker.option.gamemode = PlayMode.CatchTheBeat; checker.option.allow_convert = true; - assert.equal(checker.getRegulationDescription(), "mode: osu!catch (converts allowed)"); + assert.equal(checker.getRegulationDescription(), 'mode: osu!catch (converts allowed)'); checker.option.allow_convert = false; - assert.equal(checker.getRegulationDescription(), "mode: osu!catch (converts disallowed)"); + assert.equal(checker.getRegulationDescription(), 'mode: osu!catch (converts disallowed)'); checker.option.gamemode = PlayMode.OsuMania; checker.option.allow_convert = true; - assert.equal(checker.getRegulationDescription(), "mode: osu!mania (converts allowed)"); + assert.equal(checker.getRegulationDescription(), 'mode: osu!mania (converts allowed)'); checker.option.allow_convert = false; - assert.equal(checker.getRegulationDescription(), "mode: osu!mania (converts disallowed)"); + assert.equal(checker.getRegulationDescription(), 'mode: osu!mania (converts disallowed)'); checker.option.gamemode = PlayMode.Osu; checker.option.star_max = 1; - assert.equal(checker.getRegulationDescription(), "difficulty <= 1.00, mode: osu!"); + assert.equal(checker.getRegulationDescription(), 'difficulty <= 1.00, mode: osu!'); checker.option.star_max = 0; checker.option.star_min = 1; - assert.equal(checker.getRegulationDescription(), "1.00 <= difficulty, mode: osu!"); + assert.equal(checker.getRegulationDescription(), '1.00 <= difficulty, mode: osu!'); checker.option.star_max = 2; checker.option.star_min = 1; - assert.equal(checker.getRegulationDescription(), "1.00 <= difficulty <= 2.00, mode: osu!"); + assert.equal(checker.getRegulationDescription(), '1.00 <= difficulty <= 2.00, mode: osu!'); checker.option.star_max = 0; checker.option.star_min = 0; checker.option.length_max = 60; - assert.equal(checker.getRegulationDescription(), "length <= 1:00, mode: osu!"); + assert.equal(checker.getRegulationDescription(), 'length <= 1:00, mode: osu!'); checker.option.length_max = 0; checker.option.length_min = 90; - assert.equal(checker.getRegulationDescription(), "1:30 <= length, mode: osu!"); + assert.equal(checker.getRegulationDescription(), '1:30 <= length, mode: osu!'); checker.option.length_max = 120; checker.option.length_min = 30; - assert.equal(checker.getRegulationDescription(), "0:30 <= length <= 2:00, mode: osu!"); + assert.equal(checker.getRegulationDescription(), '0:30 <= length <= 2:00, mode: osu!'); checker.option.star_max = 2; checker.option.star_min = 1; checker.option.length_max = 120; checker.option.length_min = 30; - assert.equal(checker.getRegulationDescription(), "1.00 <= difficulty <= 2.00, 0:30 <= length <= 2:00, mode: osu!"); + assert.equal(checker.getRegulationDescription(), '1.00 <= difficulty <= 2.00, 0:30 <= length <= 2:00, mode: osu!'); checker.option.enabled = false; - assert.equal(checker.getRegulationDescription(), "Disabled (1.00 <= difficulty <= 2.00, 0:30 <= length <= 2:00, mode: osu!)"); + assert.equal(checker.getRegulationDescription(), 'Disabled (1.00 <= difficulty <= 2.00, 0:30 <= length <= 2:00, mode: osu!)'); }); }); - describe("regulation check tests", () => { + describe('regulation check tests', () => { const originalFetcher = BeatmapRepository.fetcher; const fakeFetcher = new FakeBeatmapFetcher(); before(function () { @@ -750,17 +750,17 @@ describe("Map Checker Tests", function () { BeatmapRepository.fetcher = originalFetcher; }); - it("default settings test", async () => { + it('default settings test', async () => { const { checker, lobby, ircClient } = await setup({ enabled: true }); const mapid = 100; - fakeFetcher.setBeatmapProperties(mapid, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(mapid, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, mapid); assert.equal(checker.lastMapId, mapid); }); - it("star accept test", async () => { + it('star accept test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 5, star_min: 2, @@ -768,16 +768,16 @@ describe("Map Checker Tests", function () { length_min: 0, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 100); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 100, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 100, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 101); }); - it("star no limit accept test", async () => { + it('star no limit accept test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 2, @@ -785,16 +785,16 @@ describe("Map Checker Tests", function () { length_min: 0, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 100); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 100, 10); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 100, 10); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 101); }); - it("star reject test", async () => { + it('star reject test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 5, star_min: 2, @@ -802,16 +802,16 @@ describe("Map Checker Tests", function () { length_min: 0, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5.01); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5.01); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 0); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 100, 1.99); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 100, 1.99); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 0); }); - it("length accept test", async () => { + it('length accept test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 0, @@ -819,16 +819,16 @@ describe("Map Checker Tests", function () { length_min: 10, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 100); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 10, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 10, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 101); }); - it("length no limit accept test", async () => { + it('length no limit accept test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 0, @@ -836,16 +836,16 @@ describe("Map Checker Tests", function () { length_min: 10, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 100); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 10, 10); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 10, 10); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 101); }); - it("length reject test", async () => { + it('length reject test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 5, star_min: 2, @@ -853,16 +853,16 @@ describe("Map Checker Tests", function () { length_min: 10, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 101, 5.); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 101, 5.); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 0); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 9, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 9, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 0); }); - it("gamemode accept test", async () => { + it('gamemode accept test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 0, @@ -872,27 +872,27 @@ describe("Map Checker Tests", function () { allow_convert: false, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 100); checker.option.gamemode = PlayMode.Taiko; - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Taiko, 100, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Taiko, 100, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 101); checker.option.gamemode = PlayMode.CatchTheBeat; - fakeFetcher.setBeatmapProperties(102, "test", PlayMode.CatchTheBeat, 100, 2); + fakeFetcher.setBeatmapProperties(102, 'test', PlayMode.CatchTheBeat, 100, 2); await ircClient.emulateChangeMapAsync(0, 102); assert.equal(checker.lastMapId, 102); checker.option.gamemode = PlayMode.OsuMania; - fakeFetcher.setBeatmapProperties(103, "test", PlayMode.OsuMania, 100, 2); + fakeFetcher.setBeatmapProperties(103, 'test', PlayMode.OsuMania, 100, 2); await ircClient.emulateChangeMapAsync(0, 103); assert.equal(checker.lastMapId, 103); }); - it("gamemode allow convert accept test", async () => { + it('gamemode allow convert accept test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 0, @@ -902,27 +902,27 @@ describe("Map Checker Tests", function () { allow_convert: true, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 100); checker.option.gamemode = PlayMode.Taiko; - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 100, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 100, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 101); checker.option.gamemode = PlayMode.CatchTheBeat; - fakeFetcher.setBeatmapProperties(102, "test", PlayMode.Osu, 100, 2); + fakeFetcher.setBeatmapProperties(102, 'test', PlayMode.Osu, 100, 2); await ircClient.emulateChangeMapAsync(0, 102); assert.equal(checker.lastMapId, 102); checker.option.gamemode = PlayMode.OsuMania; - fakeFetcher.setBeatmapProperties(103, "test", PlayMode.Osu, 100, 2); + fakeFetcher.setBeatmapProperties(103, 'test', PlayMode.Osu, 100, 2); await ircClient.emulateChangeMapAsync(0, 103); assert.equal(checker.lastMapId, 103); }); - it("gamemode disallow convert reject test", async () => { + it('gamemode disallow convert reject test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 0, @@ -932,27 +932,27 @@ describe("Map Checker Tests", function () { allow_convert: false, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 100); checker.option.gamemode = PlayMode.Taiko; - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.Osu, 100, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.Osu, 100, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 100); checker.option.gamemode = PlayMode.CatchTheBeat; - fakeFetcher.setBeatmapProperties(102, "test", PlayMode.Osu, 100, 2); + fakeFetcher.setBeatmapProperties(102, 'test', PlayMode.Osu, 100, 2); await ircClient.emulateChangeMapAsync(0, 102); assert.equal(checker.lastMapId, 100); checker.option.gamemode = PlayMode.OsuMania; - fakeFetcher.setBeatmapProperties(103, "test", PlayMode.Osu, 100, 2); + fakeFetcher.setBeatmapProperties(103, 'test', PlayMode.Osu, 100, 2); await ircClient.emulateChangeMapAsync(0, 103); assert.equal(checker.lastMapId, 100); }); - it("gamemode ous reject test", async () => { + it('gamemode ous reject test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 0, @@ -962,20 +962,20 @@ describe("Map Checker Tests", function () { allow_convert: false, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Taiko, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Taiko, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 0); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.CatchTheBeat, 100, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.CatchTheBeat, 100, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 0); - fakeFetcher.setBeatmapProperties(102, "test", PlayMode.OsuMania, 100, 2); + fakeFetcher.setBeatmapProperties(102, 'test', PlayMode.OsuMania, 100, 2); await ircClient.emulateChangeMapAsync(0, 102); assert.equal(checker.lastMapId, 0); }); - it("gamemode ous reject test", async () => { + it('gamemode ous reject test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 0, star_min: 0, @@ -985,20 +985,20 @@ describe("Map Checker Tests", function () { allow_convert: false, enabled: true }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Taiko, 100, 5); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Taiko, 100, 5); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 0); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.CatchTheBeat, 100, 2); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.CatchTheBeat, 100, 2); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 0); - fakeFetcher.setBeatmapProperties(102, "test", PlayMode.OsuMania, 100, 2); + fakeFetcher.setBeatmapProperties(102, 'test', PlayMode.OsuMania, 100, 2); await ircClient.emulateChangeMapAsync(0, 102); assert.equal(checker.lastMapId, 0); }); - it("disalbed test", async () => { + it('disalbed test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 3, star_min: 2, @@ -1008,24 +1008,24 @@ describe("Map Checker Tests", function () { allow_convert: false, enabled: false }); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Taiko, 100, 15); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Taiko, 100, 15); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 0); assert.equal(checker.numViolations, 0); - fakeFetcher.setBeatmapProperties(101, "test", PlayMode.CatchTheBeat, 1000, 1); + fakeFetcher.setBeatmapProperties(101, 'test', PlayMode.CatchTheBeat, 1000, 1); await ircClient.emulateChangeMapAsync(0, 101); assert.equal(checker.lastMapId, 0); assert.equal(checker.numViolations, 0); - fakeFetcher.setBeatmapProperties(102, "test", PlayMode.OsuMania, 100, 5); + fakeFetcher.setBeatmapProperties(102, 'test', PlayMode.OsuMania, 100, 5); await ircClient.emulateChangeMapAsync(0, 102); assert.equal(checker.lastMapId, 0); assert.equal(checker.numViolations, 0); }); }); - describe("skip host tests", () => { + describe('skip host tests', () => { const originalFetcher = BeatmapRepository.fetcher; const fakeFetcher = new FakeBeatmapFetcher(); before(function () { @@ -1034,7 +1034,7 @@ describe("Map Checker Tests", function () { after(function () { BeatmapRepository.fetcher = originalFetcher; }); - it("num violation test", async () => { + it('num violation test', async () => { const { checker, lobby, ircClient } = await setup({ star_max: 5, star_min: 0, @@ -1044,9 +1044,9 @@ describe("Map Checker Tests", function () { allow_convert: false, enabled: true }); - await ircClient.emulateChangeHost("p1"); + await ircClient.emulateChangeHost('p1'); assert.equal(checker.numViolations, 0); - fakeFetcher.setBeatmapProperties(100, "test", PlayMode.Osu, 100, 6.55); + fakeFetcher.setBeatmapProperties(100, 'test', PlayMode.Osu, 100, 6.55); await ircClient.emulateChangeMapAsync(0, 100); assert.equal(checker.lastMapId, 0); assert.equal(checker.numViolations, 1); @@ -1059,7 +1059,7 @@ describe("Map Checker Tests", function () { assert.equal(checker.lastMapId, 0); assert.equal(checker.numViolations, 3); - await ircClient.emulateChangeHost("p2"); + await ircClient.emulateChangeHost('p2'); assert.equal(checker.numViolations, 0); }); }); diff --git a/src/tests/MapRecasterTest.ts b/src/tests/MapRecasterTest.ts index c9ed3878..e53e2f46 100644 --- a/src/tests/MapRecasterTest.ts +++ b/src/tests/MapRecasterTest.ts @@ -6,7 +6,7 @@ import { MapRecaster } from '../plugins/MapRecaster'; import tu from './TestUtils'; import { BanchoResponseType } from '../parsers/CommandParser'; -describe("Map Recaster Tests", function () { +describe('Map Recaster Tests', function () { before(function () { tu.configMochaAsSilent(); }); @@ -17,47 +17,47 @@ describe("Map Recaster Tests", function () { const ma = new MapRecaster(li.lobby); return { recaster: ma, ...li }; } - it("recast test", async () => { + it('recast test', async () => { const { recaster, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(3, ircClient); await ircClient.emulateChangeMapAsync(0); const mapid = lobby.mapId; const t1 = tu.assertBanchoRespond(lobby, BanchoResponseType.MpBeatmapChanged, (b => b.params[0] == mapid), 10); - ircClient.emulateMessage(players[0], ircClient.channel, "!update"); + ircClient.emulateMessage(players[0], ircClient.channel, '!update'); await t1; }); - it("request twice test", async () => { + it('request twice test', async () => { const { recaster, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(3, ircClient); await ircClient.emulateChangeMapAsync(0); const mapid = lobby.mapId; const t1 = tu.assertBanchoRespond(lobby, BanchoResponseType.MpBeatmapChanged, (b => b.params[0] == mapid), 10); - ircClient.emulateMessage(players[0], ircClient.channel, "!update"); + ircClient.emulateMessage(players[0], ircClient.channel, '!update'); await t1; const t2 = tu.assertBanchoNotRespond(lobby, BanchoResponseType.MpBeatmapChanged, (b => b.params[0] == mapid), 10); - ircClient.emulateMessage(players[1], ircClient.channel, "!update"); + ircClient.emulateMessage(players[1], ircClient.channel, '!update'); await t2; }); - it("can update every time player changes map", async () => { + it('can update every time player changes map', async () => { const { recaster, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(3, ircClient); await ircClient.emulateChangeMapAsync(0); let mapid = lobby.mapId; const t1 = tu.assertBanchoRespond(lobby, BanchoResponseType.MpBeatmapChanged, (b => b.params[0] == mapid), 10); - ircClient.emulateMessage(players[0], ircClient.channel, "!update"); + ircClient.emulateMessage(players[0], ircClient.channel, '!update'); await t1; await ircClient.emulateChangeMapAsync(0); mapid = lobby.mapId; const t2 = tu.assertBanchoRespond(lobby, BanchoResponseType.MpBeatmapChanged, (b => b.params[0] == mapid), 10); - ircClient.emulateMessage(players[1], ircClient.channel, "!update"); + ircClient.emulateMessage(players[1], ircClient.channel, '!update'); await t2; await ircClient.emulateChangeMapAsync(0); mapid = lobby.mapId; const t3 = tu.assertBanchoRespond(lobby, BanchoResponseType.MpBeatmapChanged, (b => b.params[0] == mapid), 10); - ircClient.emulateMessage(players[1], ircClient.channel, "!update"); + ircClient.emulateMessage(players[1], ircClient.channel, '!update'); await t3; }); }); diff --git a/src/tests/MatchAborterTest.ts b/src/tests/MatchAborterTest.ts index beba38c1..14834e24 100644 --- a/src/tests/MatchAborterTest.ts +++ b/src/tests/MatchAborterTest.ts @@ -5,7 +5,7 @@ import { DummyIrcClient } from '../dummies/DummyIrcClient'; import { MatchAborter, MatchAborterOption } from '../plugins/MatchAborter'; import tu from './TestUtils'; -describe("Match Aboter Tests", function () { +describe('Match Aboter Tests', function () { before(function () { tu.configMochaAsSilent(); }); @@ -25,12 +25,12 @@ describe("Match Aboter Tests", function () { return { aborter: ma, ...li }; } - it("construction test", async () => { + it('construction test', async () => { const { aborter, lobby, ircClient } = await setupAsync(); }); - describe("vote tests", function () { - it("vote required check", async () => { + describe('vote tests', function () { + it('vote required check', async () => { const { aborter, lobby, ircClient } = await setupAsync(); const md = 3; let tm = ircClient.emulateMatchAsync(md); @@ -68,76 +68,76 @@ describe("Match Aboter Tests", function () { tm = ircClient.emulateMatchAsync(md); assert.equal(aborter.voteRequired, 3); }); - it("host aborts the match", async () => { + it('host aborts the match', async () => { const { aborter, lobby, ircClient } = await setupAsync(50); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); ircClient.emulateMatchAsync(50); const et = tu.assertEventFire(lobby.AbortedMatch, null, 10); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!abort'); await et; }); - it("players abort the match", async () => { + it('players abort the match', async () => { const { aborter, lobby, ircClient } = await setupAsync(1000); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); ircClient.emulateMatchAsync(100); const et = tu.assertEventFire(lobby.AbortedMatch, null, 100); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 1); - await ircClient.emulateMessageAsync(players[2], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[2], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 2); await et; }); - it("the match won't be aborted if there are not enough votes", async () => { + it('the match won\'t be aborted if there are not enough votes', async () => { const { aborter, lobby, ircClient } = await setupAsync(50); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); ircClient.emulateMatchAsync(10); const et = tu.assertEventNeverFire(lobby.AbortedMatch, null, 10); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 1); await et; }); - it("double vote", async () => { + it('double vote', async () => { const { aborter, lobby, ircClient } = await setupAsync(50); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); ircClient.emulateMatchAsync(10); const et = tu.assertEventNeverFire(lobby.AbortedMatch, null, 10); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 1); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 1); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 1); await et; }); - it("authorized user aborts the match", async () => { + it('authorized user aborts the match', async () => { const { aborter, lobby, ircClient } = await setupAsync(50); const players = await tu.AddPlayersAsync(5, ircClient); lobby.GetOrMakePlayer(players[1]).setRole(Roles.Authorized); await tu.changeHostAsync(players[0], lobby); ircClient.emulateMatchAsync(10); const et = tu.assertEventFire(lobby.AbortedMatch, null, 10); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "*abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '*abort'); await et; }); - it("player leaving causes abort", async () => { + it('player leaving causes abort', async () => { const { aborter, lobby, ircClient } = await setupAsync(100); const players = await tu.AddPlayersAsync(7, ircClient); await tu.changeHostAsync(players[0], lobby); ircClient.emulateMatchAsync(100); const et = tu.assertEventFire(lobby.AbortedMatch, null, 100); assert.equal(aborter.voteRequired, 3); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 1); - await ircClient.emulateMessageAsync(players[2], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[2], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 2); await ircClient.emulateRemovePlayerAsync(players[3]); await et; }); - it("player joining during the match has no effect", async () => { + it('player joining during the match has no effect', async () => { const { aborter, lobby, ircClient } = await setupAsync(100); const players = await tu.AddPlayersAsync(6, ircClient); await tu.changeHostAsync(players[0], lobby); @@ -145,21 +145,21 @@ describe("Match Aboter Tests", function () { const et = tu.assertEventFire(lobby.AbortedMatch, null, 100); assert.equal(aborter.voteRequired, 2); assert.equal(lobby.playersInGame, 6); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 1); - await ircClient.emulateAddPlayerAsync("tom"); + await ircClient.emulateAddPlayerAsync('tom'); assert.equal(lobby.playersInGame, 6); assert.equal(aborter.voteRequired, 2); - await ircClient.emulateMessageAsync(players[2], ircClient.channel, "!abort"); + await ircClient.emulateMessageAsync(players[2], ircClient.channel, '!abort'); assert.equal(aborter.voting.count, 2); await et; }); }); - describe("auto abort tests", function () { - it("auto abort test", async () => { + describe('auto abort tests', function () { + it('auto abort test', async () => { const { aborter, lobby, ircClient } = await setupAsync(10); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); @@ -171,7 +171,7 @@ describe("Match Aboter Tests", function () { assert.isNotNull(aborter.abortTimer); await et; }); - it("dosen't abort the match if the match finished nomarlly", async () => { + it('dosen\'t abort the match if the match finished nomarlly', async () => { const { aborter, lobby, ircClient } = await setupAsync(10); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); @@ -185,7 +185,7 @@ describe("Match Aboter Tests", function () { tu.assertEventNeverFire(lobby.AbortedMatch, null, 10); await em2; }); - it("player leaving causes abort", async () => { + it('player leaving causes abort', async () => { const { aborter, lobby, ircClient } = await setupAsync(10); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); @@ -201,13 +201,13 @@ describe("Match Aboter Tests", function () { assert.isNotNull(aborter.abortTimer); await et; }); - it("player joining during the match has no effect", async () => { + it('player joining during the match has no effect', async () => { const { aborter, lobby, ircClient } = await setupAsync(10); const players = await tu.AddPlayersAsync(6, ircClient); await tu.changeHostAsync(players[0], lobby); ircClient.emulateMatchAsync(100); assert.equal(aborter.autoAbortRequired, 3); - await ircClient.emulateAddPlayerAsync("tom"); + await ircClient.emulateAddPlayerAsync('tom'); assert.equal(aborter.autoAbortRequired, 3); const et = tu.assertEventFire(lobby.AbortedMatch, null, 100); await ircClient.emulatePlayerFinishAsync(players[0]); diff --git a/src/tests/MatchStarterTest.ts b/src/tests/MatchStarterTest.ts index fcc50047..e2ea788d 100644 --- a/src/tests/MatchStarterTest.ts +++ b/src/tests/MatchStarterTest.ts @@ -5,7 +5,7 @@ import { DummyIrcClient } from '../dummies/DummyIrcClient'; import { BanchoResponseType } from '../parsers/CommandParser'; import { MatchStarter, MatchStarterOption } from '../plugins/MatchStarter'; import tu from './TestUtils'; -describe("MatchStarterTest", function () { +describe('MatchStarterTest', function () { before(function () { tu.configMochaAsSilent(); }); @@ -18,14 +18,14 @@ describe("MatchStarterTest", function () { vote_rate: rate, vote_msg_defer_ms: 0, start_when_all_player_ready: true - } - const starter = new MatchStarter(li.lobby, option) + }; + const starter = new MatchStarter(li.lobby, option); return { starter, ...li }; } async function assertSendMpStart(lobby: Lobby): Promise { return tu.assertEventFire(lobby.SentMessage, ({ message }) => { - return message.startsWith("!mp start"); + return message.startsWith('!mp start'); }); } @@ -48,7 +48,7 @@ describe("MatchStarterTest", function () { }, timeout); } - it("all player ready test", async () => { + it('all player ready test', async () => { const { starter, lobby, ircClient } = await setupAsync(); await tu.AddPlayersAsync(5, ircClient); assert.isFalse(lobby.isMatching); @@ -57,16 +57,16 @@ describe("MatchStarterTest", function () { await t; }); - describe("vote tests", function () { - it("required votes test", async () => { + describe('vote tests', function () { + it('required votes test', async () => { const { starter, lobby, ircClient } = await setupAsync(); for (let i = 1; i <= 16; i++) { - let ex = Math.max(Math.ceil(i * starter.option.vote_rate), starter.option.vote_min); + const ex = Math.max(Math.ceil(i * starter.option.vote_rate), starter.option.vote_min); await tu.AddPlayersAsync(1, ircClient); - assert.equal(starter.voting.required, ex, "players:" + i); + assert.equal(starter.voting.required, ex, 'players:' + i); } }); - it("vote test", async () => { + it('vote test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); @@ -74,23 +74,23 @@ describe("MatchStarterTest", function () { assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 0); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!start'); assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 1); - await ircClient.emulateMessageAsync(players[2], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[2], ircClient.channel, '!start'); assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 2); - await ircClient.emulateMessageAsync(players[3], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[3], ircClient.channel, '!start'); assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 3); - await ircClient.emulateMessageAsync(players[4], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[4], ircClient.channel, '!start'); assert.isTrue(lobby.isMatching); assert.equal(starter.voting.count, 0); }); - it("sould ignore when player vote twice", async () => { + it('sould ignore when player vote twice', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); @@ -98,22 +98,22 @@ describe("MatchStarterTest", function () { assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 0); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!start'); assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 1); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!start'); assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 1); }); - it("shold reset when host changed", async () => { + it('shold reset when host changed', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!start"); - await ircClient.emulateMessageAsync(players[2], ircClient.channel, "!start"); - await ircClient.emulateMessageAsync(players[3], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!start'); + await ircClient.emulateMessageAsync(players[2], ircClient.channel, '!start'); + await ircClient.emulateMessageAsync(players[3], ircClient.channel, '!start'); assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 3); @@ -121,16 +121,16 @@ describe("MatchStarterTest", function () { assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 0); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start'); assert.isFalse(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 1); // host vote - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!start'); assert.isTrue(lobby.isMatching); }); - it("shold ignore vote when matching", async () => { + it('shold ignore vote when matching', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); @@ -140,8 +140,8 @@ describe("MatchStarterTest", function () { assert.isTrue(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 0); - for (let p of players) { - await ircClient.emulateMessageAsync(p, ircClient.channel, "!start"); + for (const p of players) { + await ircClient.emulateMessageAsync(p, ircClient.channel, '!start'); assert.isTrue(lobby.isMatching); assert.isFalse(starter.voting.passed); assert.equal(starter.voting.count, 0); @@ -149,102 +149,102 @@ describe("MatchStarterTest", function () { return t; }); }); - describe("host and auth command tests", function () { - it("host !start test", async () => { + describe('host and auth command tests', function () { + it('host !start test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start'); assert.isTrue(lobby.isMatching); }); - it("host !mp start test", async () => { + it('host !mp start test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!mp start"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!mp start'); assert.isTrue(lobby.isMatching); }); - it("auth *start test", async () => { + it('auth *start test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); lobby.GetOrMakePlayer(players[0]).setRole(Roles.Authorized); await tu.changeHostAsync(players[1], lobby); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "*start"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '*start'); assert.isTrue(lobby.isMatching); }); - it("player *start test", async () => { + it('player *start test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[1], lobby); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "*start"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '*start'); assert.isFalse(lobby.isMatching); }); }); - describe("start timer tests", function () { - it("!start timer test", async () => { + describe('start timer tests', function () { + it('!start timer test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start 30"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start 30'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isTrue(starter.IsSelfStartTimerActive); }); - it("!start timer 0 test", async () => { + it('!start timer 0 test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start 0"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start 0'); assert.isTrue(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); }); - it("!start timer with negative | NaN test", async () => { + it('!start timer with negative | NaN test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); const t = assertNeverBeginTimer(lobby, 10); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start -100"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start -100'); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start -454212"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start -454212'); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start -"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start -'); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start -0"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start -0'); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start aaa"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start aaa'); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start 10 aaa"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start 10 aaa'); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start aaa sdfa"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start aaa sdfa'); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start *231sd"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start *231sd'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); }); - it("!start timer from player test", async () => { + it('!start timer from player test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!start 100"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!start 100'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); }); - it("!start timer from auth player test", async () => { + it('!start timer from auth player test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); lobby.GetOrMakePlayer(players[0]).setRole(Roles.Authorized); @@ -252,49 +252,49 @@ describe("MatchStarterTest", function () { assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start 30"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start 30'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isTrue(starter.IsSelfStartTimerActive); }); - it("!stop test", async () => { + it('!stop test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start 30"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start 30'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isTrue(starter.IsSelfStartTimerActive); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!stop"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!stop'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); }); - it("!stop from player test", async () => { + it('!stop from player test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isFalse(starter.IsSelfStartTimerActive); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!start 30"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!start 30'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isTrue(starter.IsSelfStartTimerActive); - await ircClient.emulateMessageAsync(players[1], ircClient.channel, "!stop"); + await ircClient.emulateMessageAsync(players[1], ircClient.channel, '!stop'); assert.isFalse(lobby.isMatching); assert.isFalse(lobby.isStartTimerActive); assert.isTrue(starter.IsSelfStartTimerActive); }); }); - it("with help test", async () => { + it('with help test', async () => { const { starter, lobby, ircClient } = await setupAsync(); const players = await tu.AddPlayersAsync(5, ircClient); await tu.changeHostAsync(players[0], lobby); - starter.SendPluginMessage("mp_start", ["30", "withhelp"]); + starter.SendPluginMessage('mp_start', ['30', 'withhelp']); }); }); diff --git a/src/tests/MpSettingsParserTest.ts b/src/tests/MpSettingsParserTest.ts index b974fd5b..0a98c782 100644 --- a/src/tests/MpSettingsParserTest.ts +++ b/src/tests/MpSettingsParserTest.ts @@ -5,52 +5,52 @@ import { MpSettingsCases } from './cases/MpSettingsCases'; import log4js from 'log4js'; -describe("MpSettingsParserTest", function () { +describe('MpSettingsParserTest', function () { before(function () { - log4js.configure("config/log_mocha_silent.json"); + log4js.configure('config/log_mocha_silent.json'); }); - it("mp settings parse test", () => { + it('mp settings parse test', () => { const p = new MpSettingsParser(); - let b: boolean = false; + const b: boolean = false; assert.isFalse(p.isParsing); assert.isFalse(p.isParsed); - assert.isTrue(p.feedLine("Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403")); + assert.isTrue(p.feedLine('Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403')); assert.isTrue(p.isParsing); assert.isFalse(p.isParsed); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: Freemod")); - assert.isTrue(p.feedLine("Players: 5")); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: Freemod')); + assert.isTrue(p.feedLine('Players: 5')); assert.isTrue(p.isParsing); assert.isFalse(p.isParsed); - assert.isFalse(p.feedLine("hello!")); + assert.isFalse(p.feedLine('hello!')); assert.isTrue(p.isParsing); assert.isFalse(p.isParsed); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host]")); - assert.isTrue(p.feedLine("Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [Hidden, DoubleTime]")); - assert.isTrue(p.feedLine("Slot 3 Not Ready https://osu.ppy.sh/u/13745792 Seidosam ")); - assert.isTrue(p.feedLine("Slot 4 Not Ready https://osu.ppy.sh/u/7354213 Suitaksas ")); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host]')); + assert.isTrue(p.feedLine('Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [Hidden, DoubleTime]')); + assert.isTrue(p.feedLine('Slot 3 Not Ready https://osu.ppy.sh/u/13745792 Seidosam ')); + assert.isTrue(p.feedLine('Slot 4 Not Ready https://osu.ppy.sh/u/7354213 Suitaksas ')); assert.isTrue(p.isParsing); - assert.isTrue(p.feedLine("Slot 5 Not Ready https://osu.ppy.sh/u/13585495 -Kasell ")); + assert.isTrue(p.feedLine('Slot 5 Not Ready https://osu.ppy.sh/u/13585495 -Kasell ')); assert.isFalse(p.isParsing); assert.isTrue(p.isParsed); assert.isNotNull(p.result); const r = p.result as MpSettingsResult; - assert.equal(r.name, "5* (´・ω・`) host rotate"); - assert.equal(r.history, "https://osu.ppy.sh/mp/53084403"); - assert.equal(r.beatmapUrl, "https://osu.ppy.sh/b/853167"); - assert.equal(r.beatmapTitle, "Silent Siren - Hachigatsu no Yoru [August]"); - assert.equal(r.teamMode, "HeadToHead"); - assert.equal(r.winCondition, "Score"); - assert.equal(r.activeMods, "Freemod"); + assert.equal(r.name, '5* (´・ω・`) host rotate'); + assert.equal(r.history, 'https://osu.ppy.sh/mp/53084403'); + assert.equal(r.beatmapUrl, 'https://osu.ppy.sh/b/853167'); + assert.equal(r.beatmapTitle, 'Silent Siren - Hachigatsu no Yoru [August]'); + assert.equal(r.teamMode, 'HeadToHead'); + assert.equal(r.winCondition, 'Score'); + assert.equal(r.activeMods, 'Freemod'); assert.equal(r.players.length, 5); - assert.equal(r.players[0].name, "gnsksz"); - assert.equal(r.players[1].name, "Discuzz"); - assert.equal(r.players[2].name, "Seidosam"); - assert.equal(r.players[3].name, "Suitaksas"); - assert.equal(r.players[4].name, "-Kasell"); + assert.equal(r.players[0].name, 'gnsksz'); + assert.equal(r.players[1].name, 'Discuzz'); + assert.equal(r.players[2].name, 'Seidosam'); + assert.equal(r.players[3].name, 'Suitaksas'); + assert.equal(r.players[4].name, '-Kasell'); assert.equal(r.players[0].id, 8286882); assert.equal(r.players[1].id, 10351992); assert.equal(r.players[2].id, 13745792); @@ -66,41 +66,41 @@ describe("MpSettingsParserTest", function () { assert.equal(r.players[2].team, Teams.None); assert.equal(r.players[3].team, Teams.None); assert.equal(r.players[4].team, Teams.None); - assert.equal(r.players[0].options, "Host"); - assert.equal(r.players[1].options, "Hidden, DoubleTime"); - assert.equal(r.players[2].options, ""); - assert.equal(r.players[3].options, ""); - assert.equal(r.players[4].options, ""); + assert.equal(r.players[0].options, 'Host'); + assert.equal(r.players[1].options, 'Hidden, DoubleTime'); + assert.equal(r.players[2].options, ''); + assert.equal(r.players[3].options, ''); + assert.equal(r.players[4].options, ''); }); - it("mp settings parse with space test", () => { + it('mp settings parse with space test', () => { const p = new MpSettingsParser(); - assert.isTrue(p.feedLine("Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: Freemod")); - assert.isTrue(p.feedLine("Players: 5")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gns ksz [Host]")); - assert.isTrue(p.feedLine("Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [Hidden, DoubleTime]")); - assert.isTrue(p.feedLine("Slot 3 Not Ready https://osu.ppy.sh/u/13745792 Seido sam ")); - assert.isTrue(p.feedLine("Slot 4 Not Ready https://osu.ppy.sh/u/7354213 Suitaksas ")); - assert.isTrue(p.feedLine("Slot 5 Not Ready https://osu.ppy.sh/u/13585495 -Kasell ")); + assert.isTrue(p.feedLine('Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: Freemod')); + assert.isTrue(p.feedLine('Players: 5')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gns ksz [Host]')); + assert.isTrue(p.feedLine('Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [Hidden, DoubleTime]')); + assert.isTrue(p.feedLine('Slot 3 Not Ready https://osu.ppy.sh/u/13745792 Seido sam ')); + assert.isTrue(p.feedLine('Slot 4 Not Ready https://osu.ppy.sh/u/7354213 Suitaksas ')); + assert.isTrue(p.feedLine('Slot 5 Not Ready https://osu.ppy.sh/u/13585495 -Kasell ')); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r = p.result as MpSettingsResult; - assert.equal(r.name, "5* (´・ω・`) host rotate"); - assert.equal(r.history, "https://osu.ppy.sh/mp/53084403"); - assert.equal(r.beatmapUrl, "https://osu.ppy.sh/b/853167"); - assert.equal(r.beatmapTitle, "Silent Siren - Hachigatsu no Yoru [August]"); - assert.equal(r.teamMode, "HeadToHead"); - assert.equal(r.winCondition, "Score"); - assert.equal(r.activeMods, "Freemod"); + assert.equal(r.name, '5* (´・ω・`) host rotate'); + assert.equal(r.history, 'https://osu.ppy.sh/mp/53084403'); + assert.equal(r.beatmapUrl, 'https://osu.ppy.sh/b/853167'); + assert.equal(r.beatmapTitle, 'Silent Siren - Hachigatsu no Yoru [August]'); + assert.equal(r.teamMode, 'HeadToHead'); + assert.equal(r.winCondition, 'Score'); + assert.equal(r.activeMods, 'Freemod'); assert.equal(r.players.length, 5); - assert.equal(r.players[0].name, "gns ksz"); - assert.equal(r.players[1].name, "Discuzz"); - assert.equal(r.players[2].name, "Seido sam"); - assert.equal(r.players[3].name, "Suitaksas"); - assert.equal(r.players[4].name, "-Kasell"); + assert.equal(r.players[0].name, 'gns ksz'); + assert.equal(r.players[1].name, 'Discuzz'); + assert.equal(r.players[2].name, 'Seido sam'); + assert.equal(r.players[3].name, 'Suitaksas'); + assert.equal(r.players[4].name, '-Kasell'); assert.equal(r.players[0].id, 8286882); assert.equal(r.players[1].id, 10351992); assert.equal(r.players[2].id, 13745792); @@ -111,40 +111,40 @@ describe("MpSettingsParserTest", function () { assert.equal(r.players[2].isHost, false); assert.equal(r.players[3].isHost, false); assert.equal(r.players[4].isHost, false); - assert.equal(r.players[0].options, "Host"); + assert.equal(r.players[0].options, 'Host'); assert.equal(r.players[0].team, Teams.None); - assert.equal(r.players[1].options, "Hidden, DoubleTime"); + assert.equal(r.players[1].options, 'Hidden, DoubleTime'); }); - it("mp settings parse with blackets test", () => { + it('mp settings parse with blackets test', () => { const p = new MpSettingsParser(); - assert.isTrue(p.feedLine("Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: Freemod")); - assert.isTrue(p.feedLine("Players: 5")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz[aueie] [Host]")); - assert.isTrue(p.feedLine("Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [as]v [Hidden, DoubleTime]")); - assert.isTrue(p.feedLine("Slot 3 Not Ready https://osu.ppy.sh/u/13745792 Sedo sam [quit] ")); - assert.isTrue(p.feedLine("Slot 4 Not Ready https://osu.ppy.sh/u/7354213 Suit[__]aksas ")); - assert.isTrue(p.feedLine("Slot 5 Not Ready https://osu.ppy.sh/u/13585495 -K][][a sell ")); + assert.isTrue(p.feedLine('Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: Freemod')); + assert.isTrue(p.feedLine('Players: 5')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz[aueie] [Host]')); + assert.isTrue(p.feedLine('Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [as]v [Hidden, DoubleTime]')); + assert.isTrue(p.feedLine('Slot 3 Not Ready https://osu.ppy.sh/u/13745792 Sedo sam [quit] ')); + assert.isTrue(p.feedLine('Slot 4 Not Ready https://osu.ppy.sh/u/7354213 Suit[__]aksas ')); + assert.isTrue(p.feedLine('Slot 5 Not Ready https://osu.ppy.sh/u/13585495 -K][][a sell ')); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r = p.result as MpSettingsResult; - assert.equal(r.name, "5* (´・ω・`) host rotate"); - assert.equal(r.history, "https://osu.ppy.sh/mp/53084403"); - assert.equal(r.beatmapUrl, "https://osu.ppy.sh/b/853167"); - assert.equal(r.beatmapTitle, "Silent Siren - Hachigatsu no Yoru [August]"); - assert.equal(r.teamMode, "HeadToHead"); - assert.equal(r.winCondition, "Score"); - assert.equal(r.activeMods, "Freemod"); + assert.equal(r.name, '5* (´・ω・`) host rotate'); + assert.equal(r.history, 'https://osu.ppy.sh/mp/53084403'); + assert.equal(r.beatmapUrl, 'https://osu.ppy.sh/b/853167'); + assert.equal(r.beatmapTitle, 'Silent Siren - Hachigatsu no Yoru [August]'); + assert.equal(r.teamMode, 'HeadToHead'); + assert.equal(r.winCondition, 'Score'); + assert.equal(r.activeMods, 'Freemod'); assert.equal(r.players.length, 5); - assert.equal(r.players[0].name, "gnsksz[aueie]"); - assert.equal(r.players[1].name, "Discuzz [as]v"); - assert.equal(r.players[2].name, "Sedo sam [quit]"); - assert.equal(r.players[3].name, "Suit[__]aksas"); - assert.equal(r.players[4].name, "-K][][a sell"); + assert.equal(r.players[0].name, 'gnsksz[aueie]'); + assert.equal(r.players[1].name, 'Discuzz [as]v'); + assert.equal(r.players[2].name, 'Sedo sam [quit]'); + assert.equal(r.players[3].name, 'Suit[__]aksas'); + assert.equal(r.players[4].name, '-K][][a sell'); assert.equal(r.players[0].id, 8286882); assert.equal(r.players[1].id, 10351992); assert.equal(r.players[2].id, 13745792); @@ -155,40 +155,40 @@ describe("MpSettingsParserTest", function () { assert.equal(r.players[2].isHost, false); assert.equal(r.players[3].isHost, false); assert.equal(r.players[4].isHost, false); - assert.equal(r.players[0].options, "Host"); - assert.equal(r.players[1].options, "Hidden, DoubleTime"); + assert.equal(r.players[0].options, 'Host'); + assert.equal(r.players[1].options, 'Hidden, DoubleTime'); }); - it("mp settings none orderd slot test", () => { + it('mp settings none orderd slot test', () => { const p = new MpSettingsParser(); - assert.isTrue(p.feedLine("Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: Freemod")); - assert.isTrue(p.feedLine("Players: 5")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host]")); - assert.isTrue(p.feedLine("Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [Hidden, DoubleTime]")); - assert.isTrue(p.feedLine("Slot 6 Not Ready https://osu.ppy.sh/u/13745792 Seidosam ")); - assert.isTrue(p.feedLine("Slot 9 Not Ready https://osu.ppy.sh/u/7354213 Suitaksas ")); - assert.isTrue(p.feedLine("Slot 12 Not Ready https://osu.ppy.sh/u/13585495 -Kasell ")); + assert.isTrue(p.feedLine('Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: Freemod')); + assert.isTrue(p.feedLine('Players: 5')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host]')); + assert.isTrue(p.feedLine('Slot 2 Not Ready https://osu.ppy.sh/u/10351992 Discuzz [Hidden, DoubleTime]')); + assert.isTrue(p.feedLine('Slot 6 Not Ready https://osu.ppy.sh/u/13745792 Seidosam ')); + assert.isTrue(p.feedLine('Slot 9 Not Ready https://osu.ppy.sh/u/7354213 Suitaksas ')); + assert.isTrue(p.feedLine('Slot 12 Not Ready https://osu.ppy.sh/u/13585495 -Kasell ')); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r = p.result as MpSettingsResult; - assert.equal(r.name, "5* (´・ω・`) host rotate"); - assert.equal(r.history, "https://osu.ppy.sh/mp/53084403"); - assert.equal(r.beatmapUrl, "https://osu.ppy.sh/b/853167"); - assert.equal(r.beatmapTitle, "Silent Siren - Hachigatsu no Yoru [August]"); - assert.equal(r.teamMode, "HeadToHead"); - assert.equal(r.winCondition, "Score"); - assert.equal(r.activeMods, "Freemod"); + assert.equal(r.name, '5* (´・ω・`) host rotate'); + assert.equal(r.history, 'https://osu.ppy.sh/mp/53084403'); + assert.equal(r.beatmapUrl, 'https://osu.ppy.sh/b/853167'); + assert.equal(r.beatmapTitle, 'Silent Siren - Hachigatsu no Yoru [August]'); + assert.equal(r.teamMode, 'HeadToHead'); + assert.equal(r.winCondition, 'Score'); + assert.equal(r.activeMods, 'Freemod'); assert.equal(r.players.length, 5); - assert.equal(r.players[0].name, "gnsksz"); - assert.equal(r.players[1].name, "Discuzz"); - assert.equal(r.players[2].name, "Seidosam"); - assert.equal(r.players[3].name, "Suitaksas"); - assert.equal(r.players[4].name, "-Kasell"); + assert.equal(r.players[0].name, 'gnsksz'); + assert.equal(r.players[1].name, 'Discuzz'); + assert.equal(r.players[2].name, 'Seidosam'); + assert.equal(r.players[3].name, 'Suitaksas'); + assert.equal(r.players[4].name, '-Kasell'); assert.equal(r.players[0].id, 8286882); assert.equal(r.players[1].id, 10351992); assert.equal(r.players[2].id, 13745792); @@ -199,42 +199,42 @@ describe("MpSettingsParserTest", function () { assert.equal(r.players[2].isHost, false); assert.equal(r.players[3].isHost, false); assert.equal(r.players[4].isHost, false); - assert.equal(r.players[0].options, "Host"); - assert.equal(r.players[1].options, "Hidden, DoubleTime"); + assert.equal(r.players[0].options, 'Host'); + assert.equal(r.players[1].options, 'Hidden, DoubleTime'); }); - it("mp settings long name (15 characters)", () => { + it('mp settings long name (15 characters)', () => { const p = new MpSettingsParser(); - assert.isTrue(p.feedLine("Room name: 4-5* auto host rotaion, History: https://osu.ppy.sh/mp/54581109")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/1418503 tofubeats - CANDYYYLAND feat LIZ - Pa's Lam System Remix [Nathan's Extra]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: Freemod")); - assert.isTrue(p.feedLine("Players: 8")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/1 0123456789abcde ")); - assert.isTrue(p.feedLine("Slot 2 No Map https://osu.ppy.sh/u/2 ZhiZhaChn [acv] [Hidden]")); - assert.isTrue(p.feedLine("Slot 3 Not Ready https://osu.ppy.sh/u/3 Hot Cocoa ")); - assert.isTrue(p.feedLine("Slot 4 Not Ready https://osu.ppy.sh/u/4 POv2II ")); - assert.isTrue(p.feedLine("Slot 6 Not Ready https://osu.ppy.sh/u/5 MONTBLANC_heart [Host]")); - assert.isTrue(p.feedLine("Slot 8 No Map https://osu.ppy.sh/u/6 NewRecruit_Jack ")); - assert.isTrue(p.feedLine("Slot 9 No Map https://osu.ppy.sh/u/7 ya nunta ")); - assert.isTrue(p.feedLine("Slot 16 Not Ready https://osu.ppy.sh/u/8 Jow [Hidden]")); + assert.isTrue(p.feedLine('Room name: 4-5* auto host rotaion, History: https://osu.ppy.sh/mp/54581109')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/1418503 tofubeats - CANDYYYLAND feat LIZ - Pa\'s Lam System Remix [Nathan\'s Extra]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: Freemod')); + assert.isTrue(p.feedLine('Players: 8')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/1 0123456789abcde ')); + assert.isTrue(p.feedLine('Slot 2 No Map https://osu.ppy.sh/u/2 ZhiZhaChn [acv] [Hidden]')); + assert.isTrue(p.feedLine('Slot 3 Not Ready https://osu.ppy.sh/u/3 Hot Cocoa ')); + assert.isTrue(p.feedLine('Slot 4 Not Ready https://osu.ppy.sh/u/4 POv2II ')); + assert.isTrue(p.feedLine('Slot 6 Not Ready https://osu.ppy.sh/u/5 MONTBLANC_heart [Host]')); + assert.isTrue(p.feedLine('Slot 8 No Map https://osu.ppy.sh/u/6 NewRecruit_Jack ')); + assert.isTrue(p.feedLine('Slot 9 No Map https://osu.ppy.sh/u/7 ya nunta ')); + assert.isTrue(p.feedLine('Slot 16 Not Ready https://osu.ppy.sh/u/8 Jow [Hidden]')); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r = p.result as MpSettingsResult; - assert.equal(r.name, "4-5* auto host rotaion"); - assert.equal(r.history, "https://osu.ppy.sh/mp/54581109"); - assert.equal(r.beatmapUrl, "https://osu.ppy.sh/b/1418503"); - assert.equal(r.beatmapTitle, "tofubeats - CANDYYYLAND feat LIZ - Pa's Lam System Remix [Nathan's Extra]"); - assert.equal(r.teamMode, "HeadToHead"); - assert.equal(r.winCondition, "Score"); - assert.equal(r.activeMods, "Freemod"); + assert.equal(r.name, '4-5* auto host rotaion'); + assert.equal(r.history, 'https://osu.ppy.sh/mp/54581109'); + assert.equal(r.beatmapUrl, 'https://osu.ppy.sh/b/1418503'); + assert.equal(r.beatmapTitle, 'tofubeats - CANDYYYLAND feat LIZ - Pa\'s Lam System Remix [Nathan\'s Extra]'); + assert.equal(r.teamMode, 'HeadToHead'); + assert.equal(r.winCondition, 'Score'); + assert.equal(r.activeMods, 'Freemod'); assert.equal(r.players.length, 8); - assert.equal(r.players[0].name, "0123456789abcde"); - assert.equal(r.players[1].name, "ZhiZhaChn [acv]"); - assert.equal(r.players[2].name, "Hot Cocoa"); - assert.equal(r.players[3].name, "POv2II"); - assert.equal(r.players[4].name, "MONTBLANC_heart"); + assert.equal(r.players[0].name, '0123456789abcde'); + assert.equal(r.players[1].name, 'ZhiZhaChn [acv]'); + assert.equal(r.players[2].name, 'Hot Cocoa'); + assert.equal(r.players[3].name, 'POv2II'); + assert.equal(r.players[4].name, 'MONTBLANC_heart'); assert.equal(r.players[0].id, 1); assert.equal(r.players[1].id, 2); assert.equal(r.players[2].id, 3); @@ -245,105 +245,105 @@ describe("MpSettingsParserTest", function () { assert.equal(r.players[2].isHost, false); assert.equal(r.players[3].isHost, false); assert.equal(r.players[4].isHost, true); - assert.equal(r.players[1].options, "Hidden"); - assert.equal(r.players[4].options, "Host"); - assert.equal(r.players[7].options, "Hidden"); + assert.equal(r.players[1].options, 'Hidden'); + assert.equal(r.players[4].options, 'Host'); + assert.equal(r.players[7].options, 'Hidden'); }); - it("mp settings host and mods", () => { + it('mp settings host and mods', () => { const p = new MpSettingsParser(); - assert.isTrue(p.feedLine("Room name: ahr test, History: https://osu.ppy.sh/mp/54598622")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/86920 SID - Ranbu no Melody (TV Size) [Happy's Insane]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: DoubleTime, Freemod")); - assert.isTrue(p.feedLine("Players: 1")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host / Hidden, HardRock]")); + assert.isTrue(p.feedLine('Room name: ahr test, History: https://osu.ppy.sh/mp/54598622')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/86920 SID - Ranbu no Melody (TV Size) [Happy\'s Insane]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: DoubleTime, Freemod')); + assert.isTrue(p.feedLine('Players: 1')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host / Hidden, HardRock]')); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r = p.result as MpSettingsResult; - assert.equal(r.teamMode, "HeadToHead"); - assert.equal(r.winCondition, "Score"); - assert.equal(r.activeMods, "DoubleTime, Freemod"); + assert.equal(r.teamMode, 'HeadToHead'); + assert.equal(r.winCondition, 'Score'); + assert.equal(r.activeMods, 'DoubleTime, Freemod'); assert.equal(r.players.length, 1); - assert.equal(r.players[0].name, "gnsksz"); + assert.equal(r.players[0].name, 'gnsksz'); assert.equal(r.players[0].isHost, true); - assert.equal(r.players[0].options, "Host / Hidden, HardRock"); + assert.equal(r.players[0].options, 'Host / Hidden, HardRock'); }); - it("mp settings twice", () => { + it('mp settings twice', () => { const p = new MpSettingsParser(); - assert.isTrue(p.feedLine("Room name: ahr test, History: https://osu.ppy.sh/mp/54598622")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/86920 SID - Ranbu no Melody (TV Size) [Happy's Insane]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: DoubleTime, Freemod")); - assert.isTrue(p.feedLine("Players: 1")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host / Hidden, HardRock]")); + assert.isTrue(p.feedLine('Room name: ahr test, History: https://osu.ppy.sh/mp/54598622')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/86920 SID - Ranbu no Melody (TV Size) [Happy\'s Insane]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: DoubleTime, Freemod')); + assert.isTrue(p.feedLine('Players: 1')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host / Hidden, HardRock]')); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r1 = p.result as MpSettingsResult; - assert.equal(r1.teamMode, "HeadToHead"); - assert.equal(r1.winCondition, "Score"); - assert.equal(r1.activeMods, "DoubleTime, Freemod"); + assert.equal(r1.teamMode, 'HeadToHead'); + assert.equal(r1.winCondition, 'Score'); + assert.equal(r1.activeMods, 'DoubleTime, Freemod'); assert.equal(r1.players.length, 1); - assert.equal(r1.players[0].name, "gnsksz"); + assert.equal(r1.players[0].name, 'gnsksz'); assert.equal(r1.players[0].id, 8286882); assert.equal(r1.players[0].isHost, true); - assert.equal(r1.players[0].options, "Host / Hidden, HardRock"); + assert.equal(r1.players[0].options, 'Host / Hidden, HardRock'); assert.isTrue(p.isParsed); assert.isFalse(p.isParsing); - assert.isTrue(p.feedLine("Room name: 4-5* auto host rotaion, History: https://osu.ppy.sh/mp/54581109")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/1418503 tofubeats - CANDYYYLAND feat LIZ - Pa's Lam System Remix [Nathan's Extra]")); - assert.isTrue(p.feedLine("Team mode: HeadToHead, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: Freemod")); - assert.isTrue(p.feedLine("Players: 1")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/2 0123456789abcde ")); + assert.isTrue(p.feedLine('Room name: 4-5* auto host rotaion, History: https://osu.ppy.sh/mp/54581109')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/1418503 tofubeats - CANDYYYLAND feat LIZ - Pa\'s Lam System Remix [Nathan\'s Extra]')); + assert.isTrue(p.feedLine('Team mode: HeadToHead, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: Freemod')); + assert.isTrue(p.feedLine('Players: 1')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/2 0123456789abcde ')); assert.isTrue(p.isParsed); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r2 = p.result as MpSettingsResult; - assert.equal(r2.name, "4-5* auto host rotaion"); - assert.equal(r2.history, "https://osu.ppy.sh/mp/54581109"); - assert.equal(r2.beatmapUrl, "https://osu.ppy.sh/b/1418503"); - assert.equal(r2.beatmapTitle, "tofubeats - CANDYYYLAND feat LIZ - Pa's Lam System Remix [Nathan's Extra]"); - assert.equal(r2.teamMode, "HeadToHead"); - assert.equal(r2.winCondition, "Score"); - assert.equal(r2.activeMods, "Freemod"); + assert.equal(r2.name, '4-5* auto host rotaion'); + assert.equal(r2.history, 'https://osu.ppy.sh/mp/54581109'); + assert.equal(r2.beatmapUrl, 'https://osu.ppy.sh/b/1418503'); + assert.equal(r2.beatmapTitle, 'tofubeats - CANDYYYLAND feat LIZ - Pa\'s Lam System Remix [Nathan\'s Extra]'); + assert.equal(r2.teamMode, 'HeadToHead'); + assert.equal(r2.winCondition, 'Score'); + assert.equal(r2.activeMods, 'Freemod'); assert.equal(r2.players.length, 1); - assert.equal(r2.players[0].name, "0123456789abcde"); + assert.equal(r2.players[0].name, '0123456789abcde'); assert.notEqual(r1, r2); }); - it("mp settings team", () => { + it('mp settings team', () => { const p = new MpSettingsParser(); - assert.isTrue(p.feedLine("Room name: ahr test, History: https://osu.ppy.sh/mp/54598622")); - assert.isTrue(p.feedLine("Beatmap: https://osu.ppy.sh/b/86920 SID - Ranbu no Melody (TV Size) [Happy's Insane]")); - assert.isTrue(p.feedLine("Team mode: TeamVs, Win condition: Score")); - assert.isTrue(p.feedLine("Active mods: DoubleTime, Freemod")); - assert.isTrue(p.feedLine("Players: 1")); - assert.isTrue(p.feedLine("Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host / Team Blue / Hidden, HardRock]")); + assert.isTrue(p.feedLine('Room name: ahr test, History: https://osu.ppy.sh/mp/54598622')); + assert.isTrue(p.feedLine('Beatmap: https://osu.ppy.sh/b/86920 SID - Ranbu no Melody (TV Size) [Happy\'s Insane]')); + assert.isTrue(p.feedLine('Team mode: TeamVs, Win condition: Score')); + assert.isTrue(p.feedLine('Active mods: DoubleTime, Freemod')); + assert.isTrue(p.feedLine('Players: 1')); + assert.isTrue(p.feedLine('Slot 1 Not Ready https://osu.ppy.sh/u/8286882 gnsksz [Host / Team Blue / Hidden, HardRock]')); assert.isFalse(p.isParsing); assert.isNotNull(p.result); const r = p.result as MpSettingsResult; - assert.equal(r.teamMode, "TeamVs"); - assert.equal(r.winCondition, "Score"); - assert.equal(r.activeMods, "DoubleTime, Freemod"); + assert.equal(r.teamMode, 'TeamVs'); + assert.equal(r.winCondition, 'Score'); + assert.equal(r.activeMods, 'DoubleTime, Freemod'); assert.equal(r.players.length, 1); - assert.equal(r.players[0].name, "gnsksz"); + assert.equal(r.players[0].name, 'gnsksz'); assert.equal(r.players[0].id, 8286882); assert.equal(r.players[0].isHost, true); - assert.equal(r.players[0].options, "Host / Team Blue / Hidden, HardRock"); + assert.equal(r.players[0].options, 'Host / Team Blue / Hidden, HardRock'); assert.equal(r.players[0].team, Teams.Blue); }); - it("check cases", () => { + it('check cases', () => { const p = new MpSettingsParser(); - for (let key in MpSettingsCases) { + for (const key in MpSettingsCases) { const c = MpSettingsCases[key]; - for (let t of c.texts) { + for (const t of c.texts) { p.feedLine(t); } assert.isTrue(p.isParsed, c.title); diff --git a/src/tests/StatParserTest.ts b/src/tests/StatParserTest.ts index a22ec51e..36c6a35b 100644 --- a/src/tests/StatParserTest.ts +++ b/src/tests/StatParserTest.ts @@ -2,37 +2,37 @@ import { assert } from 'chai'; import { StatParser, StatStatuses, StatResult } from '../parsers/StatParser'; const testTexts = [ - "Stats for (Jason)[https://osu.ppy.sh/u/7342098] is Multiplaying:", - "Score: 18,163,888,782 (#1631)", - "Plays: 78245 (lv100)", - "Accuracy: 97.36%", - "Stats for (horcrux18)[https://osu.ppy.sh/u/8778911] is Afk:", - "Score: 584,565,786 (#260177)", - "Plays: 5695 (lv64)", - "Accuracy: 86.94%", - "Stats for (gviz)[https://osu.ppy.sh/u/15145414] is Multiplayer:", - "Score: 00 (#0)", - "Plays: 7 (lv2)", - "Accuracy: 0%", - "Stats for (Angel Arrow)[https://osu.ppy.sh/u/1970239] is Testing:", - "Score: 59,315,895,109 (#1006)", - "Plays: 104962 (lv102)", - "Accuracy: 98.16%", - "Stats for (Foreskin)[https://osu.ppy.sh/u/3760263]:", - "Score: 00 (#0)", - "Plays: 1 (lv1)", - "Accuracy: 0.00%" + 'Stats for (Jason)[https://osu.ppy.sh/u/7342098] is Multiplaying:', + 'Score: 18,163,888,782 (#1631)', + 'Plays: 78245 (lv100)', + 'Accuracy: 97.36%', + 'Stats for (horcrux18)[https://osu.ppy.sh/u/8778911] is Afk:', + 'Score: 584,565,786 (#260177)', + 'Plays: 5695 (lv64)', + 'Accuracy: 86.94%', + 'Stats for (gviz)[https://osu.ppy.sh/u/15145414] is Multiplayer:', + 'Score: 00 (#0)', + 'Plays: 7 (lv2)', + 'Accuracy: 0%', + 'Stats for (Angel Arrow)[https://osu.ppy.sh/u/1970239] is Testing:', + 'Score: 59,315,895,109 (#1006)', + 'Plays: 104962 (lv102)', + 'Accuracy: 98.16%', + 'Stats for (Foreskin)[https://osu.ppy.sh/u/3760263]:', + 'Score: 00 (#0)', + 'Plays: 1 (lv1)', + 'Accuracy: 0.00%' ]; const expectedResults = [ - new StatResult ("Jason", 7342098, StatStatuses.Multiplaying, 18163888782, 1631, 78245, 100, 97.36), - new StatResult("horcrux18", 8778911, StatStatuses.Afk, 584_565_786, 260177, 5695, 64, 86.94), - new StatResult("gviz", 15145414, StatStatuses.Multiplayer, 0, 0, 7, 2, 0), - new StatResult("Angel Arrow", 1970239, StatStatuses.Testing, 59315895109, 1006, 104962, 102, 98.16), - new StatResult("Foreskin", 3760263, StatStatuses.None, 0, 0, 1, 1, 0), + new StatResult ('Jason', 7342098, StatStatuses.Multiplaying, 18163888782, 1631, 78245, 100, 97.36), + new StatResult('horcrux18', 8778911, StatStatuses.Afk, 584_565_786, 260177, 5695, 64, 86.94), + new StatResult('gviz', 15145414, StatStatuses.Multiplayer, 0, 0, 7, 2, 0), + new StatResult('Angel Arrow', 1970239, StatStatuses.Testing, 59315895109, 1006, 104962, 102, 98.16), + new StatResult('Foreskin', 3760263, StatStatuses.None, 0, 0, 1, 1, 0), ]; -it("StatParser Test", function () { +it('StatParser Test', function () { assert.equal(testTexts.length, expectedResults.length * 4); const parser = new StatParser(); assert.isFalse(parser.isParsed); diff --git a/src/tests/TestUtils.ts b/src/tests/TestUtils.ts index 1f79d147..1bd57d7f 100644 --- a/src/tests/TestUtils.ts +++ b/src/tests/TestUtils.ts @@ -9,12 +9,12 @@ import { assert } from 'chai'; import log4js from 'log4js'; class TestUtils { - ownerNickname: string = "creator"; - lobbyName: string = "test"; + ownerNickname: string = 'creator'; + lobbyName: string = 'test'; async SetupLobbyAsync(logging: boolean = false): Promise<{ lobby: Lobby, ircClient: DummyIrcClient }> { - const ircClient = new DummyIrcClient("osu_irc_server", this.ownerNickname); + const ircClient = new DummyIrcClient('osu_irc_server', this.ownerNickname); if (logging) { logIrcEvent(ircClient); } @@ -24,11 +24,11 @@ class TestUtils { } async AddPlayersAsync(names: string[] | number, client: DummyIrcClient): Promise { - if (typeof names == "number") { + if (typeof names == 'number') { const start = client.players.size; const p = []; for (let i = 0; i < names; i++) { - p[i] = "p" + (i + start) + p[i] = 'p' + (i + start); await client.emulateAddPlayerAsync(p[i]); } return p; @@ -39,7 +39,7 @@ class TestUtils { } async sendMessageAsOwner(lobby: Lobby, message: string) { - let owner = lobby.GetOrMakePlayer(this.ownerNickname); + const owner = lobby.GetOrMakePlayer(this.ownerNickname); lobby.RaiseReceivedChatCommand(owner, message); } @@ -52,11 +52,11 @@ class TestUtils { assertHost(username: string, lobby: Lobby): void { const host = lobby.host; if (host == null) { - assert.fail("No one is host now."); + assert.fail('No one is host now.'); } else { assert.equal(host.name, username); } - for (let p of lobby.players) { + for (const p of lobby.players) { if (p == host) { assert.isTrue(p.isHost); } else { @@ -74,22 +74,22 @@ class TestUtils { lobby.TransferHost(lobby.GetPlayer(name) as Player); return p; } - loggerMode = ""; + loggerMode = ''; configMochaVerbosely(): void { - if (this.loggerMode != "Verbosely") { - this.loggerMode = "Verbosely"; + if (this.loggerMode != 'Verbosely') { + this.loggerMode = 'Verbosely'; log4js.shutdown(); - log4js.configure("config/log_mocha.json"); + log4js.configure('config/log_mocha.json'); } } configMochaAsSilent(): void { - if (this.loggerMode != "Silent") { - this.loggerMode = "Silent" + if (this.loggerMode != 'Silent') { + this.loggerMode = 'Silent'; log4js.shutdown(); - log4js.configure("config/log_mocha_silent.json"); + log4js.configure('config/log_mocha_silent.json'); } } @@ -106,7 +106,7 @@ class TestUtils { if (timeout != 0) { id = setTimeout(() => { d.dispose(); - reject("The expected event was not fired"); + reject('The expected event was not fired'); }, timeout); } const d = event.on(a => { @@ -134,7 +134,7 @@ class TestUtils { if (cb != null && cb(a) === false) return; clearTimeout(id); d.dispose(); - reject("The event expected not to fire was fired"); + reject('The event expected not to fire was fired'); }); }); } @@ -152,7 +152,7 @@ class TestUtils { if (timeout != 0) { id = setTimeout(() => { d.dispose(); - reject("the expected response was not returned."); + reject('the expected response was not returned.'); }, timeout); } const d = lobby.ReceivedBanchoResponse.on(a => { @@ -183,14 +183,14 @@ class TestUtils { if (cb != null && cb(a.response) === false) return; clearTimeout(id); d.dispose(); - reject("the response not expected was returned."); + reject('the response not expected was returned.'); }); }); } assertMpSettingsResult(lobby: Lobby, result: MpSettingsResult) { assert.equal(lobby.players.size, result.players.length); - for (let r of result.players) { + for (const r of result.players) { const p = lobby.GetPlayer(r.name); if (p == null) { assert.fail(); diff --git a/src/tests/TypedConfigTest.ts b/src/tests/TypedConfigTest.ts index 90a97034..2ba65432 100644 --- a/src/tests/TypedConfigTest.ts +++ b/src/tests/TypedConfigTest.ts @@ -1,7 +1,7 @@ import { assert } from 'chai'; import { CONFIG_OPTION, generateDefaultOptionTypeHint, loadEnvConfigWithTypeHint } from '../TypedConfig'; -describe("TypedConfigTests", function () { +describe('TypedConfigTests', function () { let CONFIG_OPTION_USE_ENV_DEFAULT = false; before(function () { CONFIG_OPTION_USE_ENV_DEFAULT = CONFIG_OPTION.USE_ENV; @@ -11,8 +11,8 @@ describe("TypedConfigTests", function () { CONFIG_OPTION.USE_ENV = CONFIG_OPTION_USE_ENV_DEFAULT; }); - describe("generateDefaultOptionTypeHint tests", function () { - it("create boolean hints", function () { + describe('generateDefaultOptionTypeHint tests', function () { + it('create boolean hints', function () { const hint = generateDefaultOptionTypeHint({ a: false, b: true @@ -22,7 +22,7 @@ describe("TypedConfigTests", function () { { key: 'b', nullable: false, type: 'boolean' } ]); }); - it("create number typehint", function () { + it('create number typehint', function () { const hint = generateDefaultOptionTypeHint({ a: 0, b: 1, @@ -38,21 +38,21 @@ describe("TypedConfigTests", function () { { key: 'f', nullable: false, type: 'number' }, ]); }); - it("create string typehint", function () { + it('create string typehint', function () { const hint = generateDefaultOptionTypeHint({ - a: "", - b: "hello" + a: '', + b: 'hello' }); assert.deepEqual(hint, [ { key: 'a', nullable: false, type: 'string' }, { key: 'b', nullable: false, type: 'string' } ]); }); - it("create array typehint", function () { + it('create array typehint', function () { const hint = generateDefaultOptionTypeHint({ a: [], - b: ["a"], - c: ["a", "b"], + b: ['a'], + c: ['a', 'b'], d: [1, 2, 3], }); assert.deepEqual(hint, [ @@ -62,7 +62,7 @@ describe("TypedConfigTests", function () { { key: 'd', nullable: false, type: 'array' } ]); }); - it("create nullable typehint", function () { + it('create nullable typehint', function () { const hint = generateDefaultOptionTypeHint({ a: null, b: undefined, @@ -74,151 +74,151 @@ describe("TypedConfigTests", function () { }); }); - describe("loadEnvConfigWithTypeHint", function () { - it("load bool", function () { + describe('loadEnvConfigWithTypeHint', function () { + it('load bool', function () { const hints = generateDefaultOptionTypeHint({ a: false, b: true }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "false", ahr_test_b: "true" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'false', ahr_test_b: 'true' }); assert.deepEqual(opt, { a: false, b: true }); }); - it("load extra bool", function () { + it('load extra bool', function () { const hints = generateDefaultOptionTypeHint({ a: false, b: true }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "false", ahr_test_b: "true", ahr_test_c: "sfd", ahr_test_d: "safsaf" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'false', ahr_test_b: 'true', ahr_test_c: 'sfd', ahr_test_d: 'safsaf' }); assert.deepEqual(opt, { a: false, b: true }); }); - it("load partial bool", function () { + it('load partial bool', function () { const hints = generateDefaultOptionTypeHint({ a: false, b: true }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "false" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'false' }); assert.deepEqual(opt, { a: false }); }); - it("load invalid bool", function () { + it('load invalid bool', function () { const hints = generateDefaultOptionTypeHint({ a: false, b: true }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "aaa" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'aaa' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "[]" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '[]' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_b: "100" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_b: '100' }); }); }); - it("load num", function () { + it('load num', function () { const hints = generateDefaultOptionTypeHint({ a: 0, b: 1 }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "0", ahr_test_b: "1" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '0', ahr_test_b: '1' }); assert.deepEqual(opt, { a: 0, b: 1 }); }); - it("load float", function () { + it('load float', function () { const hints = generateDefaultOptionTypeHint({ a: 0, b: 1 }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "0.0125", ahr_test_b: "-0" }); - assert.approximately(opt["a"] as number, 0.0125, 0.001); - assert.approximately(opt["b"] as number, 0, 0.001); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '0.0125', ahr_test_b: '-0' }); + assert.approximately(opt['a'] as number, 0.0125, 0.001); + assert.approximately(opt['b'] as number, 0, 0.001); }); - it("load extra num", function () { + it('load extra num', function () { const hints = generateDefaultOptionTypeHint({ a: 0, b: 1 }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "0", ahr_test_b: "1", ahr_test_c: "2", ahr_test_d: "3" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '0', ahr_test_b: '1', ahr_test_c: '2', ahr_test_d: '3' }); assert.deepEqual(opt, { a: 0, b: 1 }); }); - it("load partial num", function () { + it('load partial num', function () { const hints = generateDefaultOptionTypeHint({ a: 0, b: 1 }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "0" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '0' }); assert.deepEqual(opt, { a: 0 }); }); - it("load invalid num", function () { + it('load invalid num', function () { const hints = generateDefaultOptionTypeHint({ a: 0, b: 1 }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "aaa" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'aaa' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "[]" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '[]' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_b: "NaN" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_b: 'NaN' }); }); }); - it("load string", function () { - const hints = generateDefaultOptionTypeHint({ a: "", b: "aaa" }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "", ahr_test_b: "aaa" }); - assert.deepEqual(opt, { a: "", b: "aaa" }); + it('load string', function () { + const hints = generateDefaultOptionTypeHint({ a: '', b: 'aaa' }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '', ahr_test_b: 'aaa' }); + assert.deepEqual(opt, { a: '', b: 'aaa' }); }); - it("load extra string", function () { - const hints = generateDefaultOptionTypeHint({ a: "", b: "aaa" }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "0", ahr_test_b: "1", ahr_test_c: "2", ahr_test_d: "3" }); - assert.deepEqual(opt, { a: "0", b: "1" }); + it('load extra string', function () { + const hints = generateDefaultOptionTypeHint({ a: '', b: 'aaa' }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '0', ahr_test_b: '1', ahr_test_c: '2', ahr_test_d: '3' }); + assert.deepEqual(opt, { a: '0', b: '1' }); }); - it("load partial string", function () { - const hints = generateDefaultOptionTypeHint({ a: "", b: "aaa" }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "0" }); - assert.deepEqual(opt, { a: "0" }); + it('load partial string', function () { + const hints = generateDefaultOptionTypeHint({ a: '', b: 'aaa' }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '0' }); + assert.deepEqual(opt, { a: '0' }); }); - it("load array", function () { - const hints = generateDefaultOptionTypeHint({ a: [], b: ["aa", "bb"] }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: '[]', ahr_test_b: '["a", "b"]' }); - assert.deepEqual(opt, { a: [], b: ["a", "b"] }); + it('load array', function () { + const hints = generateDefaultOptionTypeHint({ a: [], b: ['aa', 'bb'] }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '[]', ahr_test_b: '["a", "b"]' }); + assert.deepEqual(opt, { a: [], b: ['a', 'b'] }); }); - it("load extra array", function () { - const hints = generateDefaultOptionTypeHint({ a: [], b: ["aa", "bb"] }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: '["0"]', ahr_test_b: '["1"]', ahr_test_c: '["2"]', ahr_test_d: '["3"]' }); - assert.deepEqual(opt, { a: ["0"], b: ["1"] }); + it('load extra array', function () { + const hints = generateDefaultOptionTypeHint({ a: [], b: ['aa', 'bb'] }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '["0"]', ahr_test_b: '["1"]', ahr_test_c: '["2"]', ahr_test_d: '["3"]' }); + assert.deepEqual(opt, { a: ['0'], b: ['1'] }); }); - it("load partial array", function () { - const hints = generateDefaultOptionTypeHint({ a: [], b: ["aa", "bb"] }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: '["0"]' }); - assert.deepEqual(opt, { a: ["0"] }); + it('load partial array', function () { + const hints = generateDefaultOptionTypeHint({ a: [], b: ['aa', 'bb'] }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '["0"]' }); + assert.deepEqual(opt, { a: ['0'] }); }); - it("load invalid array", function () { - const hints = generateDefaultOptionTypeHint({ a: [], b: ["aa", "bb"] }); + it('load invalid array', function () { + const hints = generateDefaultOptionTypeHint({ a: [], b: ['aa', 'bb'] }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "aaa" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'aaa' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "[[],[]]" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: '[[],[]]' }); }); assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_b: "[1,2,3,4]" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_b: '[1,2,3,4]' }); }); }); }); - describe("nullable hints", function () { - it("declear nullable bool", function () { + describe('nullable hints', function () { + it('declear nullable bool', function () { const hints = generateDefaultOptionTypeHint({ a: false, b: false }); hints[1].nullable = true; assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "null" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'null' }); }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_b: "null" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_b: 'null' }); assert.deepEqual(opt, { b: null }); }); - it("declear nullable number", function () { + it('declear nullable number', function () { const hints = generateDefaultOptionTypeHint({ a: 0, b: 0 }); hints[1].nullable = true; assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "null" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'null' }); }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_b: "null" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_b: 'null' }); assert.deepEqual(opt, { b: null }); }); - it("declear nullable string", function () { - const hints = generateDefaultOptionTypeHint({ a: "", b: "" }); + it('declear nullable string', function () { + const hints = generateDefaultOptionTypeHint({ a: '', b: '' }); hints[1].nullable = true; - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "null", ahr_test_b: "null" }); - assert.deepEqual(opt, { a: "null", b: null }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'null', ahr_test_b: 'null' }); + assert.deepEqual(opt, { a: 'null', b: null }); }); - it("declear nullable array", function () { + it('declear nullable array', function () { const hints = generateDefaultOptionTypeHint({ a: [], b: [] }); hints[1].nullable = true; assert.throw(() => { - loadEnvConfigWithTypeHint("test", hints, { ahr_test_a: "null" }); + loadEnvConfigWithTypeHint('test', hints, { ahr_test_a: 'null' }); }); - const opt = loadEnvConfigWithTypeHint("test", hints, { ahr_test_b: "null" }); + const opt = loadEnvConfigWithTypeHint('test', hints, { ahr_test_b: 'null' }); assert.deepEqual(opt, { b: null }); }); }); diff --git a/src/tests/WordCounterTest.ts b/src/tests/WordCounterTest.ts index cd99c384..043b1222 100644 --- a/src/tests/WordCounterTest.ts +++ b/src/tests/WordCounterTest.ts @@ -4,177 +4,177 @@ import { DummyIrcClient } from '../dummies/DummyIrcClient'; import { WordCounter, WordCounterPeriod } from '../plugins/WordCounter'; import tu from './TestUtils'; -describe("WordCounter Tests", function () { +describe('WordCounter Tests', function () { before(function () { tu.configMochaAsSilent(); }); - async function setup(periods = [{ symbol: "a", duration_ms: 1000 }]): + async function setup(periods = [{ symbol: 'a', duration_ms: 1000 }]): Promise<{ counter: WordCounter, lobby: Lobby, ircClient: DummyIrcClient }> { const li = await tu.SetupLobbyAsync(); const option = { periods: periods - } - const counter = new WordCounter(li.lobby, option) + }; + const counter = new WordCounter(li.lobby, option); return { counter, ...li }; } function assertPeriod(period: WordCounterPeriod, cpp: number, cppm: number, wpp: number, wppm: number) { - assert.equal(period.chatsPerPeriod, cpp, "chat / p"); - assert.equal(period.chatsPerPeriodMax, cppm, "chat max / p"); - assert.equal(period.wordsPerPeriod, wpp, "word / p"); - assert.equal(period.wordsPerPeriodMax, wppm, "word max / p"); + assert.equal(period.chatsPerPeriod, cpp, 'chat / p'); + assert.equal(period.chatsPerPeriodMax, cppm, 'chat max / p'); + assert.equal(period.wordsPerPeriod, wpp, 'word / p'); + assert.equal(period.wordsPerPeriodMax, wppm, 'word max / p'); } - describe("single period tests", function () { - it("info count", async () => { + describe('single period tests', function () { + it('info count', async () => { const { counter, lobby, ircClient } = await setup(); const players = await tu.AddPlayersAsync(3, ircClient); const p = counter.periods[0]; assertPeriod(p, 0, 0, 0, 0); - await ircClient.emulateMessageAsync(players[0], ircClient.channel, "!info"); + await ircClient.emulateMessageAsync(players[0], ircClient.channel, '!info'); await tu.delayAsync(10); assert.equal(p.chatsPerPeriod, 1); assert.equal(p.chatsPerPeriodMax, 1); assert.isAbove(p.wordsPerPeriod, 1); assert.isAbove(p.wordsPerPeriodMax, 1); }); - it("update test1", async () => { + it('update test1', async () => { const { counter, lobby, ircClient } = await setup(); const players = await tu.AddPlayersAsync(3, ircClient); const p = counter.periods[0]; assertPeriod(p, 0, 0, 0, 0); - counter.update("hello world!", 0); + counter.update('hello world!', 0); assertPeriod(p, 1, 1, 12, 12); }); - it("update test2", async () => { + it('update test2', async () => { const { counter, lobby, ircClient } = await setup(); const players = await tu.AddPlayersAsync(3, ircClient); const p = counter.periods[0]; assertPeriod(p, 0, 0, 0, 0); - counter.update("hello world!", 0); + counter.update('hello world!', 0); assertPeriod(p, 1, 1, 12, 12); - counter.update("abcdefg", 1); + counter.update('abcdefg', 1); assertPeriod(p, 2, 2, 19, 19); }); - it("period test", async () => { - const { counter, lobby, ircClient } = await setup([{ symbol: "a", duration_ms: 1 }]); + it('period test', async () => { + const { counter, lobby, ircClient } = await setup([{ symbol: 'a', duration_ms: 1 }]); const players = await tu.AddPlayersAsync(3, ircClient); const p = counter.periods[0]; assertPeriod(p, 0, 0, 0, 0); - counter.update("hello world!", 0); + counter.update('hello world!', 0); assertPeriod(p, 1, 1, 12, 12); - counter.update("abcdefg", 10); + counter.update('abcdefg', 10); assertPeriod(p, 1, 1, 7, 12); }); - it("max value test", async () => { - const { counter, lobby, ircClient } = await setup([{ symbol: "a", duration_ms: 1 }]); + it('max value test', async () => { + const { counter, lobby, ircClient } = await setup([{ symbol: 'a', duration_ms: 1 }]); const players = await tu.AddPlayersAsync(3, ircClient); const p = counter.periods[0]; assertPeriod(p, 0, 0, 0, 0); - counter.update("hello world!", 0); + counter.update('hello world!', 0); assertPeriod(p, 1, 1, 12, 12); - counter.update("hoge piyo hoge piyo!", 2); + counter.update('hoge piyo hoge piyo!', 2); assertPeriod(p, 1, 1, 20, 20); - counter.update("Yikes!", 4); + counter.update('Yikes!', 4); assertPeriod(p, 1, 1, 6, 20); }); - it("border test", async () => { - const { counter, lobby, ircClient } = await setup([{ symbol: "a", duration_ms: 10 }]); + it('border test', async () => { + const { counter, lobby, ircClient } = await setup([{ symbol: 'a', duration_ms: 10 }]); const players = await tu.AddPlayersAsync(3, ircClient); const p = counter.periods[0]; assertPeriod(p, 0, 0, 0, 0); - counter.update("hello world!", 10); + counter.update('hello world!', 10); assertPeriod(p, 1, 1, 12, 12); - counter.update("abcdefg", 21); + counter.update('abcdefg', 21); assertPeriod(p, 1, 1, 7, 12); }); - it("garbage collection test", async () => { - const { counter, lobby, ircClient } = await setup([{ symbol: "a", duration_ms: 10 }]); + it('garbage collection test', async () => { + const { counter, lobby, ircClient } = await setup([{ symbol: 'a', duration_ms: 10 }]); const players = await tu.AddPlayersAsync(3, ircClient); const p = counter.periods[0]; assertPeriod(p, 0, 0, 0, 0); for (let i = 0; i < 100; i++) { - counter.update("hello world!", 10); + counter.update('hello world!', 10); } assertPeriod(p, 100, 100, 1200, 1200); assert.equal(counter.samples.length, 100); - counter.update("abcdefg", 100); + counter.update('abcdefg', 100); assert.equal(counter.samples.length, 1); assertPeriod(p, 1, 100, 7, 1200); }); }); - describe("multi periods tests", function () { - it("period test", async () => { + describe('multi periods tests', function () { + it('period test', async () => { const def_periods = [ - { symbol: "a", duration_ms: 10 }, - { symbol: "b", duration_ms: 100 } + { symbol: 'a', duration_ms: 10 }, + { symbol: 'b', duration_ms: 100 } ]; const { counter, lobby, ircClient } = await setup(def_periods); const players = await tu.AddPlayersAsync(3, ircClient); - assert.equal(counter.periods[0].symbol, "a"); + assert.equal(counter.periods[0].symbol, 'a'); assertPeriod(counter.periods[0], 0, 0, 0, 0); - assert.equal(counter.periods[1].symbol, "b"); + assert.equal(counter.periods[1].symbol, 'b'); assertPeriod(counter.periods[1], 0, 0, 0, 0); - counter.update("hello world!", 0); + counter.update('hello world!', 0); assertPeriod(counter.periods[0], 1, 1, 12, 12); assertPeriod(counter.periods[1], 1, 1, 12, 12); - counter.update("abcdefg", 30); + counter.update('abcdefg', 30); assertPeriod(counter.periods[0], 1, 1, 7, 12); assertPeriod(counter.periods[1], 2, 2, 19, 19); }); - it("garbage collection test", async () => { + it('garbage collection test', async () => { const def_periods = [ - { symbol: "a", duration_ms: 10 }, - { symbol: "b", duration_ms: 100 }, - { symbol: "c", duration_ms: 1000 } + { symbol: 'a', duration_ms: 10 }, + { symbol: 'b', duration_ms: 100 }, + { symbol: 'c', duration_ms: 1000 } ]; const { counter, lobby, ircClient } = await setup(def_periods); const players = await tu.AddPlayersAsync(3, ircClient); - assert.equal(counter.periods[0].symbol, "a"); + assert.equal(counter.periods[0].symbol, 'a'); assertPeriod(counter.periods[0], 0, 0, 0, 0); - assert.equal(counter.periods[1].symbol, "b"); + assert.equal(counter.periods[1].symbol, 'b'); assertPeriod(counter.periods[1], 0, 0, 0, 0); for (let i = 0; i < 100; i++) { - counter.update("hello world!", 10); + counter.update('hello world!', 10); } assertPeriod(counter.periods[0], 100, 100, 1200, 1200); assertPeriod(counter.periods[1], 100, 100, 1200, 1200); assertPeriod(counter.periods[2], 100, 100, 1200, 1200); assert.equal(counter.samples.length, 100); - counter.update("abcdef", 30); + counter.update('abcdef', 30); assertPeriod(counter.periods[0], 1, 100, 6, 1200); assertPeriod(counter.periods[1], 101, 101, 1206, 1206); assertPeriod(counter.periods[2], 101, 101, 1206, 1206); assert.equal(counter.samples.length, 101); - counter.update("abcdef", 130); + counter.update('abcdef', 130); assertPeriod(counter.periods[0], 1, 100, 6, 1200); assertPeriod(counter.periods[1], 2, 101, 12, 1206); assertPeriod(counter.periods[2], 102, 102, 1212, 1212); assert.equal(counter.samples.length, 102); - counter.update("abcdef", 5000); + counter.update('abcdef', 5000); assertPeriod(counter.periods[0], 1, 100, 6, 1200); assertPeriod(counter.periods[1], 1, 101, 6, 1206); assertPeriod(counter.periods[2], 1, 102, 6, 1212); assert.equal(counter.samples.length, 1); }); }); - it("no period test", async () => { + it('no period test', async () => { const { lobby, ircClient } = await tu.SetupLobbyAsync(); const option = { periods: [] - } + }; const counter = new WordCounter(lobby, option); assert.equal(counter.periods.length, 0); - counter.update("test", Date.now()); + counter.update('test', Date.now()); }); }); diff --git a/src/tests/cases/MpSettingsCases.ts b/src/tests/cases/MpSettingsCases.ts index 3c4fa6b1..999e842d 100644 --- a/src/tests/cases/MpSettingsCases.ts +++ b/src/tests/cases/MpSettingsCases.ts @@ -9,188 +9,188 @@ export interface MpSettingsCase { export const MpSettingsCases: { [key: string]: MpSettingsCase } = { case1_1: { - title: "case1_1", + title: 'case1_1', texts: [ - "Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403", - "Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]", - "Team mode: HeadToHead, Win condition: Score", - "Active mods: Freemod", - "Players: 5", - "Slot 1 Not Ready https://osu.ppy.sh/u/111 p1 [Host]", - "Slot 2 Not Ready https://osu.ppy.sh/u/222 p2 [Hidden, DoubleTime]", - "Slot 3 Not Ready https://osu.ppy.sh/u/333 p3 ", - "Slot 4 Not Ready https://osu.ppy.sh/u/444 p4 ", - "Slot 5 Not Ready https://osu.ppy.sh/u/555 p5 "], + 'Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403', + 'Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]', + 'Team mode: HeadToHead, Win condition: Score', + 'Active mods: Freemod', + 'Players: 5', + 'Slot 1 Not Ready https://osu.ppy.sh/u/111 p1 [Host]', + 'Slot 2 Not Ready https://osu.ppy.sh/u/222 p2 [Hidden, DoubleTime]', + 'Slot 3 Not Ready https://osu.ppy.sh/u/333 p3 ', + 'Slot 4 Not Ready https://osu.ppy.sh/u/444 p4 ', + 'Slot 5 Not Ready https://osu.ppy.sh/u/555 p5 '], result: { - name: "5* (´・ω・`) host rotate", id: 53084403, history: "https://osu.ppy.sh/mp/53084403", - beatmapId: 853167, beatmapUrl: "https://osu.ppy.sh/b/853167", beatmapTitle: "Silent Siren - Hachigatsu no Yoru [August]", - teamMode: "HeadToHead", winCondition: "Score", activeMods: "Freemod", + name: '5* (´・ω・`) host rotate', id: 53084403, history: 'https://osu.ppy.sh/mp/53084403', + beatmapId: 853167, beatmapUrl: 'https://osu.ppy.sh/b/853167', beatmapTitle: 'Silent Siren - Hachigatsu no Yoru [August]', + teamMode: 'HeadToHead', winCondition: 'Score', activeMods: 'Freemod', numPlayers: 5, players: [ - { name: "p1", slot: 1, ready: "Not Ready", team: Teams.None, isHost: true, options: "Host", id: 111, profile: "https://osu.ppy.sh/u/111" }, - { name: "p2", slot: 2, ready: "Not Ready", team: Teams.None, isHost: false, options: "Hidden, DoubleTime", id: 222, profile: "https://osu.ppy.sh/u/222" }, - { name: "p3", slot: 3, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 333, profile: "https://osu.ppy.sh/u/333" }, - { name: "p4", slot: 4, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 444, profile: "https://osu.ppy.sh/u/444" }, - { name: "p5", slot: 5, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 555, profile: "https://osu.ppy.sh/u/555" }, + { name: 'p1', slot: 1, ready: 'Not Ready', team: Teams.None, isHost: true, options: 'Host', id: 111, profile: 'https://osu.ppy.sh/u/111' }, + { name: 'p2', slot: 2, ready: 'Not Ready', team: Teams.None, isHost: false, options: 'Hidden, DoubleTime', id: 222, profile: 'https://osu.ppy.sh/u/222' }, + { name: 'p3', slot: 3, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 333, profile: 'https://osu.ppy.sh/u/333' }, + { name: 'p4', slot: 4, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 444, profile: 'https://osu.ppy.sh/u/444' }, + { name: 'p5', slot: 5, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 555, profile: 'https://osu.ppy.sh/u/555' }, ] } }, case1_2: { - title: "case1_2", + title: 'case1_2', texts: [ - "Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403", - "Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]", - "Team mode: HeadToHead, Win condition: Score", - "Active mods: Freemod", - "Players: 5", - "Slot 1 Not Ready https://osu.ppy.sh/u/111 p1 ", - "Slot 2 Not Ready https://osu.ppy.sh/u/222 p2 [Hidden, DoubleTime]", - "Slot 3 Not Ready https://osu.ppy.sh/u/333 p3 [Host]", - "Slot 4 Not Ready https://osu.ppy.sh/u/444 p4 ", - "Slot 5 Not Ready https://osu.ppy.sh/u/555 p5 "], + 'Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403', + 'Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]', + 'Team mode: HeadToHead, Win condition: Score', + 'Active mods: Freemod', + 'Players: 5', + 'Slot 1 Not Ready https://osu.ppy.sh/u/111 p1 ', + 'Slot 2 Not Ready https://osu.ppy.sh/u/222 p2 [Hidden, DoubleTime]', + 'Slot 3 Not Ready https://osu.ppy.sh/u/333 p3 [Host]', + 'Slot 4 Not Ready https://osu.ppy.sh/u/444 p4 ', + 'Slot 5 Not Ready https://osu.ppy.sh/u/555 p5 '], result: { - name: "5* (´・ω・`) host rotate", id: 53084403, history: "https://osu.ppy.sh/mp/53084403", - beatmapId: 853167, beatmapUrl: "https://osu.ppy.sh/b/853167", beatmapTitle: "Silent Siren - Hachigatsu no Yoru [August]", - teamMode: "HeadToHead", winCondition: "Score", activeMods: "Freemod", + name: '5* (´・ω・`) host rotate', id: 53084403, history: 'https://osu.ppy.sh/mp/53084403', + beatmapId: 853167, beatmapUrl: 'https://osu.ppy.sh/b/853167', beatmapTitle: 'Silent Siren - Hachigatsu no Yoru [August]', + teamMode: 'HeadToHead', winCondition: 'Score', activeMods: 'Freemod', numPlayers: 5, players: [ - { name: "p1", slot: 1, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 111, profile: "https://osu.ppy.sh/u/111" }, - { name: "p2", slot: 2, ready: "Not Ready", team: Teams.None, isHost: false, options: "Hidden, DoubleTime", id: 222, profile: "https://osu.ppy.sh/u/222" }, - { name: "p3", slot: 3, ready: "Not Ready", team: Teams.None, isHost: true, options: "Host", id: 333, profile: "https://osu.ppy.sh/u/333" }, - { name: "p4", slot: 4, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 444, profile: "https://osu.ppy.sh/u/444" }, - { name: "p5", slot: 5, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 555, profile: "https://osu.ppy.sh/u/555" }, + { name: 'p1', slot: 1, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 111, profile: 'https://osu.ppy.sh/u/111' }, + { name: 'p2', slot: 2, ready: 'Not Ready', team: Teams.None, isHost: false, options: 'Hidden, DoubleTime', id: 222, profile: 'https://osu.ppy.sh/u/222' }, + { name: 'p3', slot: 3, ready: 'Not Ready', team: Teams.None, isHost: true, options: 'Host', id: 333, profile: 'https://osu.ppy.sh/u/333' }, + { name: 'p4', slot: 4, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 444, profile: 'https://osu.ppy.sh/u/444' }, + { name: 'p5', slot: 5, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 555, profile: 'https://osu.ppy.sh/u/555' }, ] } }, case1_3: { - title: "case1_3", + title: 'case1_3', texts: [ - "Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403", - "Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]", - "Team mode: HeadToHead, Win condition: Score", - "Active mods: Freemod", - "Players: 5", - "Slot 1 Not Ready https://osu.ppy.sh/u/666 p6 ", - "Slot 2 Not Ready https://osu.ppy.sh/u/222 p2 [Hidden, DoubleTime]", - "Slot 4 Not Ready https://osu.ppy.sh/u/444 p4 [Host]", - "Slot 5 Not Ready https://osu.ppy.sh/u/555 p5 ", - "Slot 6 Not Ready https://osu.ppy.sh/u/777 p7 "], + 'Room name: 5* (´・ω・`) host rotate, History: https://osu.ppy.sh/mp/53084403', + 'Beatmap: https://osu.ppy.sh/b/853167 Silent Siren - Hachigatsu no Yoru [August]', + 'Team mode: HeadToHead, Win condition: Score', + 'Active mods: Freemod', + 'Players: 5', + 'Slot 1 Not Ready https://osu.ppy.sh/u/666 p6 ', + 'Slot 2 Not Ready https://osu.ppy.sh/u/222 p2 [Hidden, DoubleTime]', + 'Slot 4 Not Ready https://osu.ppy.sh/u/444 p4 [Host]', + 'Slot 5 Not Ready https://osu.ppy.sh/u/555 p5 ', + 'Slot 6 Not Ready https://osu.ppy.sh/u/777 p7 '], result: { - name: "5* (´・ω・`) host rotate", id: 53084403, history: "https://osu.ppy.sh/mp/53084403", - beatmapId: 853167, beatmapUrl: "https://osu.ppy.sh/b/853167", beatmapTitle: "Silent Siren - Hachigatsu no Yoru [August]", - teamMode: "HeadToHead", winCondition: "Score", activeMods: "Freemod", + name: '5* (´・ω・`) host rotate', id: 53084403, history: 'https://osu.ppy.sh/mp/53084403', + beatmapId: 853167, beatmapUrl: 'https://osu.ppy.sh/b/853167', beatmapTitle: 'Silent Siren - Hachigatsu no Yoru [August]', + teamMode: 'HeadToHead', winCondition: 'Score', activeMods: 'Freemod', numPlayers: 5, players: [ - { name: "p6", slot: 1, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 666, profile: "https://osu.ppy.sh/u/666" }, - { name: "p2", slot: 2, ready: "Not Ready", team: Teams.None, isHost: false, options: "Hidden, DoubleTime", id: 222, profile: "https://osu.ppy.sh/u/222" }, - { name: "p4", slot: 4, ready: "Not Ready", team: Teams.None, isHost: true, options: "Host", id: 444, profile: "https://osu.ppy.sh/u/444" }, - { name: "p5", slot: 5, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 555, profile: "https://osu.ppy.sh/u/555" }, - { name: "p7", slot: 6, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 777, profile: "https://osu.ppy.sh/u/777" }, + { name: 'p6', slot: 1, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 666, profile: 'https://osu.ppy.sh/u/666' }, + { name: 'p2', slot: 2, ready: 'Not Ready', team: Teams.None, isHost: false, options: 'Hidden, DoubleTime', id: 222, profile: 'https://osu.ppy.sh/u/222' }, + { name: 'p4', slot: 4, ready: 'Not Ready', team: Teams.None, isHost: true, options: 'Host', id: 444, profile: 'https://osu.ppy.sh/u/444' }, + { name: 'p5', slot: 5, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 555, profile: 'https://osu.ppy.sh/u/555' }, + { name: 'p7', slot: 6, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 777, profile: 'https://osu.ppy.sh/u/777' }, ] } }, case2: { - title: "case2", + title: 'case2', texts: [ - "Room name: 4-5 auto host rotation, History: https://osu.ppy.sh/mp/54771533", - "Beatmap: https://osu.ppy.sh/b/1188131 yuikonnu - Ghost Rule [Hyper]", - "Team mode: HeadToHead, Win condition: Score", - "Active mods: Freemod", - "Players: 5", - "Slot 1 Not Ready https://osu.ppy.sh/u/123 aaaaaa [Hidden]", - "Slot 3 Not Ready https://osu.ppy.sh/u/456 bbbbbb111 ", - "Slot 4 Not Ready https://osu.ppy.sh/u/789 ccc 23 [Host / Hidden]", - "Slot 6 Not Ready https://osu.ppy.sh/u/147 d [Hidden]", - "Slot 7 Not Ready https://osu.ppy.sh/u/258 eee ",], + 'Room name: 4-5 auto host rotation, History: https://osu.ppy.sh/mp/54771533', + 'Beatmap: https://osu.ppy.sh/b/1188131 yuikonnu - Ghost Rule [Hyper]', + 'Team mode: HeadToHead, Win condition: Score', + 'Active mods: Freemod', + 'Players: 5', + 'Slot 1 Not Ready https://osu.ppy.sh/u/123 aaaaaa [Hidden]', + 'Slot 3 Not Ready https://osu.ppy.sh/u/456 bbbbbb111 ', + 'Slot 4 Not Ready https://osu.ppy.sh/u/789 ccc 23 [Host / Hidden]', + 'Slot 6 Not Ready https://osu.ppy.sh/u/147 d [Hidden]', + 'Slot 7 Not Ready https://osu.ppy.sh/u/258 eee ',], result: { - name: "4-5 auto host rotation", id: 54771533, history: "https://osu.ppy.sh/mp/54771533", - beatmapId: 1188131, beatmapUrl: "https://osu.ppy.sh/b/1188131", beatmapTitle: "yuikonnu - Ghost Rule [Hyper]", - teamMode: "HeadToHead", winCondition: "Score", activeMods: "Freemod", + name: '4-5 auto host rotation', id: 54771533, history: 'https://osu.ppy.sh/mp/54771533', + beatmapId: 1188131, beatmapUrl: 'https://osu.ppy.sh/b/1188131', beatmapTitle: 'yuikonnu - Ghost Rule [Hyper]', + teamMode: 'HeadToHead', winCondition: 'Score', activeMods: 'Freemod', numPlayers: 5, players: [ - { name: "aaaaaa", slot: 1, ready: "Not Ready", team: Teams.None, isHost: false, options: "Hidden", id: 123, profile: "https://osu.ppy.sh/u/123" }, - { name: "bbbbbb111", slot: 3, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 456, profile: "https://osu.ppy.sh/u/456" }, - { name: "ccc 23", slot: 4, ready: "Not Ready", team: Teams.None, isHost: true, options: "Host / Hidden", id: 789, profile: "https://osu.ppy.sh/u/789" }, - { name: "d", slot: 6, ready: "Not Ready", team: Teams.None, isHost: false, options: "Hidden", id: 147, profile: "https://osu.ppy.sh/u/147" }, - { name: "eee", slot: 7, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 258, profile: "https://osu.ppy.sh/u/258" }] + { name: 'aaaaaa', slot: 1, ready: 'Not Ready', team: Teams.None, isHost: false, options: 'Hidden', id: 123, profile: 'https://osu.ppy.sh/u/123' }, + { name: 'bbbbbb111', slot: 3, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 456, profile: 'https://osu.ppy.sh/u/456' }, + { name: 'ccc 23', slot: 4, ready: 'Not Ready', team: Teams.None, isHost: true, options: 'Host / Hidden', id: 789, profile: 'https://osu.ppy.sh/u/789' }, + { name: 'd', slot: 6, ready: 'Not Ready', team: Teams.None, isHost: false, options: 'Hidden', id: 147, profile: 'https://osu.ppy.sh/u/147' }, + { name: 'eee', slot: 7, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 258, profile: 'https://osu.ppy.sh/u/258' }] } }, case3: { - title: "case3", + title: 'case3', texts: [ - "Room name: 4-5* auto host rotaion, History: https://osu.ppy.sh/mp/54581109", - "Beatmap: https://osu.ppy.sh/b/1418503 tofubeats - CANDYYYLAND feat LIZ - Pa's Lam System Remix [Nathan's Extra]", - "Team mode: HeadToHead, Win condition: Score", - "Active mods: Freemod", - "Players: 7", - "Slot 1 Not Ready https://osu.ppy.sh/u/1 player1 [Host / Hidden, HardRock]", - "Slot 2 Not Ready https://osu.ppy.sh/u/2 player2[abc] ", - "Slot 3 Not Ready https://osu.ppy.sh/u/3 pl a ye r3 ", - "Slot 4 Not Ready https://osu.ppy.sh/u/4 pl_a[y]er4 ", - "Slot 5 Not Ready https://osu.ppy.sh/u/5 player5abcdefga ", - "Slot 6 Not Ready https://osu.ppy.sh/u/6 pla y e r 6efga [Hidden]", - "Slot 16 Not Ready https://osu.ppy.sh/u/7 player7abc[fga] [Hidden]"], + 'Room name: 4-5* auto host rotaion, History: https://osu.ppy.sh/mp/54581109', + 'Beatmap: https://osu.ppy.sh/b/1418503 tofubeats - CANDYYYLAND feat LIZ - Pa\'s Lam System Remix [Nathan\'s Extra]', + 'Team mode: HeadToHead, Win condition: Score', + 'Active mods: Freemod', + 'Players: 7', + 'Slot 1 Not Ready https://osu.ppy.sh/u/1 player1 [Host / Hidden, HardRock]', + 'Slot 2 Not Ready https://osu.ppy.sh/u/2 player2[abc] ', + 'Slot 3 Not Ready https://osu.ppy.sh/u/3 pl a ye r3 ', + 'Slot 4 Not Ready https://osu.ppy.sh/u/4 pl_a[y]er4 ', + 'Slot 5 Not Ready https://osu.ppy.sh/u/5 player5abcdefga ', + 'Slot 6 Not Ready https://osu.ppy.sh/u/6 pla y e r 6efga [Hidden]', + 'Slot 16 Not Ready https://osu.ppy.sh/u/7 player7abc[fga] [Hidden]'], result: { - name: "4-5* auto host rotaion", id: 54581109, history: "https://osu.ppy.sh/mp/54581109", - beatmapId: 1418503, beatmapUrl: "https://osu.ppy.sh/b/1418503", beatmapTitle: "tofubeats - CANDYYYLAND feat LIZ - Pa's Lam System Remix [Nathan's Extra]", - teamMode: "HeadToHead", winCondition: "Score", activeMods: "Freemod", + name: '4-5* auto host rotaion', id: 54581109, history: 'https://osu.ppy.sh/mp/54581109', + beatmapId: 1418503, beatmapUrl: 'https://osu.ppy.sh/b/1418503', beatmapTitle: 'tofubeats - CANDYYYLAND feat LIZ - Pa\'s Lam System Remix [Nathan\'s Extra]', + teamMode: 'HeadToHead', winCondition: 'Score', activeMods: 'Freemod', numPlayers: 7, players: [ - { name: "player1", slot: 1, ready: "Not Ready", team: Teams.None, isHost: true, options: "Host / Hidden, HardRock", id: 1, profile: "https://osu.ppy.sh/u/1" }, - { name: "player2[abc]", slot: 2, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 2, profile: "https://osu.ppy.sh/u/2" }, - { name: "pl a ye r3", slot: 3, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 3, profile: "https://osu.ppy.sh/u/3" }, - { name: "pl_a[y]er4", slot: 4, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 4, profile: "https://osu.ppy.sh/u/4" }, - { name: "player5abcdefga", slot: 5, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 5, profile: "https://osu.ppy.sh/u/5" }, - { name: "pla y e r 6efga", slot: 6, ready: "Not Ready", team: Teams.None, isHost: false, options: "Hidden", id: 6, profile: "https://osu.ppy.sh/u/6" }, - { name: "player7abc[fga]", slot: 16, ready: "Not Ready", team: Teams.None, isHost: false, options: "Hidden", id: 7, profile: "https://osu.ppy.sh/u/7" },] + { name: 'player1', slot: 1, ready: 'Not Ready', team: Teams.None, isHost: true, options: 'Host / Hidden, HardRock', id: 1, profile: 'https://osu.ppy.sh/u/1' }, + { name: 'player2[abc]', slot: 2, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 2, profile: 'https://osu.ppy.sh/u/2' }, + { name: 'pl a ye r3', slot: 3, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 3, profile: 'https://osu.ppy.sh/u/3' }, + { name: 'pl_a[y]er4', slot: 4, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 4, profile: 'https://osu.ppy.sh/u/4' }, + { name: 'player5abcdefga', slot: 5, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 5, profile: 'https://osu.ppy.sh/u/5' }, + { name: 'pla y e r 6efga', slot: 6, ready: 'Not Ready', team: Teams.None, isHost: false, options: 'Hidden', id: 6, profile: 'https://osu.ppy.sh/u/6' }, + { name: 'player7abc[fga]', slot: 16, ready: 'Not Ready', team: Teams.None, isHost: false, options: 'Hidden', id: 7, profile: 'https://osu.ppy.sh/u/7' },] } }, team: { - title: "team", + title: 'team', texts: [ - "Room name: 4* auto host rotaion test, History: https://osu.ppy.sh/mp/54597968", - "Beatmap: https://osu.ppy.sh/b/1569586 Chaos City Niigata - Ukiyoe Yokochou [Insane]", - "Team mode: TeamVs, Win condition: Score", - "Active mods: Freemod", - "Players: 2", - "Slot 1 Ready https://osu.ppy.sh/u/111 p1 [Host / Team Blue]", - "Slot 2 No Map https://osu.ppy.sh/u/222 p2 [Team Red ]",], + 'Room name: 4* auto host rotaion test, History: https://osu.ppy.sh/mp/54597968', + 'Beatmap: https://osu.ppy.sh/b/1569586 Chaos City Niigata - Ukiyoe Yokochou [Insane]', + 'Team mode: TeamVs, Win condition: Score', + 'Active mods: Freemod', + 'Players: 2', + 'Slot 1 Ready https://osu.ppy.sh/u/111 p1 [Host / Team Blue]', + 'Slot 2 No Map https://osu.ppy.sh/u/222 p2 [Team Red ]',], result: { - name: "4* auto host rotaion test", id: 54597968, history: "https://osu.ppy.sh/mp/54597968", - beatmapId: 1569586, beatmapUrl: "https://osu.ppy.sh/b/1569586", beatmapTitle: "Chaos City Niigata - Ukiyoe Yokochou [Insane]", - teamMode: "TeamVs", winCondition: "Score", activeMods: "Freemod", + name: '4* auto host rotaion test', id: 54597968, history: 'https://osu.ppy.sh/mp/54597968', + beatmapId: 1569586, beatmapUrl: 'https://osu.ppy.sh/b/1569586', beatmapTitle: 'Chaos City Niigata - Ukiyoe Yokochou [Insane]', + teamMode: 'TeamVs', winCondition: 'Score', activeMods: 'Freemod', numPlayers: 2, players: [ - { name: "p1", slot: 1, ready: "Ready", team: Teams.Blue, isHost: true, options: "Host / Team Blue", id: 111, profile: "https://osu.ppy.sh/u/111" }, - { name: "p2", slot: 2, ready: "No Map", team: Teams.Red, isHost: false, options: "Team Red", id: 222, profile: "https://osu.ppy.sh/u/222" } + { name: 'p1', slot: 1, ready: 'Ready', team: Teams.Blue, isHost: true, options: 'Host / Team Blue', id: 111, profile: 'https://osu.ppy.sh/u/111' }, + { name: 'p2', slot: 2, ready: 'No Map', team: Teams.Red, isHost: false, options: 'Team Red', id: 222, profile: 'https://osu.ppy.sh/u/222' } ] } }, template: { - title: "template", + title: 'template', texts: [ - "Room name: roomName, History: https://osu.ppy.sh/mp/123", - "Beatmap: https://osu.ppy.sh/b/123 map name [normal]", - "Team mode: HeadToHead, Win condition: Score", - "Active mods: Freemod", - "Players: 5", - "Slot 1 Not Ready https://osu.ppy.sh/u/1 player1 [Host]", - "Slot 2 Not Ready https://osu.ppy.sh/u/2 player2 ", - "Slot 3 Not Ready https://osu.ppy.sh/u/3 player3 ", - "Slot 4 Not Ready https://osu.ppy.sh/u/4 player4 ", - "Slot 5 Not Ready https://osu.ppy.sh/u/5 player5 "], + 'Room name: roomName, History: https://osu.ppy.sh/mp/123', + 'Beatmap: https://osu.ppy.sh/b/123 map name [normal]', + 'Team mode: HeadToHead, Win condition: Score', + 'Active mods: Freemod', + 'Players: 5', + 'Slot 1 Not Ready https://osu.ppy.sh/u/1 player1 [Host]', + 'Slot 2 Not Ready https://osu.ppy.sh/u/2 player2 ', + 'Slot 3 Not Ready https://osu.ppy.sh/u/3 player3 ', + 'Slot 4 Not Ready https://osu.ppy.sh/u/4 player4 ', + 'Slot 5 Not Ready https://osu.ppy.sh/u/5 player5 '], result: { - name: "roomName", id: 123, history: "https://osu.ppy.sh/mp/123", - beatmapId: 123, beatmapUrl: "https://osu.ppy.sh/b/123", beatmapTitle: "map name [normal]", - teamMode: "HeadToHead", winCondition: "Score", activeMods: "Freemod", + name: 'roomName', id: 123, history: 'https://osu.ppy.sh/mp/123', + beatmapId: 123, beatmapUrl: 'https://osu.ppy.sh/b/123', beatmapTitle: 'map name [normal]', + teamMode: 'HeadToHead', winCondition: 'Score', activeMods: 'Freemod', numPlayers: 5, players: [ - { name: "player1", slot: 1, ready: "Not Ready", team: Teams.None, isHost: true, options: "Host", id: 1, profile: "https://osu.ppy.sh/u/1" }, - { name: "player2", slot: 2, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 2, profile: "https://osu.ppy.sh/u/2" }, - { name: "player3", slot: 3, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 3, profile: "https://osu.ppy.sh/u/3" }, - { name: "player4", slot: 4, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 4, profile: "https://osu.ppy.sh/u/4" }, - { name: "player5", slot: 5, ready: "Not Ready", team: Teams.None, isHost: false, options: "", id: 5, profile: "https://osu.ppy.sh/u/5" }, + { name: 'player1', slot: 1, ready: 'Not Ready', team: Teams.None, isHost: true, options: 'Host', id: 1, profile: 'https://osu.ppy.sh/u/1' }, + { name: 'player2', slot: 2, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 2, profile: 'https://osu.ppy.sh/u/2' }, + { name: 'player3', slot: 3, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 3, profile: 'https://osu.ppy.sh/u/3' }, + { name: 'player4', slot: 4, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 4, profile: 'https://osu.ppy.sh/u/4' }, + { name: 'player5', slot: 5, ready: 'Not Ready', team: Teams.None, isHost: false, options: '', id: 5, profile: 'https://osu.ppy.sh/u/5' }, ] } } -} +}; diff --git a/src/trials/AppendersTrial.ts b/src/trials/AppendersTrial.ts index a5057b03..cbe11c9c 100644 --- a/src/trials/AppendersTrial.ts +++ b/src/trials/AppendersTrial.ts @@ -9,87 +9,87 @@ export interface DiscordBotConfig { } const COMMANDS: ApplicationCommandData[] = [ - { - name: "test", - description: "execute appender test", - }, + { + name: 'test', + description: 'execute appender test', + }, ]; export async function trial() { - const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_INTEGRATIONS] }) - const cfg = config.get("Discord"); - - log4js.configure({ - appenders: { - discord: { - type: "src/discord/DiscordAppender", - layout: { - type: "pattern", - pattern: "%m" - } - }, - }, - categories: { default: { appenders: ['discord'], level: 'all' } } - }); + const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_INTEGRATIONS] }); + const cfg = config.get('Discord'); - client.once('ready', async cl => { - for (let g of cl.guilds.cache.values()) { - await registerCommands(g); + log4js.configure({ + appenders: { + discord: { + type: 'src/discord/DiscordAppender', + layout: { + type: 'pattern', + pattern: '%m' } + }, + }, + categories: { default: { appenders: ['discord'], level: 'all' } } + }); - console.log(`invite link => ${generateInviteLink(client)}`); - setContext(cl, {}); - }); + client.once('ready', async cl => { + for (const g of cl.guilds.cache.values()) { + await registerCommands(g); + } - client.on("interactionCreate", async interaction => { - if (!interaction.isCommand()) return; - if (!interaction.inGuild()) return; - switch (interaction.commandName) { - case "test": - await test(interaction); - break; - } - }); + console.log(`invite link => ${generateInviteLink(client)}`); + setContext(cl, {}); + }); + + client.on('interactionCreate', async interaction => { + if (!interaction.isCommand()) return; + if (!interaction.inGuild()) return; + switch (interaction.commandName) { + case 'test': + await test(interaction); + break; + } + }); - await client.login(cfg.token); + await client.login(cfg.token); } async function test(interaction: GuildCommandInteraction) { - let chatlogger = log4js.getLogger("chat"); - setDiscordId(interaction, chatlogger); - chatlogger.trace("%s:%s", "user1", "hello"); - chatlogger.info("%s:%s", "user2", "hello"); + const chatlogger = log4js.getLogger('chat'); + setDiscordId(interaction, chatlogger); + chatlogger.trace('%s:%s', 'user1', 'hello'); + chatlogger.info('%s:%s', 'user2', 'hello'); - let inout = log4js.getLogger("inout"); - setDiscordId(interaction, inout); - inout.trace("+\x1B[32m Gaevsk1y, Althic_ \x1B[0m, -\x1B[31m Tryeforce(2), Shinkilol(1) \x1B[0m"); - inout.trace("+\x1B[32m Lammahs, Toga_love, m180icheui, Blobby, jjw4074, JohnsonxD \x1B[0m"); - inout.info("-\x1B[31m popth4molly(2), KingBaLK(1), Gaevsk1y(1) \x1B[0m"); + const inout = log4js.getLogger('inout'); + setDiscordId(interaction, inout); + inout.trace('+\x1B[32m Gaevsk1y, Althic_ \x1B[0m, -\x1B[31m Tryeforce(2), Shinkilol(1) \x1B[0m'); + inout.trace('+\x1B[32m Lammahs, Toga_love, m180icheui, Blobby, jjw4074, JohnsonxD \x1B[0m'); + inout.info('-\x1B[31m popth4molly(2), KingBaLK(1), Gaevsk1y(1) \x1B[0m'); - let lobby = log4js.getLogger("lobby"); - setDiscordId(interaction, lobby); - lobby.info("info log"); - lobby.warn("warn log"); - lobby.error("error log"); - await interaction.reply("end"); + const lobby = log4js.getLogger('lobby'); + setDiscordId(interaction, lobby); + lobby.info('info log'); + lobby.warn('warn log'); + lobby.error('error log'); + await interaction.reply('end'); } function generateInviteLink(client: Client): string { - return client.generateInvite({ - scopes: ['bot', 'applications.commands'], - permissions: [ - Permissions.FLAGS.MANAGE_CHANNELS, - Permissions.FLAGS.MANAGE_ROLES - ] - }); + return client.generateInvite({ + scopes: ['bot', 'applications.commands'], + permissions: [ + Permissions.FLAGS.MANAGE_CHANNELS, + Permissions.FLAGS.MANAGE_ROLES + ] + }); } async function registerCommands(guild: Guild) { - await guild.commands.set(COMMANDS); + await guild.commands.set(COMMANDS); } function setDiscordId(interaction: GuildCommandInteraction, logger: any) { - logger.addContext("guildId", interaction.guildId); - logger.addContext("channelId", interaction.channelId); + logger.addContext('guildId', interaction.guildId); + logger.addContext('channelId', interaction.channelId); } diff --git a/src/trials/BanchoIrcTrial.ts b/src/trials/BanchoIrcTrial.ts index 4b1df39e..4669852e 100644 --- a/src/trials/BanchoIrcTrial.ts +++ b/src/trials/BanchoIrcTrial.ts @@ -19,7 +19,7 @@ export function trial() { console.log('Got private message from %s: %s', nick, message); const v = parser.ParseMpMakeResponse(nick, message); if (v != null) { - console.log(`--- parsed pm id=${v.id} title=${v.title}`) + console.log(`--- parsed pm id=${v.id} title=${v.title}`); } }); @@ -49,7 +49,7 @@ export function trial() { bot.addListener('registered', function (message) { console.log('registered %s', message); //bot.say("BanchoBot", "!mp make irc test lobby4"); - bot.join("#lobby"); + bot.join('#lobby'); }); } @@ -59,12 +59,12 @@ export function ConnectionServerTrial() { logIrcEvent(bot); - console.log("hostmask => " + bot.hostMask); + console.log('hostmask => ' + bot.hostMask); bot.connect(); bot.addListener('registered', function (message) { - console.log("hostmask => " + bot.hostMask); - bot.disconnect("goodby", () => { console.log("disconnected"); }); + console.log('hostmask => ' + bot.hostMask); + bot.disconnect('goodby', () => { console.log('disconnected'); }); }); } diff --git a/src/trials/DiscordTrial.ts b/src/trials/DiscordTrial.ts index 6b840959..58c1f0ee 100644 --- a/src/trials/DiscordTrial.ts +++ b/src/trials/DiscordTrial.ts @@ -10,102 +10,102 @@ interface DiscordOption { } const commands = [ - { - name: "ping", - description: "ping" - } -] + { + name: 'ping', + description: 'ping' + } +]; const ADMIN_ROLE: CreateRoleOptions = { - name: "ahr-admin", - color: "ORANGE", - reason: "ahr-bot administrator" + name: 'ahr-admin', + color: 'ORANGE', + reason: 'ahr-bot administrator' }; export async function trial() { - let client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_INTEGRATIONS] }); - let cfg = config.get("Discord"); + const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_INTEGRATIONS] }); + const cfg = config.get('Discord'); - client.once('ready', async cl => { - console.log('Ready! ' + generateInviteLink()); - for (let g of cl.guilds.cache.values()) { - await g.commands.set(commands); - } - }); + client.once('ready', async cl => { + console.log('Ready! ' + generateInviteLink()); + for (const g of cl.guilds.cache.values()) { + await g.commands.set(commands); + } + }); - client.on('interactionCreate', async interaction => { - if (!interaction.inGuild()) return; - - if (interaction.isCommand()) { - if (interaction.commandName === "ping") { - const emb = new MessageEmbed().setColor("AQUA").setTitle("aaa").addField("field", "aa"); - const btn1 = new MessageButton().setLabel("menu").setStyle(MessageButtonStyles.SUCCESS).setCustomId("menu"); - const row = new MessageActionRow().addComponents(btn1); - await interaction.reply("Pong!"); - await interaction.channel?.send({ embeds: [emb], components: [row] }); - } - } - - if (interaction.isButton()) { - switch (interaction.customId) { - case "menu": - if (checkMemberHasAhrAdminRole(interaction.member as GuildMember)) { - await interaction.reply({ - content: "admin menu", - components: [new MessageActionRow().addComponents(new MessageButton().setLabel("transfer").setStyle(MessageButtonStyles.SUCCESS).setCustomId("transfer"), new MessageButton().setLabel("close").setStyle(MessageButtonStyles.DANGER).setCustomId("close"))], - ephemeral: true - }); - } else { - await interaction.reply({ - content: "there is no menu for you.", - ephemeral: true - }); - } - - break; - - case "transfer": - await interaction.reply({ content: "start transfer", ephemeral: true }); - break; - - case "close": - await interaction.reply({ content: "close", ephemeral: true }); - break; - } - } - }); + client.on('interactionCreate', async interaction => { + if (!interaction.inGuild()) return; - client.on("messageCreate", async message => { - console.log("msg:" + message.content); + if (interaction.isCommand()) { + if (interaction.commandName === 'ping') { + const emb = new MessageEmbed().setColor('AQUA').setTitle('aaa').addField('field', 'aa'); + const btn1 = new MessageButton().setLabel('menu').setStyle(MessageButtonStyles.SUCCESS).setCustomId('menu'); + const row = new MessageActionRow().addComponents(btn1); + await interaction.reply('Pong!'); + await interaction.channel?.send({ embeds: [emb], components: [row] }); + } + } - if (message.author.bot) { - return; - } + if (interaction.isButton()) { + switch (interaction.customId) { + case 'menu': + if (checkMemberHasAhrAdminRole(interaction.member as GuildMember)) { + await interaction.reply({ + content: 'admin menu', + components: [new MessageActionRow().addComponents(new MessageButton().setLabel('transfer').setStyle(MessageButtonStyles.SUCCESS).setCustomId('transfer'), new MessageButton().setLabel('close').setStyle(MessageButtonStyles.DANGER).setCustomId('close'))], + ephemeral: true + }); + } else { + await interaction.reply({ + content: 'there is no menu for you.', + ephemeral: true + }); + } + + break; + + case 'transfer': + await interaction.reply({ content: 'start transfer', ephemeral: true }); + break; + + case 'close': + await interaction.reply({ content: 'close', ephemeral: true }); + break; + } + } + }); - if (message.content === "ai") { - await message.channel.send("ou"); - } - }); + client.on('messageCreate', async message => { + console.log('msg:' + message.content); - console.log(cfg.token); - await client.login(cfg.token); - - function generateInviteLink(): string { - return client.generateInvite({ - scopes: ['bot', 'applications.commands'], - permissions: [ - Permissions.FLAGS.MANAGE_CHANNELS, - Permissions.FLAGS.MANAGE_ROLES, - Permissions.FLAGS.MANAGE_MESSAGES, - ] - }); + if (message.author.bot) { + return; } - function checkMemberHasAhrAdminRole(member: GuildMember) { - return member.roles.cache.find(f => f.name == ADMIN_ROLE.name) !== undefined; + if (message.content === 'ai') { + await message.channel.send('ou'); } + }); + + console.log(cfg.token); + await client.login(cfg.token); + + function generateInviteLink(): string { + return client.generateInvite({ + scopes: ['bot', 'applications.commands'], + permissions: [ + Permissions.FLAGS.MANAGE_CHANNELS, + Permissions.FLAGS.MANAGE_ROLES, + Permissions.FLAGS.MANAGE_MESSAGES, + ] + }); + } + + function checkMemberHasAhrAdminRole(member: GuildMember) { + return member.roles.cache.find(f => f.name == ADMIN_ROLE.name) !== undefined; + } } diff --git a/src/trials/HistryTrial.ts b/src/trials/HistryTrial.ts index 469f1cf3..073c30b9 100644 --- a/src/trials/HistryTrial.ts +++ b/src/trials/HistryTrial.ts @@ -17,7 +17,7 @@ async function GetHistryTrial() { const params = { 'limit': 100, 'before': 1695874063 - } + }; const response = await axios.get(url, { params }) .catch(err => { @@ -26,24 +26,24 @@ async function GetHistryTrial() { console.log(JSON.stringify(response.data)); - fs.writeFile("data/arc/history_76714773_joinleftsametime.json", JSON.stringify(response.data)); + fs.writeFile('data/arc/history_76714773_joinleftsametime.json', JSON.stringify(response.data)); } async function GetOrderTrial() { const matchId = 76714773; const repo = new HistoryRepository(matchId); - const res = await repo.calcCurrentOrderAsName() + const res = await repo.calcCurrentOrderAsName(); console.log(res); } async function GetLobbyNameChanger() { - let hr = new HistoryRepository(67719013, new HistoryFecher()); - let ln = ""; + const hr = new HistoryRepository(67719013, new HistoryFecher()); + let ln = ''; hr.changedLobbyName.on(e => { - console.log(e.oldName + "->" + e.newName + " "); + console.log(e.oldName + '->' + e.newName + ' '); ln = e.newName; }); - while (!ln.startsWith("4-5*")) { + while (!ln.startsWith('4-5*')) { await hr.fetch(true); } } @@ -51,22 +51,22 @@ async function GetLobbyNameChanger() { async function promiseTrial() { let task = delayAsync(100).then(() => 1); setImmediate(async () => { - let n = await task; - console.log("i1 " + n); + const n = await task; + console.log('i1 ' + n); }); setImmediate(async () => { task = task.then(() => 2); - let n = await task; - console.log("i2 " + n); + const n = await task; + console.log('i2 ' + n); }); setImmediate(async () => { task = task.then(() => 3); - let n = await task; - console.log("i3 " + n); + const n = await task; + console.log('i3 ' + n); }); setImmediate(async () => { - let n = await task; - console.log("i4 " + n); + const n = await task; + console.log('i4 ' + n); }); } diff --git a/src/trials/IrcTrial.ts b/src/trials/IrcTrial.ts index e864046a..bb7d761b 100644 --- a/src/trials/IrcTrial.ts +++ b/src/trials/IrcTrial.ts @@ -1,9 +1,9 @@ import * as irc from '../libs/irc'; const IrcTestSettings = { - server: "irc.dollyfish.net.nz", - nick: "ohr", - channel: "#test" + server: 'irc.dollyfish.net.nz', + nick: 'ohr', + channel: '#test' }; export function trial() { @@ -57,6 +57,6 @@ export function trial() { bot.addListener('registered', function (message) { console.log('registered %s', message); - bot.join("#test"); + bot.join('#test'); }); } diff --git a/src/trials/LobbynameTrial.ts b/src/trials/LobbynameTrial.ts index e78f8705..fd44a3e8 100644 --- a/src/trials/LobbynameTrial.ts +++ b/src/trials/LobbynameTrial.ts @@ -1,11 +1,11 @@ export function trial() { - let cases = ["a", "asdflkj", " $% BN |~=", "4-5 | alt | test @join", "あいうおaaa", "aa\n\raa"]; - for (let c of cases) { - console.log(`${c} => ${rep(c)}`); - } + const cases = ['a', 'asdflkj', ' $% BN |~=', '4-5 | alt | test @join', 'あいうおaaa', 'aa\n\raa']; + for (const c of cases) { + console.log(`${c} => ${rep(c)}`); + } } function rep(text: string): string { - text = text.replace(/[^ -/:-@\[-~0-9a-zA-Z]/g, ""); - return text; + text = text.replace(/[^ -/:-@\[-~0-9a-zA-Z]/g, ''); + return text; } \ No newline at end of file diff --git a/src/trials/TypedEventTrials.ts b/src/trials/TypedEventTrials.ts index 079a8b42..f75c4740 100644 --- a/src/trials/TypedEventTrials.ts +++ b/src/trials/TypedEventTrials.ts @@ -1,18 +1,18 @@ import { TypedEvent } from '../libs/TypedEvent'; export function trial() { - let e1 = new TypedEvent(); + const e1 = new TypedEvent(); e1.once(n => console.log(`fired e1 arg = ${n}`)); e1.emit(1); - let e2 = new TypedEvent<[number, string]>(); + const e2 = new TypedEvent<[number, string]>(); e2.once((t) => console.log(`fired e2 arg1 = ${t[0]} arg2 = ${t[1]}`)); - e2.emit([1, "x"]); + e2.emit([1, 'x']); - let e3 = new TypedEvent<{ a: number, b: string }>(); + const e3 = new TypedEvent<{ a: number, b: string }>(); e3.once((t) => console.log(`fired e2 a = ${t.a} b = ${t.b}`)); const a = 1; - const b = "x"; - const c = "c"; + const b = 'x'; + const c = 'c'; e3.emit({ a, b }); } diff --git a/src/trials/WebApiTrial.ts b/src/trials/WebApiTrial.ts index 6bd6c5b4..14b91fba 100644 --- a/src/trials/WebApiTrial.ts +++ b/src/trials/WebApiTrial.ts @@ -8,7 +8,7 @@ export interface WebApiTrialOption { code: string, } -const oAuthConfig = config.get("WebApi"); +const oAuthConfig = config.get('WebApi'); export async function trial() { //getTokenTrial(); @@ -21,11 +21,11 @@ export async function trial() { export async function getGuestTokenTrial(): Promise { try { - const response = await axios.post("https://osu.ppy.sh/oauth/token", { - "grant_type": "client_credentials", - "client_id": "" + oAuthConfig.client_id, - "client_secret": oAuthConfig.client_secret, - "scope": "public" + const response = await axios.post('https://osu.ppy.sh/oauth/token', { + 'grant_type': 'client_credentials', + 'client_id': '' + oAuthConfig.client_id, + 'client_secret': oAuthConfig.client_secret, + 'scope': 'public' }); const c = response.data; console.log(c); @@ -36,12 +36,12 @@ export async function getGuestTokenTrial(): Promise { export async function getTokenTrial(): Promise { try { - const response = await axios.post("https://osu.ppy.sh/oauth/token", { - "grant_type": "authorization_code", - "client_id": "" + oAuthConfig.client_id, - "client_secret": oAuthConfig.client_secret, - "code": oAuthConfig.code, - "redirect_uri": oAuthConfig.callback + const response = await axios.post('https://osu.ppy.sh/oauth/token', { + 'grant_type': 'authorization_code', + 'client_id': '' + oAuthConfig.client_id, + 'client_secret': oAuthConfig.client_secret, + 'code': oAuthConfig.code, + 'redirect_uri': oAuthConfig.callback }); const c = response.data; console.log(c); @@ -52,7 +52,7 @@ export async function getTokenTrial(): Promise { function objectToURLSearchParams(obj: any): URLSearchParams { const param = new URLSearchParams(); - for (let key in obj) { + for (const key in obj) { param.append(key, obj[key]); } return obj; @@ -60,7 +60,7 @@ function objectToURLSearchParams(obj: any): URLSearchParams { export async function fetchUpdateTrial(): Promise { try { - const r = await axios.get("https://osu.ppy.sh/community/chat/updates?since=2065115911"); + const r = await axios.get('https://osu.ppy.sh/community/chat/updates?since=2065115911'); const c = r.data; console.log(c); } catch (e) { diff --git a/src/trials/WebServerTrial.ts b/src/trials/WebServerTrial.ts index 9e039566..da96306a 100644 --- a/src/trials/WebServerTrial.ts +++ b/src/trials/WebServerTrial.ts @@ -12,29 +12,29 @@ interface PromiseRequestHandler { } function wrap(fn: PromiseRequestHandler): RequestHandler { - return (req, res, next) => fn(req, res, next).catch(next) + return (req, res, next) => fn(req, res, next).catch(next); } function startTestServer() { const app = express(); const port = 3112; - const hostname = "127.0.0.1"; + const hostname = '127.0.0.1'; - app.use("", express.static("src/trials/")); - app.use("/logs", express.static("logs/cli")); + app.use('', express.static('src/trials/')); + app.use('/logs', express.static('logs/cli')); - app.get("/api/user/:id", (req, res, next) => { - let tid = parseInt(req.params.id); + app.get('/api/user/:id', (req, res, next) => { + const tid = parseInt(req.params.id); if (isNaN(tid)) return res.json({}); - let usr = historyData.users.find((v: any) => v.id.toString() == req.params.id); + const usr = historyData.users.find((v: any) => v.id.toString() == req.params.id); return res.json(usr); }); - app.get("/api/clilog/:id", (req, res, next) => { - let p = `logs/cli/${req.params.id}.log`; + app.get('/api/clilog/:id', (req, res, next) => { + const p = `logs/cli/${req.params.id}.log`; let frm = 0; if (req.query.from) { - frm = parseInt(req.query.from + ""); + frm = parseInt(req.query.from + ''); } const stream = fs.createReadStream(p, { start: frm }); const reader = readline.createInterface({ input: stream }); @@ -42,10 +42,10 @@ function startTestServer() { lines: [], end: 0 }; - reader.on("line", (data) => { + reader.on('line', (data) => { result.lines.push(data); }); - reader.on("close", () => { + reader.on('close', () => { result.end = stream.bytesRead + frm; res.json(result); }); @@ -58,7 +58,7 @@ function startTestServer() { } function parseLogLine(line: string): { date: string, level: string, tag: string, message: string } | undefined { - var m = line.match(/^\[(.+?)\] \[(\w+)\] (\w+) - (.*)/); + const m = line.match(/^\[(.+?)\] \[(\w+)\] (\w+) - (.*)/); if (m) { return { date: m[1], @@ -70,7 +70,7 @@ function parseLogLine(line: string): { date: string, level: string, tag: string, } async function parseLogTest() { - let p = `logs/cli/#mp_67681871.log`; + const p = 'logs/cli/#mp_67681871.log'; const stream = fs.createReadStream(p, { start: 64000 }); @@ -79,13 +79,13 @@ async function parseLogTest() { lines: [], end: 0 }; - reader.on("line", (data) => { + reader.on('line', (data) => { result.lines.push(parseLogLine(data)); }); - reader.on("pause", () => { - console.log("pause"); + reader.on('pause', () => { + console.log('pause'); }); - reader.on("close", () => { + reader.on('close', () => { result.end = stream.bytesRead; console.log(result); }); @@ -93,41 +93,41 @@ async function parseLogTest() { } async function readlineTrial() { - let d = "data/test/readline.txt"; - let p = `logs/cli/#mp_67681871.log`; + const d = 'data/test/readline.txt'; + const p = 'logs/cli/#mp_67681871.log'; const ws = fs.createWriteStream(d, { - encoding: "utf8", + encoding: 'utf8', }); const stream = fs.createReadStream(d, { - encoding: "utf8", // 文字コード + encoding: 'utf8', // 文字コード highWaterMark: 1024 // 一度に取得するbyte数 }); const reader = readline.createInterface({ input: stream }); let i = 1; - reader.on("line", (data) => { + reader.on('line', (data) => { // 行番号を作成 - let num = i.toString().padStart(5, "0"); // 5文字未満は"0"で埋める + const num = i.toString().padStart(5, '0'); // 5文字未満は"0"で埋める i++; console.log(`${num}: ${data}`); }); - reader.on("pause", () => { - console.log("pause"); + reader.on('pause', () => { + console.log('pause'); }); - reader.on("close", () => { - console.log("close"); + reader.on('close', () => { + console.log('close'); }); - ws.write("test1\r\n"); - ws.write("test2\r\n"); - ws.write("test3x\r\n"); + ws.write('test1\r\n'); + ws.write('test2\r\n'); + ws.write('test3x\r\n'); await new Promise(resolve => { setTimeout(() => { - ws.write("test4\r\n"); + ws.write('test4\r\n'); resolve(); }, 100); }); - console.log("after await"); + console.log('after await'); } diff --git a/src/trials/index.ts b/src/trials/index.ts index 8382f496..4a14563e 100644 --- a/src/trials/index.ts +++ b/src/trials/index.ts @@ -1,5 +1,5 @@ import log4js from 'log4js'; -log4js.configure("config/log_mocha.json"); +log4js.configure('config/log_mocha.json'); //import * as trial from './WebServerTrial.js'; //trial.webServerTrial(); diff --git a/src/web/LogServer.ts b/src/web/LogServer.ts index 3adfaaef..2093f412 100644 --- a/src/web/LogServer.ts +++ b/src/web/LogServer.ts @@ -5,26 +5,26 @@ import { Server } from 'http'; export function startLogServer(port: number): Server { const app = express(); - app.use("", express.static("src/web/statics")); - app.use("/logs", express.static("logs/cli")); - app.get("/api/clilog", (req, res, next) => { - fs.readdir("logs/cli", (err, files) => { + app.use('', express.static('src/web/statics')); + app.use('/logs', express.static('logs/cli')); + app.get('/api/clilog', (req, res, next) => { + fs.readdir('logs/cli', (err, files) => { if (err) throw err; const r = []; - for (let f of files) { - let m = f.match(/(\d+)\.log/); + for (const f of files) { + const m = f.match(/(\d+)\.log/); if (m) { r.push(parseInt(m[1])); } } res.json(r); - }) + }); }); - app.get("/api/clilog/:id", (req, res, next) => { - let p = `logs/cli/${req.params.id}.log`; + app.get('/api/clilog/:id', (req, res, next) => { + const p = `logs/cli/${req.params.id}.log`; let frm = 0; if (req.query.from) { - frm = parseInt(req.query.from + ""); + frm = parseInt(req.query.from + ''); } const stream = fs.createReadStream(p, { start: frm }); const reader = readline.createInterface({ input: stream }); @@ -32,24 +32,24 @@ export function startLogServer(port: number): Server { lines: [], end: 0 }; - reader.on("line", (data) => { + reader.on('line', (data) => { result.lines.push(data); }); - reader.on("close", () => { + reader.on('close', () => { result.end = stream.bytesRead + frm; res.json(result); }); - stream.on("error", (e) => { - console.log("cought error"); + stream.on('error', (e) => { + console.log('cought error'); next(e); }); }); - app.get("/api/clilog/size/:id", (req, res, next) => { - let p = `logs/cli/${req.params.id}.log`; + app.get('/api/clilog/size/:id', (req, res, next) => { + const p = `logs/cli/${req.params.id}.log`; let frm = 0; if (req.query.from) { - frm = parseInt(req.query.from + ""); + frm = parseInt(req.query.from + ''); } fs.stat(p, (e, stats) => { if (e) { @@ -60,15 +60,15 @@ export function startLogServer(port: number): Server { }); }); - app.get("/api/close", (req, res, next) => { + app.get('/api/close', (req, res, next) => { server.close(); }); const server = app.listen(port, () => { - console.log(`Server running at http://${"localhost"}:${port}/`); + console.log(`Server running at http://${'localhost'}:${port}/`); }); - process.on("exit", (code) => { + process.on('exit', (code) => { server.close(); }); diff --git a/src/web/OahrWeb.ts b/src/web/OahrWeb.ts index 326c8d19..4cb1b25a 100644 --- a/src/web/OahrWeb.ts +++ b/src/web/OahrWeb.ts @@ -3,7 +3,7 @@ import log4js from 'log4js'; import express, { Express } from 'express'; import { Server } from 'http'; -const logger = log4js.getLogger("server"); +const logger = log4js.getLogger('server'); export interface OahrWebOption { port: number; @@ -11,7 +11,7 @@ export interface OahrWebOption { hostname: string; } -const OahrWebDefaultOption = config.get("OahrWeb"); +const OahrWebDefaultOption = config.get('OahrWeb'); export class OahrWeb { config: OahrWebOption; @@ -23,12 +23,12 @@ export class OahrWeb { this.app = express(); this.app.use(express.static(this.config.staticDir)); this.server = this.app.listen(this.config.port, this.config.hostname, () => { - console.log(`Server running at http://${this.config.hostname}:${this.config.port}/`) + console.log(`Server running at http://${this.config.hostname}:${this.config.port}/`); }); - this.app.get("/api/test/:id", (req, res, next) => { + this.app.get('/api/test/:id', (req, res, next) => { const re = { - test:"hello", + test:'hello', id: req.params.id }; res.json(re); diff --git a/src/web/statics/main.js b/src/web/statics/main.js index dd94a408..0572ef97 100644 --- a/src/web/statics/main.js +++ b/src/web/statics/main.js @@ -3,13 +3,13 @@ if (!lines) return; let c = null; - for (let l of lines) { - let b = parseLogLine(l); + for (const l of lines) { + const b = parseLogLine(l); if (b) { if (c) yield c; c = b; } else if (c) { - c.message += "
" + l; + c.message += '
' + l; } } if (c) yield c; @@ -17,8 +17,8 @@ function* filterLogs(logs) { if (!logs) return; - for (let l of logs) { - if (l.tag == "mapChecker") { + for (const l of logs) { + if (l.tag == 'mapChecker') { continue; } yield l; @@ -26,9 +26,9 @@ } function parseLogLine(line) { - var m = line.match(/^\[(.+?)\] \[(\w+)\] (\w+) - (.*)/); + const m = line.match(/^\[(.+?)\] \[(\w+)\] (\w+) - (.*)/); if (m) { - let d = { + const d = { date: m[1], level: m[2], tag: m[3], @@ -45,20 +45,20 @@ } function convertLink(log) { - log.message = log.message.replace(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/, "$&") + log.message = log.message.replace(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/, '$&'); } function decolateChat(log) { - let sender = "system"; - let message = ""; - let cl = ""; - if (log.tag == "chat") { + let sender = 'system'; + let message = ''; + let cl = ''; + if (log.tag == 'chat') { const m = log.message.match(/^(\*?[^\:]+)\:(.*)$/); sender = m[1]; message = m[2]; - cl = (sender == "bot") ? " bot" : " user"; - } else if (log.tag == "inout") { - for (let v of log.message.split("\x1b")) { + cl = (sender == 'bot') ? ' bot' : ' user'; + } else if (log.tag == 'inout') { + for (const v of log.message.split('\x1b')) { const m = v.match(/^\[(\d+)m(.*)/); if (m) { message += `${m[2]}`; @@ -68,68 +68,68 @@ } } else { message = log.message; - cl = " system"; + cl = ' system'; } log.message = `${sender}:
${message}
`; } function formatDate(date) { const M = date.getMonth() + 1; - const d = ("" + date.getDate()).padStart(2, "0"); - const h = ("" + date.getHours()).padStart(2, "0"); - const m = ("" + date.getMinutes()).padStart(2, "0"); - const s = ("" + date.getSeconds()).padStart(2, "0"); + const d = ('' + date.getDate()).padStart(2, '0'); + const h = ('' + date.getHours()).padStart(2, '0'); + const m = ('' + date.getMinutes()).padStart(2, '0'); + const s = ('' + date.getSeconds()).padStart(2, '0'); return `${M}/${d} ${h}:${m}:${s}`; } function AppendLog(log) { decolate(log); - let li = document.createElement("li"); - let spDate = document.createElement("time"); - spDate.className = "date"; - spDate.setAttribute("datetime", log.date); + const li = document.createElement('li'); + const spDate = document.createElement('time'); + spDate.className = 'date'; + spDate.setAttribute('datetime', log.date); spDate.innerText = formatDate(new Date(log.date)); - let spLevel = document.createElement("span"); - spLevel.className = "level"; + const spLevel = document.createElement('span'); + spLevel.className = 'level'; spLevel.innerText = log.level; - let spTag = document.createElement("span"); - spTag.className = "tag"; + const spTag = document.createElement('span'); + spTag.className = 'tag'; spTag.innerText = log.tag; - let spMsg = document.createElement("span"); - spMsg.className = "message"; + const spMsg = document.createElement('span'); + spMsg.className = 'message'; spMsg.innerHTML = log.message; - li.classList.add("lvl_" + log.level); - li.classList.add("tag_" + log.tag); + li.classList.add('lvl_' + log.level); + li.classList.add('tag_' + log.tag); li.appendChild(spMsg); li.appendChild(spDate); li.appendChild(spLevel); li.appendChild(spTag); - let listElem = document.getElementById("list"); + const listElem = document.getElementById('list'); listElem.appendChild(li); } function test_static_data() { const logs = [ - "[2020-10-13T00:32:03.815] [TRACE] skipper - stop timer", - "[2020-10-13T00:32:12.081] [TRACE] selector - removed TheDqvex from host queue", - "[2020-10-13T00:36:45.544] [INFO] lobby - beatmap changed(by ChickenNugget) : https://osu.ppy.sh/b/173391 Igorrr - Pavor Nocturnus [Insane]", - "[2020-10-14T01:50:32.278] [INFO] chat - picked map: https://osu.ppy.sh/beatmaps/2017496 Until The World Ends star=5.78 length=5:10", - "Violation of Regulation : 5.00 <= difficulty <= 6.00, length <= 5:00", - "The map is a bit out of regulation. you can skip current host with '!skip' voting command.", - " ", - "[2020-10-14T01:50:32.279] [TRACE] chat - bot:Queued the match to start in 90 seconds", - "[2020-10-14T01:50:51.570] [INFO] chat - bappojappo:is this a stream", - "[2020-10-14T01:50:53.941] [INFO] chat - bappojappo:map", - "[2020-10-15T02:58:35.191] [INFO] inout - - mcclennys ", - "[2020-10-15T03:08:26.782] [INFO] inout - + Tobymusen , - leon4chanel " + '[2020-10-13T00:32:03.815] [TRACE] skipper - stop timer', + '[2020-10-13T00:32:12.081] [TRACE] selector - removed TheDqvex from host queue', + '[2020-10-13T00:36:45.544] [INFO] lobby - beatmap changed(by ChickenNugget) : https://osu.ppy.sh/b/173391 Igorrr - Pavor Nocturnus [Insane]', + '[2020-10-14T01:50:32.278] [INFO] chat - picked map: https://osu.ppy.sh/beatmaps/2017496 Until The World Ends star=5.78 length=5:10', + 'Violation of Regulation : 5.00 <= difficulty <= 6.00, length <= 5:00', + 'The map is a bit out of regulation. you can skip current host with \'!skip\' voting command.', + ' ', + '[2020-10-14T01:50:32.279] [TRACE] chat - bot:Queued the match to start in 90 seconds', + '[2020-10-14T01:50:51.570] [INFO] chat - bappojappo:is this a stream', + '[2020-10-14T01:50:53.941] [INFO] chat - bappojappo:map', + '[2020-10-15T02:58:35.191] [INFO] inout - - mcclennys ', + '[2020-10-15T03:08:26.782] [INFO] inout - + Tobymusen , - leon4chanel ' ]; - let al = parseLogs(logs); - let bl = filterLogs(al); + const al = parseLogs(logs); + const bl = filterLogs(al); - for (let v of bl) { + for (const v of bl) { AppendLog(v); } } @@ -139,37 +139,37 @@ } function setMapId(mapId) { - document.getElementsByName("mapid")[0].value = mapId; - document.location.search = "mapid=" + mapId; + document.getElementsByName('mapid')[0].value = mapId; + document.location.search = 'mapid=' + mapId; } function updateClicked() { - let value = document.getElementsByName("mapid")[0].value; - document.location.search = "mapid=" + value; + const value = document.getElementsByName('mapid')[0].value; + document.location.search = 'mapid=' + value; } function closeClicked() { - fetch(`/api/close`).then(async res => { - let r = await res.json(); + fetch('/api/close').then(async res => { + const r = await res.json(); alert(r.result); - }) + }); } let cursor = 0; let timeid = 0; function fetchLogsAsync() { - let mapId = document.getElementsByName("mapid")[0].value; - let autoScrollCheckBox = document.getElementsByName("autoScroll")[0]; + const mapId = document.getElementsByName('mapid')[0].value; + const autoScrollCheckBox = document.getElementsByName('autoScroll')[0]; clearTimeout(timeid); return fetch(`/api/clilog/${mapId}?from=${cursor}`).then(res => { return res.json(); }).then(data => { cursor = data.end; - let al = parseLogs(data.lines); - let bl = filterLogs(al); + const al = parseLogs(data.lines); + const bl = filterLogs(al); - for (let l of bl) { + for (const l of bl) { AppendLog(l); } if (autoScrollCheckBox.checked) { @@ -191,12 +191,12 @@ } function fetchMapIds() { - return fetch(`/api/clilog`).then(res => { + return fetch('/api/clilog').then(res => { return res.json(); }).then(data => { - let idElem = document.getElementById("ids"); - for (let id of data) { - const c = document.createElement("option"); + const idElem = document.getElementById('ids'); + for (const id of data) { + const c = document.createElement('option'); c.value = id; idElem.appendChild(c); } @@ -204,28 +204,28 @@ } function ScrollToBottom() { - let doc = document.documentElement; - let bottom = doc.scrollHeight - doc.clientHeight; + const doc = document.documentElement; + const bottom = doc.scrollHeight - doc.clientHeight; window.scroll(0, bottom); } function init() { - let params = (new URL(document.location)).searchParams; - let mapId = params.get("mapid"); + const params = (new URL(document.location)).searchParams; + const mapId = params.get('mapid'); fetchMapIds(); if (mapId) { - document.getElementsByName("mapid")[0].value = mapId; + document.getElementsByName('mapid')[0].value = mapId; fetchLogSize(mapId).then(() => { fetchLogsAsync(mapId); }); - let his = document.getElementById("history"); - his.href = "https://osu.ppy.sh/community/matches/" + mapId; - his.innerText = "history"; + const his = document.getElementById('history'); + his.href = 'https://osu.ppy.sh/community/matches/' + mapId; + his.innerText = 'history'; } - document.getElementById("update").addEventListener("click", () => updateClicked()); - document.getElementById("close").addEventListener("click", () => closeClicked()); - document.getElementById("fetchlog").addEventListener("click", () => fetchLogsAsync()); + document.getElementById('update').addEventListener('click', () => updateClicked()); + document.getElementById('close').addEventListener('click', () => closeClicked()); + document.getElementById('fetchlog').addEventListener('click', () => fetchLogsAsync()); } init(); diff --git a/src/webapi/BeatmapRepository.ts b/src/webapi/BeatmapRepository.ts index 3fd80c19..696e751d 100644 --- a/src/webapi/BeatmapRepository.ts +++ b/src/webapi/BeatmapRepository.ts @@ -6,24 +6,24 @@ import { WebApiClient } from './WebApiClient'; export type BeatmapCache = Beatmap & { fetchedAt: number }; class BeatmapRepositoryClass { - maps: Map; - cacheExpiredMs: number; - fetcher: IBeatmapFetcher; - - websiteFetcher: IBeatmapFetcher; - - constructor() { - this.maps = new Map(); - this.cacheExpiredMs = 24 * 3600 * 1000; - this.websiteFetcher = new WebsiteBeatmapFecher(); - if (WebApiClient.available) { - this.fetcher = WebApiClient; - } else { - this.fetcher = this.websiteFetcher; - } + maps: Map; + cacheExpiredMs: number; + fetcher: IBeatmapFetcher; + + websiteFetcher: IBeatmapFetcher; + + constructor() { + this.maps = new Map(); + this.cacheExpiredMs = 24 * 3600 * 1000; + this.websiteFetcher = new WebsiteBeatmapFecher(); + if (WebApiClient.available) { + this.fetcher = WebApiClient; + } else { + this.fetcher = this.websiteFetcher; } + } - /** + /** * * @param mapId * @param mode @@ -31,70 +31,70 @@ class BeatmapRepositoryClass { * @returns * @throws FetchBeatmapError */ - async getBeatmap(mapId: number, mode: PlayMode = PlayMode.Osu, allowConvert: boolean = true): Promise { - if (this.fetcher == WebApiClient) { - if (!WebApiClient.available) { - this.fetcher = this.websiteFetcher; - } - } + async getBeatmap(mapId: number, mode: PlayMode = PlayMode.Osu, allowConvert: boolean = true): Promise { + if (this.fetcher == WebApiClient) { + if (!WebApiClient.available) { + this.fetcher = this.websiteFetcher; + } + } - let cache = this.tryGetCache(mapId, mode, allowConvert); - if (cache) return cache; + let cache = this.tryGetCache(mapId, mode, allowConvert); + if (cache) return cache; - const set = await this.fetcher.getBeatmapset(mapId); - if (set.availability.download_disabled == true || set.availability.more_information != null) { - throw new FetchBeatmapError(FetchBeatmapErrorReason.NotAvailable); - } - this.cacheMaps(set); + const set = await this.fetcher.getBeatmapset(mapId); + if (set.availability.download_disabled == true || set.availability.more_information != null) { + throw new FetchBeatmapError(FetchBeatmapErrorReason.NotAvailable); + } + this.cacheMaps(set); - cache = this.tryGetCache(mapId, mode, allowConvert); - if (cache) return cache; + cache = this.tryGetCache(mapId, mode, allowConvert); + if (cache) return cache; - throw new FetchBeatmapError(FetchBeatmapErrorReason.PlayModeMismatched); - } + throw new FetchBeatmapError(FetchBeatmapErrorReason.PlayModeMismatched); + } - tryGetCache(mapId: number, mode: PlayMode = PlayMode.Osu, allowConvert: boolean = true): BeatmapCache | undefined { - const mapKey = this.genKey(mapId, mode); - const cache = this.maps.get(mapKey); - - if (cache) { - if (Date.now() < cache.fetchedAt + this.cacheExpiredMs) { - if (mode == PlayMode.Osu || allowConvert || !cache.convert) { - return cache; - } - } else { - this.maps.delete(mapKey); - } - } - } + tryGetCache(mapId: number, mode: PlayMode = PlayMode.Osu, allowConvert: boolean = true): BeatmapCache | undefined { + const mapKey = this.genKey(mapId, mode); + const cache = this.maps.get(mapKey); - cacheMaps(set: Beatmapset) { - const now = Date.now(); - set.recent_favourites = []; - for (const map of [...set.beatmaps ?? [], ...set.converts ?? []] as BeatmapCache[]) { - const key = this.genKey(map.id, map.mode); - map.fetchedAt = now; - map.beatmapset = set; - map.failtimes = { exit: [], fail: [] }; - this.maps.set(key, map); + if (cache) { + if (Date.now() < cache.fetchedAt + this.cacheExpiredMs) { + if (mode == PlayMode.Osu || allowConvert || !cache.convert) { + return cache; } + } else { + this.maps.delete(mapKey); + } } - - discardExpiredCache(expiredMs: number = this.cacheExpiredMs) { - const now = Date.now(); - for (const [key, cache] of this.maps.entries()) { - if (now > cache.fetchedAt + expiredMs) { - this.maps.delete(key); - } - } + } + + cacheMaps(set: Beatmapset) { + const now = Date.now(); + set.recent_favourites = []; + for (const map of [...set.beatmaps ?? [], ...set.converts ?? []] as BeatmapCache[]) { + const key = this.genKey(map.id, map.mode); + map.fetchedAt = now; + map.beatmapset = set; + map.failtimes = { exit: [], fail: [] }; + this.maps.set(key, map); + } + } + + discardExpiredCache(expiredMs: number = this.cacheExpiredMs) { + const now = Date.now(); + for (const [key, cache] of this.maps.entries()) { + if (now > cache.fetchedAt + expiredMs) { + this.maps.delete(key); + } } + } - genKey(mapid: number, mode: string | PlayMode) { - if (typeof mode == "string") { - mode = PlayMode.from(mode); - } - return `${mode.id}.${mapid}`; + genKey(mapid: number, mode: string | PlayMode) { + if (typeof mode == 'string') { + mode = PlayMode.from(mode); } + return `${mode.id}.${mapid}`; + } } export enum FetchBeatmapErrorReason { @@ -106,21 +106,21 @@ export enum FetchBeatmapErrorReason { } export function isFetchBeatmapError(err: any): err is FetchBeatmapError { - return "isFetchBeatmapError" in err; + return 'isFetchBeatmapError' in err; } export class FetchBeatmapError extends Error { - isFetchBeatmapError: true = true; - reason: FetchBeatmapErrorReason; - constructor(reason: FetchBeatmapErrorReason, message?: string) { - super(message ?? FetchBeatmapErrorReason[reason]); - this.reason = reason; - this.name = "FetchBeatmapError"; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, FetchBeatmapError); - } + isFetchBeatmapError: true = true; + reason: FetchBeatmapErrorReason; + constructor(reason: FetchBeatmapErrorReason, message?: string) { + super(message ?? FetchBeatmapErrorReason[reason]); + this.reason = reason; + this.name = 'FetchBeatmapError'; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, FetchBeatmapError); } + } } export interface IBeatmapFetcher { @@ -129,11 +129,11 @@ export interface IBeatmapFetcher { export class WebsiteBeatmapFecher implements IBeatmapFetcher { - getBeatmapsets(id: number): Promise { - return this.fetchBeatmapFromWebsite(id); - } + getBeatmapsets(id: number): Promise { + return this.fetchBeatmapFromWebsite(id); + } - /** + /** * * @param id * @param mode @@ -141,51 +141,51 @@ export class WebsiteBeatmapFecher implements IBeatmapFetcher { * @returns * @throws FetchBeatmapError */ - async getBeatmap(id: number, mode: PlayMode = PlayMode.Osu, allowConvert: boolean = false): Promise { - const set = await this.fetchBeatmapFromWebsite(id); - let map = set.beatmaps?.find(v => v.id == id && v.mode_int.toString() == mode.value); - if (map === undefined && allowConvert) { - map = set.converts?.find(v => v.id == id && v.mode_int.toString() == mode.value); - } - - if (!map) { - throw new FetchBeatmapError(FetchBeatmapErrorReason.PlayModeMismatched); - } - - map.beatmapset = set; - set.beatmaps = undefined; - return map; + async getBeatmap(id: number, mode: PlayMode = PlayMode.Osu, allowConvert: boolean = false): Promise { + const set = await this.fetchBeatmapFromWebsite(id); + let map = set.beatmaps?.find(v => v.id == id && v.mode_int.toString() == mode.value); + if (map === undefined && allowConvert) { + map = set.converts?.find(v => v.id == id && v.mode_int.toString() == mode.value); } - getBeatmapset(mapId: number): Promise { - return this.fetchBeatmapFromWebsite(mapId); + if (!map) { + throw new FetchBeatmapError(FetchBeatmapErrorReason.PlayModeMismatched); } - webpreg = new RegExp('', "ms"); - - async fetchBeatmapFromWebsite(id: number): Promise { - try { - const target = "https://osu.ppy.sh/b/" + id; - const res = await axios.get(target); - const match = this.webpreg.exec(res.data); - if (match) { - const json = JSON.parse(match[1]); - return json as Beatmapset; - } - throw new FetchBeatmapError(FetchBeatmapErrorReason.FormatError); - } catch (e: any) { - if (isFetchBeatmapError(e)) { - throw e; - } - if (axios.isAxiosError(e)) { - if (e.response?.status == 404) { - throw new FetchBeatmapError(FetchBeatmapErrorReason.NotFound); - } - throw new FetchBeatmapError(FetchBeatmapErrorReason.Unknown, e.message); - } - throw new FetchBeatmapError(FetchBeatmapErrorReason.FormatError, e.message); + map.beatmapset = set; + set.beatmaps = undefined; + return map; + } + + getBeatmapset(mapId: number): Promise { + return this.fetchBeatmapFromWebsite(mapId); + } + + webpreg = new RegExp('', 'ms'); + + async fetchBeatmapFromWebsite(id: number): Promise { + try { + const target = 'https://osu.ppy.sh/b/' + id; + const res = await axios.get(target); + const match = this.webpreg.exec(res.data); + if (match) { + const json = JSON.parse(match[1]); + return json as Beatmapset; + } + throw new FetchBeatmapError(FetchBeatmapErrorReason.FormatError); + } catch (e: any) { + if (isFetchBeatmapError(e)) { + throw e; + } + if (axios.isAxiosError(e)) { + if (e.response?.status == 404) { + throw new FetchBeatmapError(FetchBeatmapErrorReason.NotFound); } + throw new FetchBeatmapError(FetchBeatmapErrorReason.Unknown, e.message); + } + throw new FetchBeatmapError(FetchBeatmapErrorReason.FormatError, e.message); } + } } export const BeatmapRepository = new BeatmapRepositoryClass(); diff --git a/src/webapi/Beatmapsets.ts b/src/webapi/Beatmapsets.ts index c2fdf52a..1b7d2775 100644 --- a/src/webapi/Beatmapsets.ts +++ b/src/webapi/Beatmapsets.ts @@ -1,114 +1,114 @@ export type Beatmapset = { - "artist": string, - "artist_unicode": string, - "covers": Covers, - "creator": string, - "favourite_count": number, - "id": number, - "nsfw": boolean, - "play_count": number, - "preview_url": string, - "source": string, - "status": string, - "title": string, - "title_unicode": string, - "track_id": number, - "user_id": number, - "video": boolean, - "availability": { - "download_disabled": boolean, - "more_information": any + 'artist': string, + 'artist_unicode': string, + 'covers': Covers, + 'creator': string, + 'favourite_count': number, + 'id': number, + 'nsfw': boolean, + 'play_count': number, + 'preview_url': string, + 'source': string, + 'status': string, + 'title': string, + 'title_unicode': string, + 'track_id': number, + 'user_id': number, + 'video': boolean, + 'availability': { + 'download_disabled': boolean, + 'more_information': any }, - "bpm": number, - "can_be_hyped": boolean, - "discussion_enabled": boolean, - "discussion_locked": boolean, - "hype": { - "current": number, - "required": number + 'bpm': number, + 'can_be_hyped': boolean, + 'discussion_enabled': boolean, + 'discussion_locked': boolean, + 'hype': { + 'current': number, + 'required': number } | null, - "is_scoreable": boolean, - "last_updated": string, - "legacy_thread_url": string, - "nominations_summary": { - "current": number, - "required": number + 'is_scoreable': boolean, + 'last_updated': string, + 'legacy_thread_url': string, + 'nominations_summary': { + 'current': number, + 'required': number } | null, - "ranked": number, - "ranked_date": string, - "storyboard": boolean, - "submitted_date": string, - "tags": string, - "has_favourited"?: boolean, - "beatmaps"?: Beatmap[], - "converts"?: Beatmap[], - "current_user_attributes"?: { - "can_delete": false, - "can_edit_metadata": false, - "can_hype": true, - "can_hype_reason": null, - "can_love": false, - "is_watching": false, - "new_hype_time": null, - "remaining_hype": 10 + 'ranked': number, + 'ranked_date': string, + 'storyboard': boolean, + 'submitted_date': string, + 'tags': string, + 'has_favourited'?: boolean, + 'beatmaps'?: Beatmap[], + 'converts'?: Beatmap[], + 'current_user_attributes'?: { + 'can_delete': false, + 'can_edit_metadata': false, + 'can_hype': true, + 'can_hype_reason': null, + 'can_love': false, + 'is_watching': false, + 'new_hype_time': null, + 'remaining_hype': 10 }, - "description"?: { - "description": string + 'description'?: { + 'description': string }, - "genre"?: { - "id": number, - "name": string + 'genre'?: { + 'id': number, + 'name': string }, - "language"?: { - "id": number, - "name": string + 'language'?: { + 'id': number, + 'name': string }, - "ratings": number[], - "recent_favourites"?: any[], + 'ratings': number[], + 'recent_favourites'?: any[], } export type Covers = { - "cover": string, - "cover@2x": string, - "card": string, - "card@2x": string, - "list": string, - "list@2x": string, - "slimcover": string, - "slimcover@2x": string + 'cover': string, + 'cover@2x': string, + 'card': string, + 'card@2x': string, + 'list': string, + 'list@2x': string, + 'slimcover': string, + 'slimcover@2x': string } export type Beatmap = { - "difficulty_rating": number, - "id": number, - "mode": string, - "version": string, - "accuracy": number, - "ar": number, - "beatmapset_id": number, - "bpm": number, - "convert": boolean, - "count_circles": number, - "count_sliders": number, - "count_spinners": number, - "cs": number, - "deleted_at": any, - "drain": number, - "hit_length": number, - "is_scoreable": boolean, - "last_updated": string, - "mode_int": number, - "passcount": number, - "playcount": number, - "ranked": number, - "status": string, - "total_length": number, - "url": string, - "failtimes": { - "fail": number[], - "exit": number[] + 'difficulty_rating': number, + 'id': number, + 'mode': string, + 'version': string, + 'accuracy': number, + 'ar': number, + 'beatmapset_id': number, + 'bpm': number, + 'convert': boolean, + 'count_circles': number, + 'count_sliders': number, + 'count_spinners': number, + 'cs': number, + 'deleted_at': any, + 'drain': number, + 'hit_length': number, + 'is_scoreable': boolean, + 'last_updated': string, + 'mode_int': number, + 'passcount': number, + 'playcount': number, + 'ranked': number, + 'status': string, + 'total_length': number, + 'url': string, + 'failtimes': { + 'fail': number[], + 'exit': number[] }, - "max_combo": number, - "beatmapset"?: Beatmapset + 'max_combo': number, + 'beatmapset'?: Beatmapset } \ No newline at end of file diff --git a/src/webapi/HistoryFetcher.ts b/src/webapi/HistoryFetcher.ts index 5fc8969f..c5337406 100644 --- a/src/webapi/HistoryFetcher.ts +++ b/src/webapi/HistoryFetcher.ts @@ -18,7 +18,7 @@ export class HistoryFecher implements IHistoryFetcher { const url = `https://osu.ppy.sh/community/matches/${matchId}`; const params: any = { 'limit': limit, - } + }; if (before) { params.before = before; } diff --git a/src/webapi/HistoryRepository.ts b/src/webapi/HistoryRepository.ts index 476c0f4a..b2a60f04 100644 --- a/src/webapi/HistoryRepository.ts +++ b/src/webapi/HistoryRepository.ts @@ -39,7 +39,7 @@ interface FetchResult { export class HistoryRepository { lobbyId: number; matchInfo: Match | null = null; - lobbyName: string = ""; + lobbyName: string = ''; latestEventId: number = 0; oldestEventId: number = Number.MAX_VALUE; currentGameEventId: number = 0; @@ -66,8 +66,8 @@ export class HistoryRepository { constructor(lobbyId: number, fetcher: IHistoryFetcher | null = null) { this.lobbyId = lobbyId; - this.logger = log4js.getLogger("his_repo"); - this.logger.addContext("channel", lobbyId); + this.logger = log4js.getLogger('his_repo'); + this.logger.addContext('channel', lobbyId); this.users = {}; this.events = []; this.fetcher = fetcher ?? new HistoryFetcher(); @@ -75,7 +75,7 @@ export class HistoryRepository { setLobbyId(lobbyId: string) { this.lobbyId = parseInt(lobbyId); - this.logger.addContext("channel", lobbyId); + this.logger.addContext('channel', lobbyId); } /** @@ -90,9 +90,9 @@ export class HistoryRepository { } } catch (e: any) { if (e instanceof Error) { - this.logger.error("@updateToLatest : " + e.message); + this.logger.error('@updateToLatest : ' + e.message); } else { - this.logger.error("@updateToLatest : " + e); + this.logger.error('@updateToLatest : ' + e); } this.hasError = true; @@ -116,7 +116,7 @@ export class HistoryRepository { await this.fetchTask; const p = this.fetch_(isRewind); if (HistoryRepository.COOL_TIME) { - this.fetchTask = p.catch((e) => { return { isRewind, count: 0, filled: false } }).then(r => new Promise((resolve) => { + this.fetchTask = p.catch((e) => { return { isRewind, count: 0, filled: false }; }).then(r => new Promise((resolve) => { setTimeout(() => resolve(r), HistoryRepository.COOL_TIME); })); } else { @@ -128,7 +128,7 @@ export class HistoryRepository { private async fetch_(isRewind: boolean = false): Promise { if (this.lobbyId == 0) return { count: 0, filled: true, isRewind }; - let limit = 100; + const limit = 100; let after = null; let before = null; @@ -189,9 +189,9 @@ export class HistoryRepository { } }); - for (let ev of newEvents) { + for (const ev of newEvents) { switch (ev.detail.type) { - case "other": + case 'other': this.checkLobbyName(ev); if (ev.game) { if (ev.game.end_time) { @@ -201,7 +201,7 @@ export class HistoryRepository { } } break; - case "player-kicked": + case 'player-kicked': this.raiseKickedEvent(ev); break; } @@ -222,7 +222,7 @@ export class HistoryRepository { isRewind, count: data.events.length, filled: isRewind - ? this.events[0].detail.type == "match-created" + ? this.events[0].detail.type == 'match-created' : this.latestEventId == data.latest_event_id }; } @@ -282,7 +282,7 @@ export class HistoryRepository { let loopCount = 0; let hostAge = -1; // 現在のホスト let gameCount = 0; // 現在までの試合数 - let unresolvedPlayers = new Set(); // 試合に参加したがまだ順番が確定していないプレイヤー + const unresolvedPlayers = new Set(); // 試合に参加したがまだ順番が確定していないプレイヤー while (true) { i--; @@ -290,19 +290,19 @@ export class HistoryRepository { if (i < 0) { // 巻き戻し try { - let r = await this.fetch(true); + const r = await this.fetch(true); if (r.count == 0) break; // 結果が空なら終わり i = r.count - 1; } catch (e) { - this.logger.error("@calcCurrentOrderAsID - fetch : " + e); + this.logger.error('@calcCurrentOrderAsID - fetch : ' + e); throw e; } } - let ev = this.events[i]; + const ev = this.events[i]; if (ev.user_id != null) { switch (ev.detail.type) { - case "host-changed": + case 'host-changed': // clearhost実行時に id = 0 if (ev.user_id != 0 && !(ev.user_id in map)) { map[ev.user_id] = false; @@ -313,9 +313,9 @@ export class HistoryRepository { hostAge = Date.parse(ev.timestamp); unresolvedPlayers.delete(ev.user_id); break; - case "match-created": + case 'match-created': break; - case "player-joined": + case 'player-joined': if (!(ev.user_id in map)) { const la = Date.parse(ev.timestamp); map[ev.user_id] = false; @@ -324,23 +324,23 @@ export class HistoryRepository { unresolvedPlayers.delete(ev.user_id); } break; - case "player-left": - case "player-kicked": + case 'player-left': + case 'player-kicked': if (!(ev.user_id in map)) { map[ev.user_id] = true; unresolvedPlayers.delete(ev.user_id); } break; default: - this.logger.warn("unknown event type! " + JSON.stringify(ev)); + this.logger.warn('unknown event type! ' + JSON.stringify(ev)); break; } - } else if (ev.detail.type == "other" && ev.game) { + } else if (ev.detail.type == 'other' && ev.game) { hostAge = Date.parse(ev.game.start_time); //this.logger.trace(`set host age ${hostAge} bc game start`); if (ev.game.scores && gameCount < HistoryRepository.ESC_CRITERIA) { gameCount++; - for (let s of ev.game.scores) { + for (const s of ev.game.scores) { if (!(s.user_id in map)) { unresolvedPlayers.add(s.user_id); } @@ -353,10 +353,10 @@ export class HistoryRepository { // 直近{ESC_CRITERIA}回の試合参加メンバーすべての存在が確認された // ロビー作成イベントまで到達 // ループリミットを超過 - if (16 <= result.length && unresolvedPlayers.size === 0) { + if (result.length >= 16 && unresolvedPlayers.size === 0) { this.logger.info(`found ${result.length} players in ${loopCount} events. full lobby`); - if (16 < result.length) { - this.logger.warn(`lots of players!!`); + if (result.length > 16) { + this.logger.warn('lots of players!!'); } break; } @@ -364,16 +364,16 @@ export class HistoryRepository { this.logger.info(`found ${result.length} players in ${loopCount} events. estimated`); break; } - if (ev.detail.type == "match-created") { + if (ev.detail.type == 'match-created') { this.logger.info(`found ${result.length} players in ${loopCount} events. reached begin of events`); break; } if (HistoryRepository.LOOP_LIMIT < loopCount) { - this.logger.warn("loop limit exceeded! " + HistoryRepository.LOOP_LIMIT); + this.logger.warn('loop limit exceeded! ' + HistoryRepository.LOOP_LIMIT); break; } if (this.lobbyClosed) { - this.logger.warn("lobby was closed in action"); + this.logger.warn('lobby was closed in action'); result.length = 0; break; } diff --git a/src/webapi/HistoryTypes.ts b/src/webapi/HistoryTypes.ts index 4a790930..b409d663 100644 --- a/src/webapi/HistoryTypes.ts +++ b/src/webapi/HistoryTypes.ts @@ -1,91 +1,91 @@ export type History = { - "match": Match, - "events": Event[], - "users": User[], - "latest_event_id": number, - "current_game_id": number | null + 'match': Match, + 'events': Event[], + 'users': User[], + 'latest_event_id': number, + 'current_game_id': number | null } export type Match = { - "id": number, - "start_time": string, - "end_time": string | null, - "name": string + 'id': number, + 'start_time': string, + 'end_time': string | null, + 'name': string } export type Event = { - "id": number, - "detail": { - "type": EventType, - "text"?: string + 'id': number, + 'detail': { + 'type': EventType, + 'text'?: string }, - "game"?: Game, - "timestamp": string, - "user_id": number | null + 'game'?: Game, + 'timestamp': string, + 'user_id': number | null } -export type EventType = "match-created" | "match-disbanded" | - "host-changed" | "player-joined" | "player-left" | "player-kicked" | - "other"; +export type EventType = 'match-created' | 'match-disbanded' | + 'host-changed' | 'player-joined' | 'player-left' | 'player-kicked' | + 'other'; export type User = { - "avatar_url": string | null, - "country_code": string, - "default_group": string, - "id": number, - "is_active": boolean, - "is_bot": boolean, - "is_online": boolean, - "is_supporter": boolean, - "last_visit": string, - "pm_friends_only": boolean, - "profile_colour": string | null, - "username": string, - "country": { - "code": string, - "name": string + 'avatar_url': string | null, + 'country_code': string, + 'default_group': string, + 'id': number, + 'is_active': boolean, + 'is_bot': boolean, + 'is_online': boolean, + 'is_supporter': boolean, + 'last_visit': string, + 'pm_friends_only': boolean, + 'profile_colour': string | null, + 'username': string, + 'country': { + 'code': string, + 'name': string } } export type Game = { - "id": number - "start_time": string, - "end_time": string | null, - "mode": "osu" | "taiko" | "fruits" | "mania" | string, + 'id': number + 'start_time': string, + 'end_time': string | null, + 'mode': 'osu' | 'taiko' | 'fruits' | 'mania' | string, /** * 0 = osu, 1 = taiko, 2 = fruits, 3 = mania */ - "mode_int": number, - "scoring_type": "score" | "accuracy" | "combo" | "scorev2" | string, - "team_type": "head-to-head" | "tag-coop" | "team-vs" | "tag-team-vs" | string, - "mods": string[], - "beatmap": any, - "scores": Score[] + 'mode_int': number, + 'scoring_type': 'score' | 'accuracy' | 'combo' | 'scorev2' | string, + 'team_type': 'head-to-head' | 'tag-coop' | 'team-vs' | 'tag-team-vs' | string, + 'mods': string[], + 'beatmap': any, + 'scores': Score[] } export type Score = { - "id": null, - "user_id": number, - "accuracy": number, - "mods": string[], - "score": number, - "max_combo": number, - "perfect": number, - "statistics": { - "count_50": number, - "count_100": number, - "count_300": number, - "count_geki": number, - "count_katu": number, - "count_miss": number + 'id': null, + 'user_id': number, + 'accuracy': number, + 'mods': string[], + 'score': number, + 'max_combo': number, + 'perfect': number, + 'statistics': { + 'count_50': number, + 'count_100': number, + 'count_300': number, + 'count_geki': number, + 'count_katu': number, + 'count_miss': number }, - "rank": null, - "created_at": null, - "best_id": null, - "pp": number | null, - "match": { - "slot": number, - "team": "none" | "red" | "blue", - "pass": number + 'rank': null, + 'created_at': null, + 'best_id': null, + 'pp': number | null, + 'match': { + 'slot': number, + 'team': 'none' | 'red' | 'blue', + 'pass': number } } \ No newline at end of file diff --git a/src/webapi/ProfileRepository.ts b/src/webapi/ProfileRepository.ts index e24b4613..76f7c735 100644 --- a/src/webapi/ProfileRepository.ts +++ b/src/webapi/ProfileRepository.ts @@ -4,69 +4,69 @@ import { UserProfile } from './UserProfile'; export type ProfileCache = UserProfile & { fetchedAt: number }; class ProfileRepositoryClass { - profiles: Map; - cacheExpiredMs: number; - fetcher: IProfileFetcher; - - constructor() { - this.profiles = new Map(); - //Expired in 10 minutes - this.cacheExpiredMs = 10 * 1000; - this.fetcher = new WebsiteProfileFetcher(); - } - - /** + profiles: Map; + cacheExpiredMs: number; + fetcher: IProfileFetcher; + + constructor() { + this.profiles = new Map(); + //Expired in 10 minutes + this.cacheExpiredMs = 10 * 1000; + this.fetcher = new WebsiteProfileFetcher(); + } + + /** * * @param userID * @param mode * @returns * @throws FetchProfileError */ - async getProfile(userID: number, mode: string): Promise { + async getProfile(userID: number, mode: string): Promise { - let cache = this.tryGetCache(userID, mode); - if (cache) return cache; + let cache = this.tryGetCache(userID, mode); + if (cache) return cache; - const profile = await this.fetcher.getPlayer(userID, mode); - this.cacheProfile(profile); + const profile = await this.fetcher.getPlayer(userID, mode); + this.cacheProfile(profile); - cache = this.tryGetCache(userID, mode); - if (cache) return cache; - throw new FetchProfileError(FetchProfileErrorReason.NotFound); - } + cache = this.tryGetCache(userID, mode); + if (cache) return cache; + throw new FetchProfileError(FetchProfileErrorReason.NotFound); + } - tryGetCache(userID: number, mode: string): ProfileCache | undefined { - const profileKey = this.genKey(userID, mode); - const cache = this.profiles.get(profileKey); - - if (cache) { - if (Date.now() < cache.fetchedAt + this.cacheExpiredMs) { - return cache; - } else { - this.profiles.delete(profileKey); - } - } - } - cacheProfile(profile: UserProfile) { - const now = Date.now(); - const cacheProfile = profile as ProfileCache; - const key = this.genKey(profile.id, profile.playmode); - cacheProfile.fetchedAt = now; - this.profiles.set(key, cacheProfile); + tryGetCache(userID: number, mode: string): ProfileCache | undefined { + const profileKey = this.genKey(userID, mode); + const cache = this.profiles.get(profileKey); + + if (cache) { + if (Date.now() < cache.fetchedAt + this.cacheExpiredMs) { + return cache; + } else { + this.profiles.delete(profileKey); + } } + } + cacheProfile(profile: UserProfile) { + const now = Date.now(); + const cacheProfile = profile as ProfileCache; + const key = this.genKey(profile.id, profile.playmode); + cacheProfile.fetchedAt = now; + this.profiles.set(key, cacheProfile); + } - discardExpiredCache(expiredMs: number = this.cacheExpiredMs) { - const now = Date.now(); - for (const [key, cache] of this.profiles.entries()) { - if (now > cache.fetchedAt + expiredMs) { - this.profiles.delete(key); - } - } + discardExpiredCache(expiredMs: number = this.cacheExpiredMs) { + const now = Date.now(); + for (const [key, cache] of this.profiles.entries()) { + if (now > cache.fetchedAt + expiredMs) { + this.profiles.delete(key); + } } + } - genKey(userID: number, mode: string) { - return `${mode}.${userID}`; - } + genKey(userID: number, mode: string) { + return `${mode}.${userID}`; + } } export enum FetchProfileErrorReason { @@ -76,22 +76,22 @@ export enum FetchProfileErrorReason { } export function isFetchProfileError(err: any): err is FetchProfileError { - return "isFetchProfileError" in err; + return 'isFetchProfileError' in err; } export class FetchProfileError extends Error { - isFetchProfileError: true = true; - reason: FetchProfileErrorReason; - constructor(reason: FetchProfileErrorReason, message?: string) { - super(message ?? FetchProfileErrorReason[reason]); - this.reason = reason; - this.name = "FetchProfileError"; + isFetchProfileError: true = true; + reason: FetchProfileErrorReason; + constructor(reason: FetchProfileErrorReason, message?: string) { + super(message ?? FetchProfileErrorReason[reason]); + this.reason = reason; + this.name = 'FetchProfileError'; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, FetchProfileError); - } + if (Error.captureStackTrace) { + Error.captureStackTrace(this, FetchProfileError); } + } } export interface IProfileFetcher { @@ -100,58 +100,58 @@ export interface IProfileFetcher { export class WebsiteProfileFetcher implements IProfileFetcher { - /** + /** * * @param userID * @param mode * @returns * @throws FetchProfileError */ - async getPlayer(userID: number, mode: string): Promise { - const pro = await this.fetchProfileFromWebsite(userID, mode); + async getPlayer(userID: number, mode: string): Promise { + const pro = await this.fetchProfileFromWebsite(userID, mode); - if (!pro) { - throw new FetchProfileError(FetchProfileErrorReason.NotFound); - } - - return pro; + if (!pro) { + throw new FetchProfileError(FetchProfileErrorReason.NotFound); } - webpreg = new RegExp('', "ms"); - modepreg = new RegExp( - '', - "ms" - ); - - async fetchProfileFromWebsite(userID: number, mode: string): Promise { - try { - const target = "https://osu.ppy.sh/users/" + userID + "/" + mode; - const res = await axios.get(target); - const match = this.webpreg.exec(res.data); - if (match) { - const json = JSON.parse(match[1]); - const mode = this.modepreg.exec(res.data); - let rxes = json as UserProfile; - if(mode){ - var regex = /"/ig; - rxes.playmode = mode[1].trim().replace(regex,''); - } - return rxes; - } - throw new FetchProfileError(FetchProfileErrorReason.FormatError); - } catch (e: any) { - if (isFetchProfileError(e)) { - throw e; - } - if (axios.isAxiosError(e)) { - if (e.response?.status == 404) { - throw new FetchProfileError(FetchProfileErrorReason.NotFound); - } - throw new FetchProfileError(FetchProfileErrorReason.Unknown, e.message); - } - throw new FetchProfileError(FetchProfileErrorReason.FormatError, e.message); + return pro; + } + + webpreg = new RegExp('', 'ms'); + modepreg = new RegExp( + '', + 'ms' + ); + + async fetchProfileFromWebsite(userID: number, mode: string): Promise { + try { + const target = 'https://osu.ppy.sh/users/' + userID + '/' + mode; + const res = await axios.get(target); + const match = this.webpreg.exec(res.data); + if (match) { + const json = JSON.parse(match[1]); + const mode = this.modepreg.exec(res.data); + const rxes = json as UserProfile; + if(mode){ + const regex = /"/ig; + rxes.playmode = mode[1].trim().replace(regex,''); + } + return rxes; + } + throw new FetchProfileError(FetchProfileErrorReason.FormatError); + } catch (e: any) { + if (isFetchProfileError(e)) { + throw e; + } + if (axios.isAxiosError(e)) { + if (e.response?.status == 404) { + throw new FetchProfileError(FetchProfileErrorReason.NotFound); } + throw new FetchProfileError(FetchProfileErrorReason.Unknown, e.message); + } + throw new FetchProfileError(FetchProfileErrorReason.FormatError, e.message); } + } } export const ProfileRepository = new ProfileRepositoryClass(); diff --git a/src/webapi/WebApiClient.ts b/src/webapi/WebApiClient.ts index 79a4a246..60c5f3f4 100644 --- a/src/webapi/WebApiClient.ts +++ b/src/webapi/WebApiClient.ts @@ -39,10 +39,10 @@ class WebApiClientClass implements IBeatmapFetcher { token: ApiToken | undefined; constructor(option: Partial = {}) { - const WebApiDefaultOption = config.get("WebApi"); + const WebApiDefaultOption = config.get('WebApi'); this.option = { ...WebApiDefaultOption, ...option } as WebApiClientOption; - this.logger = log4js.getLogger("webapi"); - this.available = this.option.client_id != 0 && this.option.client_secret != "***"; + this.logger = log4js.getLogger('webapi'); + this.available = this.option.client_id != 0 && this.option.client_secret != '***'; } async updateToken(): Promise { @@ -66,25 +66,25 @@ class WebApiClientClass implements IBeatmapFetcher { } private getTokenPath(asGuest: boolean) { - return path.join(this.option.token_store_dir, asGuest ? "guest_token.json" : "token.json"); + return path.join(this.option.token_store_dir, asGuest ? 'guest_token.json' : 'token.json'); } private async storeToken(token: ApiToken): Promise { - if (this.option.token_store_dir == "") return false; + if (this.option.token_store_dir == '') return false; try { const p = this.getTokenPath(token.isGuest); await fs.mkdir(path.dirname(p), { recursive: true }); - await fs.writeFile(p, JSON.stringify(token), { encoding: "utf8", flag: "w" }); - this.logger.info("stored token to : " + p); + await fs.writeFile(p, JSON.stringify(token), { encoding: 'utf8', flag: 'w' }); + this.logger.info('stored token to : ' + p); return true; } catch (e) { - this.logger.error("storeToken error : " + e); + this.logger.error('storeToken error : ' + e); return false; } } private async loadStoredToken(asGuest: boolean): Promise { - if (this.option.token_store_dir == "") return; + if (this.option.token_store_dir == '') return; const p = this.getTokenPath(asGuest); try { await fs.access(p); @@ -93,16 +93,16 @@ class WebApiClientClass implements IBeatmapFetcher { } try { - const j = await fs.readFile(p, "utf8"); + const j = await fs.readFile(p, 'utf8'); const token = JSON.parse(j) as ApiToken; if (!isExpired(token)) { - this.logger.info("loaded stored token from : " + p); + this.logger.info('loaded stored token from : ' + p); return token; } this.deleteStoredToken(asGuest); - this.logger.info("deleted expired stored token"); + this.logger.info('deleted expired stored token'); } catch (e) { - this.logger.error("loadStoredToken error : " + e); + this.logger.error('loadStoredToken error : ' + e); } } @@ -116,23 +116,23 @@ class WebApiClientClass implements IBeatmapFetcher { try { fs.unlink(p); } catch (e) { - this.logger.error("load token error : " + e); + this.logger.error('load token error : ' + e); } } private async getAuthorizedToken(): Promise { try { const code = await this.getAuthorizeCode(); - const response = await axios.post("https://osu.ppy.sh/oauth/token", { - "client_id": "" + this.option.client_id, - "client_secret": this.option.client_secret, - "code": code, - "grant_type": "authorization_code", - "redirect_uri": this.option.callback + const response = await axios.post('https://osu.ppy.sh/oauth/token', { + 'client_id': '' + this.option.client_id, + 'client_secret': this.option.client_secret, + 'code': code, + 'grant_type': 'authorization_code', + 'redirect_uri': this.option.callback }); response.data.isGuest = false; response.data.expires_in += Date.now() / 1000; - this.logger.info("get Authorized token"); + this.logger.info('get Authorized token'); return response.data; } catch (e) { this.logger.error(`getAuthorizedToken error : ${e}`); @@ -143,58 +143,58 @@ class WebApiClientClass implements IBeatmapFetcher { return new Promise((resoleve, reject) => { const server = http.createServer(); let code: string | null = null; - server.once("request", (req: http.IncomingMessage, res: http.ServerResponse) => { + server.once('request', (req: http.IncomingMessage, res: http.ServerResponse) => { res.setHeader('Content-Type', 'text/html'); res.writeHead(200, { 'Content-Type': 'text/plain' }); if (!req.url) { - res.end("missing req.url"); + res.end('missing req.url'); return; } const url = new URL(req.url, `http://${req.headers.host}`); - code = url.searchParams.get("code"); + code = url.searchParams.get('code'); if (code == null) { - res.end("missing code"); + res.end('missing code'); return; } - res.end("ok : " + code); - this.logger.trace("got code! " + code); + res.end('ok : ' + code); + this.logger.trace('got code! ' + code); server.close(() => { - this.logger.trace("closed callback"); + this.logger.trace('closed callback'); }); if (res.connection) { res.connection.end(); res.connection.destroy(); } else { - reject("no connection"); + reject('no connection'); } }); - server.once("close", () => { - this.logger.trace("closed event"); + server.once('close', () => { + this.logger.trace('closed event'); if (code == null) { - reject("no code"); + reject('no code'); } else { - this.logger.info("get Authorized code"); + this.logger.info('get Authorized code'); resoleve(code); } }); server.listen(this.option.callback_port); - const nurl = new URL("https://osu.ppy.sh/oauth/authorize"); - nurl.searchParams.set("client_id", this.option.client_id.toString()); - nurl.searchParams.set("redirect_uri", this.option.callback); - nurl.searchParams.set("response_type", "code"); - nurl.searchParams.set("scope", "public"); + const nurl = new URL('https://osu.ppy.sh/oauth/authorize'); + nurl.searchParams.set('client_id', this.option.client_id.toString()); + nurl.searchParams.set('redirect_uri', this.option.callback); + nurl.searchParams.set('response_type', 'code'); + nurl.searchParams.set('scope', 'public'); open(nurl.toString()); }); } private async getGuestToken(): Promise { try { - const response = await axios.post("https://osu.ppy.sh/oauth/token", { - "grant_type": "client_credentials", - "client_id": "" + this.option.client_id, - "client_secret": this.option.client_secret, - "scope": "public" + const response = await axios.post('https://osu.ppy.sh/oauth/token', { + 'grant_type': 'client_credentials', + 'client_id': '' + this.option.client_id, + 'client_secret': this.option.client_secret, + 'scope': 'public' }); response.data.isGuest = true; response.data.expires_in += Date.now() / 1000; @@ -207,13 +207,13 @@ class WebApiClientClass implements IBeatmapFetcher { async accessApi(url: string, config: any = {}, tryCount: number = 2): Promise { while (tryCount-- > 0) { if (!await this.updateToken() || !this.token) { - throw new Error(`accessApi error : couldn't get valid token`); + throw new Error('accessApi error : couldn\'t get valid token'); } config.headers = { - "Authorization": `Bearer ${this.token.access_token}`, - "Accept": "application/json", - "Content-Type": "application/json", + 'Authorization': `Bearer ${this.token.access_token}`, + 'Accept': 'application/json', + 'Content-Type': 'application/json', }; try { @@ -225,7 +225,7 @@ class WebApiClientClass implements IBeatmapFetcher { } catch (e: any) { switch (e.response?.status) { case 401: - this.logger.info(`api access failed, delete current token.`); + this.logger.info('api access failed, delete current token.'); this.deleteStoredToken(this.option.asGuest); this.token = undefined; break; @@ -234,43 +234,43 @@ class WebApiClientClass implements IBeatmapFetcher { } } } - throw new Error("couldn't access api"); + throw new Error('couldn\'t access api'); } async getChatUpdates() { - const data = await this.accessApi("https://osu.ppy.sh/api/v2/chat/updates", { - method: "GET", + const data = await this.accessApi('https://osu.ppy.sh/api/v2/chat/updates', { + method: 'GET', params: { - "since": "0" + 'since': '0' } }); return data; } async getChannels() { - const data = await this.accessApi("https://osu.ppy.sh/api/v2/chat/channels", { - method: "GET" + const data = await this.accessApi('https://osu.ppy.sh/api/v2/chat/channels', { + method: 'GET' }); return data; } async getMe() { - const data = await this.accessApi("https://osu.ppy.sh/api/v2/me/osu", { - method: "GET" + const data = await this.accessApi('https://osu.ppy.sh/api/v2/me/osu', { + method: 'GET' }); return data; } async getNotifications() { - const data = await this.accessApi("https://osu.ppy.sh/api/v2/notifications", { - method: "GET" + const data = await this.accessApi('https://osu.ppy.sh/api/v2/notifications', { + method: 'GET' }); return data; } async getUserRecentActivity(id: number) { const data = await this.accessApi(`https://osu.ppy.sh/api/v2/users/${id}/recent_activity`, { - method: "GET" + method: 'GET' }); return data; } @@ -278,7 +278,7 @@ class WebApiClientClass implements IBeatmapFetcher { async getUser(id: number | string): Promise { try { const data = await this.accessApi(`https://osu.ppy.sh/api/v2/users/${id}/osu`, { - method: "GET" + method: 'GET' }); data.get_time = Date.now(); return trimProfile(data); @@ -293,7 +293,7 @@ class WebApiClientClass implements IBeatmapFetcher { async getPlayer(userID: number, mode: string): Promise { try { const data = await this.accessApi(`https://osu.ppy.sh/api/v2/users/${userID}/${mode}`, { - method: "GET" + method: 'GET' }); data.get_time = Date.now(); return data; @@ -307,7 +307,7 @@ class WebApiClientClass implements IBeatmapFetcher { async lookupBeatmap(mapid: number): Promise { const data = await this.accessApi(`https://osu.ppy.sh/api/v2/beatmaps/lookup?id=${mapid}`, { - method: "GET" + method: 'GET' }); data.get_time = Date.now(); return data; @@ -315,7 +315,7 @@ class WebApiClientClass implements IBeatmapFetcher { async lookupBeatmapset(mapid: number): Promise { const data = await this.accessApi(`https://osu.ppy.sh/api/v2/beatmapsets/lookup?beatmap_id=${mapid}`, { - method: "GET" + method: 'GET' }); data.get_time = Date.now(); return data; From 304270afc9dcba864727ec38c16dbaad2220abb4 Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 00:27:52 +0900 Subject: [PATCH 02/15] fixed @typescript-eslint/no-empty-function --- src/Lobby.ts | 2 +- src/cli/OahrCli.ts | 2 +- src/parsers/MpSettingsParser.ts | 1 - src/parsers/StatParser.ts | 1 - src/plugins/LobbyPlugin.ts | 2 ++ src/tests/AutoHostSelectorTest.ts | 3 --- 6 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Lobby.ts b/src/Lobby.ts index 600320c3..aa1f1a3b 100644 --- a/src/Lobby.ts +++ b/src/Lobby.ts @@ -831,7 +831,7 @@ export class Lobby { resolve(); }); if (this.channel != undefined) { - this.ircClient.part(this.channel, 'part', () => { }); + this.ircClient.part(this.channel, 'part', () => { /* do nothing. */ }); this.status = LobbyStatus.Leaving; } else { reject(); diff --git a/src/cli/OahrCli.ts b/src/cli/OahrCli.ts index bb3d5af0..ecc354c6 100644 --- a/src/cli/OahrCli.ts +++ b/src/cli/OahrCli.ts @@ -195,7 +195,7 @@ export class OahrCli extends OahrBase { exited: { name: 'exited', prompt: 'ended', - action: async (line: string) => { }, + action: async (line: string) => { /* do nothing. */ }, completer: (line: string): readline.CompleterResult => { return [['exit'], line]; } diff --git a/src/parsers/MpSettingsParser.ts b/src/parsers/MpSettingsParser.ts index c7d8bd7a..b96819d7 100644 --- a/src/parsers/MpSettingsParser.ts +++ b/src/parsers/MpSettingsParser.ts @@ -30,7 +30,6 @@ export class MpSettingsParser { get isParsed(): boolean { return !this.isParsing && this.result != null; } - constructor() { } feedLine(line: string): boolean { let m = line.match(/Room name: (.+), History: (.+?(\d+))/); diff --git a/src/parsers/StatParser.ts b/src/parsers/StatParser.ts index a65974bb..542eee3d 100644 --- a/src/parsers/StatParser.ts +++ b/src/parsers/StatParser.ts @@ -48,7 +48,6 @@ export class StatParser { get isParsed(): boolean { return !this.isParsing && this.result != null; } - constructor() { } feedLine(message: string): boolean { const line1 = message.match(/Stats for \((.+)\)\[https:\/\/osu\.ppy\.sh\/u\/(\d+)\]( is (.+))?:/); diff --git a/src/plugins/LobbyPlugin.ts b/src/plugins/LobbyPlugin.ts index 993c90d8..e238b16f 100644 --- a/src/plugins/LobbyPlugin.ts +++ b/src/plugins/LobbyPlugin.ts @@ -39,9 +39,11 @@ export class LobbyPlugin { * すべてのプラグインが読み込まれたあとに実行される */ OnLoaded(): void { + /* do nothing. */ } OnConfig(target: string, name: string, value: string): void { + /* do nothing. */ } loadEnvSettings(option: any) { diff --git a/src/tests/AutoHostSelectorTest.ts b/src/tests/AutoHostSelectorTest.ts index eafa2f7e..a870a22b 100644 --- a/src/tests/AutoHostSelectorTest.ts +++ b/src/tests/AutoHostSelectorTest.ts @@ -1217,7 +1217,4 @@ describe('AutoHostSelectorTest', function () { b.lobby.destroy(); }); }); - describe('tests for issues', () => { - - }); }); From 82181d7b4c538dc45e9e7989b6743751839a640c Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 00:28:44 +0900 Subject: [PATCH 03/15] fixed @typescript-eslint/ban-types --- src/discord/DiscordBot.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/discord/DiscordBot.ts b/src/discord/DiscordBot.ts index 6797b3a5..f041d31a 100644 --- a/src/discord/DiscordBot.ts +++ b/src/discord/DiscordBot.ts @@ -30,8 +30,7 @@ export interface DiscordBotConfig { } type GuildCommandInteraction = CommandInteraction & { guildId: string; } -export type OahrSharedObjects = { -} +export type OahrSharedObjects = Record; export class DiscordBot { ircClient: IIrcClient; From d4863628ab9c659b3bb36c305a13878971b8c5f5 Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 00:29:35 +0900 Subject: [PATCH 04/15] fixed no-fallthrough --- src/plugins/InOutLogger.ts | 3 +++ src/tests/HistoryRepositryTest.ts | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/plugins/InOutLogger.ts b/src/plugins/InOutLogger.ts index a32c56da..a7859f25 100644 --- a/src/plugins/InOutLogger.ts +++ b/src/plugins/InOutLogger.ts @@ -16,6 +16,9 @@ export class InOutLogger extends LobbyPlugin { switch (response.type) { case BanchoResponseType.MatchFinished: this.countUp(); + this.LogInOutPlayers(); + this.saveCurrentPlayers(); + break; case BanchoResponseType.MatchStarted: case BanchoResponseType.AbortedMatch: this.LogInOutPlayers(); diff --git a/src/tests/HistoryRepositryTest.ts b/src/tests/HistoryRepositryTest.ts index a7896d85..67c84e0b 100644 --- a/src/tests/HistoryRepositryTest.ts +++ b/src/tests/HistoryRepositryTest.ts @@ -343,6 +343,7 @@ describe('History repositry Tests', () => { switch (a) { case 0: assert.fail(); + break; case 1: b++; assert.equal(e.newName, 'newname 1'); @@ -350,6 +351,7 @@ describe('History repositry Tests', () => { break; case 2: assert.fail(); + break; case 3: b++; assert.equal(e.newName, 'newname 2'); From a99442d192b2f1f76f565fb026f3a77142fdc04a Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 00:31:15 +0900 Subject: [PATCH 05/15] fixed @typescript-eslint/no-empty-interface --- src/plugins/MapRecaster.ts | 8 +------- src/plugins/MiscLoader.ts | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/plugins/MapRecaster.ts b/src/plugins/MapRecaster.ts index ac8d4de1..7f4ec8a0 100644 --- a/src/plugins/MapRecaster.ts +++ b/src/plugins/MapRecaster.ts @@ -2,21 +2,15 @@ import { Lobby } from '../Lobby'; import { Player } from '../Player'; import { LobbyPlugin } from './LobbyPlugin'; import { BanchoResponseType } from '../parsers/CommandParser'; -import { getConfig } from '../TypedConfig'; - -export interface MapRecasterOption { -} /** * ホストが古いバージョンのマップを選択した際に、コマンドでマップを貼り直して最新版にする。 * !updateコマンドなどで発動。マップ選択後に1度だけ実行できる。 */ export class MapRecaster extends LobbyPlugin { - option: MapRecasterOption; canRecast: boolean = true; - constructor(lobby: Lobby, option: Partial = {}) { + constructor(lobby: Lobby) { super(lobby, 'MapRecaster', 'recaster'); - this.option = getConfig(this.pluginName, option) as MapRecasterOption; this.registerEvents(); } diff --git a/src/plugins/MiscLoader.ts b/src/plugins/MiscLoader.ts index 99619fd5..212f59a4 100644 --- a/src/plugins/MiscLoader.ts +++ b/src/plugins/MiscLoader.ts @@ -5,28 +5,22 @@ import { BanchoResponseType } from '../parsers/CommandParser'; import { BeatmapRepository, FetchBeatmapError, FetchBeatmapErrorReason } from '../webapi/BeatmapRepository'; import { FetchProfileError, FetchProfileErrorReason } from '../webapi/ProfileRepository'; import { WebApiClient } from '../webapi/WebApiClient'; -import { getConfig } from '../TypedConfig'; - -export interface MiscLoaderOption { -} /** * Get beatmap mirror link from Beatconnect * Use !mirror to fetch the mirror link */ export class MiscLoader extends LobbyPlugin { - option: MiscLoaderOption; canResend: boolean = true; beatconnectURL: string = 'https://beatconnect.io/b/${beatmapset_id}'; kitsuURL: string = 'https://kitsu.moe/d/${beatmapset_id}'; canSeeRank: boolean = false; - constructor(lobby: Lobby, option: Partial = {}) { + constructor(lobby: Lobby) { super(lobby, 'MiscLoader', 'miscLoader'); if (WebApiClient.available) { this.canSeeRank = true; } - this.option = getConfig(this.pluginName, option) as MiscLoaderOption; this.registerEvents(); } From 20006b0f509745d5103022e4c45a78edeeb731eb Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 00:31:24 +0900 Subject: [PATCH 06/15] fixed no-irregular-whitespace --- src/tests/LobbyTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/LobbyTest.ts b/src/tests/LobbyTest.ts index 311e96b9..f0513b1a 100644 --- a/src/tests/LobbyTest.ts +++ b/src/tests/LobbyTest.ts @@ -130,7 +130,7 @@ describe('LobbyTest', function () { } }); - // プレイヤーの退出 一人 + // プレイヤーの退出 一人 it('player left test', async () => { const { ircClient, lobby, players } = await PrepareLobbyWith3Players(); From b83040e1604c765a80022581033598ef99aafd41 Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 00:41:30 +0900 Subject: [PATCH 07/15] fixed no-empty --- .eslintrc.yml | 2 +- src/Lobby.ts | 8 ++++---- src/plugins/LobbyKeeper.ts | 12 ++++++------ src/tests/LobbyTest.ts | 12 +++++++++--- src/webapi/HistoryRepository.ts | 3 +-- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index cd7f82f5..85fa1661 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -52,7 +52,7 @@ rules: no-useless-catch: - "off" no-empty: - - "off" + - "error" no-fallthrough: - "error" no-constant-condition: diff --git a/src/Lobby.ts b/src/Lobby.ts index aa1f1a3b..ddecc846 100644 --- a/src/Lobby.ts +++ b/src/Lobby.ts @@ -804,8 +804,8 @@ export class Lobby { CloseLobbyAsync(): Promise { this.logger.trace('start CloseLobby'); if (this.status != LobbyStatus.Entered) { - this.logger.error('無効な呼び出し:CloseLobbyAsync'); - throw new Error('閉じるロビーがありません。'); + this.logger.error('invalid call :CloseLobbyAsync'); + throw new Error('No lobby to close.'); } return new Promise((resolve, reject) => { this.ircClient.once('part', (channel: string, nick: string) => { @@ -823,8 +823,8 @@ export class Lobby { QuitLobbyAsync(): Promise { this.logger.trace('start QuitLobby'); if (this.status != LobbyStatus.Entered) { - this.logger.error('無効な呼び出し:QuitLobbyAsync'); - throw new Error('閉じるロビーがありません。'); + this.logger.error('invalid call :QuitLobbyAsync'); + throw new Error('No lobby to close.'); } return new Promise((resolve, reject) => { this.ircClient.once('part', (channel: string, nick: string) => { diff --git a/src/plugins/LobbyKeeper.ts b/src/plugins/LobbyKeeper.ts index ada45a0d..5093fd66 100644 --- a/src/plugins/LobbyKeeper.ts +++ b/src/plugins/LobbyKeeper.ts @@ -156,7 +156,7 @@ export class LobbyKeeper extends LobbyPlugin { const team = TeamMode.from(m1[1], true); const score = ScoreMode.from(m1[2], true); return { team, score }; - } catch { } + } catch { /* continue to parse */ } } const m2 = /^(\S+)\s+(\S+)$/.exec(param); @@ -165,20 +165,20 @@ export class LobbyKeeper extends LobbyPlugin { const team = TeamMode.from(m2[1], true); const score = ScoreMode.from(m2[2], true); return { team, score }; - } catch { } + } catch { /* continue to parse */ } } try { const team = TeamMode.from(param, true); return { team, score: this.option.mode?.score ?? ScoreMode.Score }; - } catch { } + } catch { /* continue to parse */ } try { const score = ScoreMode.from(param, true); return { team: this.option.mode?.team ?? TeamMode.HeadToHead, score }; - } catch { } - - throw new Error('Invalid Option. LobbyKeeper.mode : ' + param); + } catch { + throw new Error('Invalid Option. LobbyKeeper.mode : ' + param); + } } private checkMode(teamMode: TeamMode, scoreMode: ScoreMode) { diff --git a/src/tests/LobbyTest.ts b/src/tests/LobbyTest.ts index f0513b1a..b0021b02 100644 --- a/src/tests/LobbyTest.ts +++ b/src/tests/LobbyTest.ts @@ -62,7 +62,9 @@ describe('LobbyTest', function () { try { await lobby.MakeLobbyAsync(name); assert.fail(); - } catch (e) { } + } catch (e: any) { + assert.equal(e.message, 'title is empty'); + } }); // ロビーを二回作成 @@ -73,7 +75,9 @@ describe('LobbyTest', function () { lobby.MakeLobbyAsync('1'); lobby.MakeLobbyAsync('2'); assert.fail(); - } catch { } + } catch (e: any) { + assert.equal(e.message, 'A lobby has already been made.'); + } }); // 無効な状態でロビーを閉じる @@ -83,7 +87,9 @@ describe('LobbyTest', function () { try { await lobby.CloseLobbyAsync(); assert.fail(); - } catch { } + } catch (e: any) { + assert.equal(e.message, 'No lobby to close.'); + } }); }); diff --git a/src/webapi/HistoryRepository.ts b/src/webapi/HistoryRepository.ts index b2a60f04..315d6f3d 100644 --- a/src/webapi/HistoryRepository.ts +++ b/src/webapi/HistoryRepository.ts @@ -86,8 +86,7 @@ export class HistoryRepository { if (this.hasError) return; try { - while (!(await this.fetch(false)).filled && !this.lobbyClosed) { - } + while (!(await this.fetch(false)).filled && !this.lobbyClosed); } catch (e: any) { if (e instanceof Error) { this.logger.error('@updateToLatest : ' + e.message); From c725743a4767ac2c1aecb4bc293f67497b7b4aca Mon Sep 17 00:00:00 2001 From: gnsksz Date: Sat, 7 May 2022 01:39:01 +0900 Subject: [PATCH 08/15] fixed no-useless-escape --- .eslintrc.yml | 2 +- src/Modes.ts | 3 ++- src/cli/OahrBase.ts | 3 ++- src/discord/DiscordAppender.ts | 2 +- src/dummies/FakeBeatmapFetcher.ts | 24 ++++++++++++------------ src/parsers/CommandParser.ts | 10 +++++----- src/plugins/MapChecker.ts | 2 +- src/tests/BeatmapRepositoryTest.ts | 2 +- src/tests/LobbyTest.ts | 11 +++++++++++ src/trials/LobbynameTrial.ts | 2 +- src/web/statics/main.js | 4 ++-- src/webapi/BeatmapRepository.ts | 3 +-- src/webapi/ProfileRepository.ts | 7 ++----- 13 files changed, 42 insertions(+), 33 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 85fa1661..22531db3 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -61,7 +61,7 @@ rules: no-irregular-whitespace: - "error" no-useless-escape: - - "off" + - "error" no-case-declarations: - "off" prefer-const: diff --git a/src/Modes.ts b/src/Modes.ts index 0a4ced0e..4b8153e9 100644 --- a/src/Modes.ts +++ b/src/Modes.ts @@ -191,7 +191,8 @@ export class Mod extends Mode { } static parseMods(str: string): Mod[] { - const arrMods = str.match(/[a-zA-Z0-9\-]+/g)?.map(v => Mod.from(v)); + // アルファベット, 数字, ハイフン(co-op用)のまとまりに分解する + const arrMods = str.match(/[a-zA-Z0-9-]+/g)?.map(v => Mod.from(v)); if (arrMods) { const setMods = new Set(arrMods); return Mod.removeInvalidCombinations(setMods); diff --git a/src/cli/OahrBase.ts b/src/cli/OahrBase.ts index 033c58dd..d353bff0 100644 --- a/src/cli/OahrBase.ts +++ b/src/cli/OahrBase.ts @@ -92,7 +92,8 @@ export class OahrBase { } async makeLobbyAsync(name: string): Promise { - name = name.replace(/[^ -/:-@\[-~0-9a-zA-Z]/g, ''); + // Remove all but ascii graphic characters + name = name.replace(/[^ -~]/g, ''); if (!this.isRegistered) await this.ensureRegisteredAsync(); logger.info('Making lobby, name : ' + name); await this.lobby.MakeLobbyAsync(name); diff --git a/src/discord/DiscordAppender.ts b/src/discord/DiscordAppender.ts index bda30d91..67fe9de9 100644 --- a/src/discord/DiscordAppender.ts +++ b/src/discord/DiscordAppender.ts @@ -73,7 +73,7 @@ function createContent(ev: log4js.LoggingEvent, msg: string): string | MessageOp } case 'inout': const min = msg.match(/\+\x1b\[32m (.+?) \x1B\[0m/); - const mout = msg.match(/\-\x1b\[31m (.+?) \x1B\[0m/); + const mout = msg.match(/-\x1b\[31m (.+?) \x1B\[0m/); if (min || mout) { let msg = ''; if (min) { diff --git a/src/dummies/FakeBeatmapFetcher.ts b/src/dummies/FakeBeatmapFetcher.ts index 8abeda61..a48b447f 100644 --- a/src/dummies/FakeBeatmapFetcher.ts +++ b/src/dummies/FakeBeatmapFetcher.ts @@ -30,7 +30,7 @@ export class FakeBeatmapFetcher implements IBeatmapFetcher { passcount: 100, playcount: 100, ranked: 1, - url: 'https:\/\/osu.ppy.sh\/beatmaps\/100', + url: 'https://osu.ppy.sh/beatmaps/100', failtimes: { fail: [0, 0], exit: [0, 0] @@ -42,14 +42,14 @@ export class FakeBeatmapFetcher implements IBeatmapFetcher { 'artist': 'art', 'artist_unicode': 'art', 'covers': { - 'cover': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/cover.jpg?1000', - 'cover@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/cover@2x.jpg?1000', - 'card': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/card.jpg?1000', - 'card@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/card@2x.jpg?1000', - 'list': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/list.jpg?1000', - 'list@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/list@2x.jpg?1000', - 'slimcover': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/slimcover.jpg?1000', - 'slimcover@2x': 'https:\/\/assets.ppy.sh\/beatmaps\/1000\/covers\/slimcover@2x.jpg?1000' + 'cover': 'https://assets.ppy.sh/beatmaps/1000/covers/cover.jpg?1000', + 'cover@2x': 'https://assets.ppy.sh/beatmaps/1000/covers/cover@2x.jpg?1000', + 'card': 'https://assets.ppy.sh/beatmaps/1000/covers/card.jpg?1000', + 'card@2x': 'https://assets.ppy.sh/beatmaps/1000/covers/card@2x.jpg?1000', + 'list': 'https://assets.ppy.sh/beatmaps/1000/covers/list.jpg?1000', + 'list@2x': 'https://assets.ppy.sh/beatmaps/1000/covers/list@2x.jpg?1000', + 'slimcover': 'https://assets.ppy.sh/beatmaps/1000/covers/slimcover.jpg?1000', + 'slimcover@2x': 'https://assets.ppy.sh/beatmaps/1000/covers/slimcover@2x.jpg?1000' }, 'creator': 'theramdans', 'favourite_count': 100, @@ -57,7 +57,7 @@ export class FakeBeatmapFetcher implements IBeatmapFetcher { 'id': 100, 'nsfw': false, 'play_count': 100, - 'preview_url': '\/\/b.ppy.sh\/preview\/100.mp3', + 'preview_url': '//b.ppy.sh/preview/100.mp3', 'source': '', 'status': 'ranked', 'title': 'title', @@ -75,7 +75,7 @@ export class FakeBeatmapFetcher implements IBeatmapFetcher { 'discussion_locked': false, 'is_scoreable': true, 'last_updated': '2021-06-30T17:39:11+00:00', - 'legacy_thread_url': 'https:\/\/osu.ppy.sh\/community\/forums\/topics\/100', + 'legacy_thread_url': 'https://osu.ppy.sh/community/forums/topics/100', 'nominations_summary': { 'current': 2, 'required': 2 @@ -119,7 +119,7 @@ export class FakeBeatmapFetcher implements IBeatmapFetcher { const map = { ...this.beatmapTemplate, id: id, - url: 'https:\/\/osu.ppy.sh\/beatmaps\/' + id, + url: 'https://osu.ppy.sh/beatmaps/' + id, mode: MODES[mode.id], mode_int: mode.id, convert: false, diff --git a/src/parsers/CommandParser.ts b/src/parsers/CommandParser.ts index 9a76fb44..2853e9fa 100644 --- a/src/parsers/CommandParser.ts +++ b/src/parsers/CommandParser.ts @@ -16,7 +16,7 @@ export namespace parser { } break; case 66: // B - const m_map = message.match(/Beatmap changed to\: (.+) \(https:\/\/osu.ppy.sh\/b\/(\d+)\)$/); + const m_map = message.match(/Beatmap changed to: (.+) \(https:\/\/osu.ppy.sh\/b\/(\d+)\)$/); if (m_map) { return makeBanchoResponse(BanchoResponseType.BeatmapChanged, m_map[2], m_map[1]); } @@ -229,7 +229,7 @@ export namespace parser { } export function SplitCliCommand(line: string): { command: string, arg: string } { - const l = line.match(/^\s*([\!\*]?\w+)\s+(.*)/); + const l = line.match(/^\s*([!*]?\w+)\s+(.*)/); if (l == null) { return { command: line, arg: '' }; } else { @@ -260,16 +260,16 @@ export namespace parser { message = message.trimRight().toLowerCase(); if (message[0] != '!' && message[0] != '*') return false; if (message == '!mp') return false; - return message.match(/^[\!\*](?!roll|stats?|where|faq|report|request)\w+/) != null; + return message.match(/^[!*](?!roll|stats?|where|faq|report|request)\w+/) != null; } export function ParseChatCommand(message: string): { command: string, param: string } { message = message.trimRight(); - let m = message.match(/^\!mp\s+(\w+)\s*(.*?)$/); + let m = message.match(/^!mp\s+(\w+)\s*(.*?)$/); if (m) { return { command: '!' + m[1].toLowerCase(), param: m[2] }; } - m = message.match(/^([\!\*]\w+)\s*(.*?)$/); + m = message.match(/^([!*]\w+)\s*(.*?)$/); if (m) { return { command: m[1].toLowerCase(), param: m[2] }; } else { diff --git a/src/plugins/MapChecker.ts b/src/plugins/MapChecker.ts index 1bf4a2a6..4102e621 100644 --- a/src/plugins/MapChecker.ts +++ b/src/plugins/MapChecker.ts @@ -525,7 +525,7 @@ function parseNoRegulationCommand(param: string): MapCheckerUncheckedOption | un function parseRegulationSetter(param: string): MapCheckerUncheckedOption { const result: { [key: string]: string } = {}; - for (const m of param.matchAll(/([0-9a-zA-Z_\-]+)\s*=\s*([^\s,]+)/g)) { + for (const m of param.matchAll(/([0-9a-zA-Z_-]+)\s*=\s*([^\s,]+)/g)) { const name = unifyParamName(m[1]); const value = m[2]; result[name] = value; diff --git a/src/tests/BeatmapRepositoryTest.ts b/src/tests/BeatmapRepositoryTest.ts index a98b59a1..cf430bea 100644 --- a/src/tests/BeatmapRepositoryTest.ts +++ b/src/tests/BeatmapRepositoryTest.ts @@ -24,7 +24,7 @@ describe('BeatmapRepository Tests', function () { it('parse website test', async () => { const bufSrc = await fs.readFile('./src/tests/cases/3182198.html'); const src = bufSrc.toString(); - const reg = new RegExp('', 'ms'); + const reg = /', 'ms'); - + webpreg = /', 'ms'); - modepreg = new RegExp( - '', - 'ms' - ); + webpreg = /', "ms"); + const reg = /', "ms"); + this.webpreg = /', "ms"); - this.modepreg = new RegExp('', "ms"); + this.webpreg = /