From c1b61fdd8841b70f290ce97018710d0784644d9e Mon Sep 17 00:00:00 2001 From: Hanxven Date: Tue, 31 Dec 2024 11:00:41 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8B=B1=E9=9B=84=E9=80=89=E6=8B=A9=E6=9C=9F?= =?UTF-8?q?=E9=97=B4=E7=9A=84=E8=87=AA=E5=8A=A8=E9=85=8D=E7=BD=AE=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/shards/auto-champ-config/index.ts | 250 ++++++++ .../shards/auto-champ-config/index.ts | 4 + .../auto-champ-config/ChampionConfig.vue | 605 +++++++++--------- .../views/automation/AutoChampConfig.vue | 77 +++ .../views/automation/Automation.vue | 5 + src/shared/i18n/zh-CN.yaml | 4 +- 6 files changed, 648 insertions(+), 297 deletions(-) create mode 100644 src/renderer/src-main-window/views/automation/AutoChampConfig.vue diff --git a/src/main/shards/auto-champ-config/index.ts b/src/main/shards/auto-champ-config/index.ts index 1f198736..f4b134e1 100644 --- a/src/main/shards/auto-champ-config/index.ts +++ b/src/main/shards/auto-champ-config/index.ts @@ -1,4 +1,6 @@ +import { i18next } from '@main/i18n' import { IAkariShardInitDispose } from '@shared/akari-shard/interface' +import { formatError } from '@shared/utils/errors' import { AkariIpcMain } from '../ipc' import { LeagueClientMain } from '../league-client' @@ -19,6 +21,14 @@ export class AutoChampionConfigMain implements IAkariShardInitDispose { 'mobx-utils-main' ] + static GAME_MODE_TYPE_MAP = { + CLASSIC: 'normal', + URF: 'urf', + ARAM: 'aram', + NEXUSBLITZ: 'nexusblitz', + ULTBOOK: 'ultbook' + } + private readonly _loggerFactory: LoggerFactoryMain private readonly _settingFactory: SettingFactoryMain private readonly _log: AkariLogger @@ -67,6 +77,245 @@ export class AutoChampionConfigMain implements IAkariShardInitDispose { ) } + private _handleAutoConfig() { + this._mobx.reaction( + () => [this._lc.data.champSelect.currentChampion, this.settings.enabled] as const, + ([championId, enabled]) => { + if (!enabled || !championId) { + return + } + + if (!this._lc.data.gameflow.session || !this._lc.data.champSelect.session) { + return + } + + const localPlayerCellId = this._lc.data.champSelect.session.localPlayerCellId + const self = this._lc.data.champSelect.session.myTeam.find( + (player) => player.cellId === localPlayerCellId + ) + + if (!self) { + return + } + + const gameMode = this._lc.data.gameflow.session.gameData.queue.gameMode + const queueType = this._lc.data.gameflow.session.gameData.queue.type + const selfPosition = self.assignedPosition + + let configKey: string + // CLASSIC 模式下, 特别区分是否是 RANKED + if (gameMode === 'CLASSIC') { + // 目前有 RANKED_FLEX_SR, RANKED_SOLO_5x5 + if (queueType.startsWith('RANKED_')) { + const rankedConfigKey = `ranked-${selfPosition}` + if ( + this.settings.runesV2[championId] && + this.settings.runesV2[championId][rankedConfigKey] + ) { + configKey = rankedConfigKey + } else { + configKey = 'ranked-default' + } + } else { + configKey = 'normal' + } + } else { + configKey = AutoChampionConfigMain.GAME_MODE_TYPE_MAP[gameMode] || null + } + + if (!configKey) { + return + } + + const runes = this.settings.runesV2[championId]?.[configKey] + const spells = this.settings.summonerSpells[championId]?.[configKey] + + if (runes) { + // no await + this._createOrReplaceRunesPage(runes, { championId, position: selfPosition }) + } + + if (spells) { + // no await + this._applySummonerSpells(spells, { championId, position: selfPosition }) + } + } + ) + + this._mobx.reaction( + () => this._lc.data.chat.conversations.championSelect?.id, + (id) => { + if (id && this._lc.data.gameflow.phase === 'ChampSelect') { + if (!this._lc.data.champSelect.session) { + return + } + + this._sendInChat(`[League Akari] 已启用 自动英雄配置`) + } + } + ) + } + + private _getRunesName( + config: ChampionRunesConfig, + meta: { + championId: number + position: string + } + ) { + const { championId, position } = meta + + const championName = this._lc.data.gameData.champions[championId]?.name || championId + const positionName = position ? i18next.t(`common.lanes.${position}`) : null + + const primaryStyleName = + this._lc.data.gameData.perkstyles.styles[config.primaryStyleId]?.name || config.primaryStyleId + const subStyleName = + this._lc.data.gameData.perkstyles.styles[config.subStyleId]?.name || config.subStyleId + const perkNames = config.selectedPerkIds.map( + (id) => this._lc.data.gameData.perks[id]?.name || id + ) + + if (positionName) { + return { + pageName: `${championName} - ${positionName}`, + message: `${championName} - ${positionName} 的符文页已更新为 [${primaryStyleName}] [${subStyleName}] + [${perkNames.join(', ')}]`, + errorMessage: `${championName} - ${positionName} 的符文页更新失败` + } + } else { + return { + pageName: `${championName}`, + message: `${championName} 的符文页已更新为 [${primaryStyleName}] [${subStyleName}] [${perkNames.join(', ')}]`, + errorMessage: `${championName} 的符文页更新失败` + } + } + } + + private _getSummonerSpellsName( + config: SummonerSpellsConfig, + meta: { + championId: number + position: string + } + ) { + const { championId, position } = meta + + const championName = this._lc.data.gameData.champions[championId]?.name || championId + const positionName = position ? i18next.t(`common.lanes.${position}`) : null + + const spell1Name = + this._lc.data.gameData.summonerSpells[config.spell1Id]?.name || config.spell1Id + const spell2Name = + this._lc.data.gameData.summonerSpells[config.spell2Id]?.name || config.spell2Id + + if (positionName) { + return { + message: `${championName} - ${positionName} 的召唤师技能已更新为 [${spell1Name}] [${spell2Name}]`, + errorMessage: `${championName} - ${positionName} 的召唤师技能更新失败` + } + } else { + return { + message: `${championName} 的召唤师技能已更新为 [${spell1Name}] [${spell2Name}]`, + errorMessage: `${championName} 的召唤师技能更新失败` + } + } + } + + private async _createOrReplaceRunesPage( + config: ChampionRunesConfig, + meta: { + championId: number + position: string + } + ) { + const { message, pageName, errorMessage } = this._getRunesName(config, meta) + + try { + const inventory = (await this._lc.api.perks.getPerkInventory()).data + if (inventory.canAddCustomPage) { + const { data: added } = await this._lc.api.perks.postPerkPage({ + name: pageName, + isEditable: true, + primaryStyleId: config.primaryStyleId.toString() + }) + await this._lc.api.perks.putPage({ + id: added.id, + isRecommendationOverride: false, + isTemporary: false, + name: `[Akari] ${pageName}`, + primaryStyleId: config.primaryStyleId, + selectedPerkIds: config.selectedPerkIds, + subStyleId: config.subStyleId + }) + await this._lc.api.perks.putCurrentPage(added.id) + } else { + const pages = (await this._lc.api.perks.getPerkPages()).data + if (!pages.length) { + return + } + + const page1 = pages[0] + await this._lc.api.perks.putPage({ + id: page1.id, + isRecommendationOverride: false, + isTemporary: false, + name: `[Akari] ${pageName}`, + primaryStyleId: config.primaryStyleId, + selectedPerkIds: config.selectedPerkIds, + subStyleId: config.subStyleId + }) + await this._lc.api.perks.putCurrentPage(page1.id) + } + + await this._sendInChat(message) + this._log.info(`符文页已更新`, config, meta) + } catch (error) { + this._ipc.sendEvent(AutoChampionConfigMain.id, 'error-runes-update', formatError(error)) + this._log.warn(`无法更新符文页`, error) + await this._sendInChat(errorMessage) + } + } + + private async _applySummonerSpells( + config: SummonerSpellsConfig, + meta: { + championId: number + position: string + } + ) { + const { message, errorMessage } = this._getSummonerSpellsName(config, meta) + + try { + await this._lc.api.champSelect.setSummonerSpells({ + spell1Id: config.spell1Id, + spell2Id: config.spell2Id + }) + + await this._sendInChat(message) + } catch (error) { + this._ipc.sendEvent(AutoChampionConfigMain.id, 'error-spells-update', formatError(error)) + this._log.warn(`无法更新召唤师技能`, error) + await this._sendInChat(errorMessage) + } + } + + private async _sendInChat(message: string) { + if (!this._lc.data.chat.conversations.championSelect) { + return + } + + try { + await this._lc.api.chat.chatSend( + this._lc.data.chat.conversations.championSelect.id, + `[League Akari] ${message}`, + 'celebration' + ) + } catch (error) { + this._ipc.sendEvent(AutoChampionConfigMain.id, 'error-chat-send', formatError(error)) + this._log.warn(`无法发送信息`, error) + } + } + async onInit() { await this._setting.applyToState() @@ -77,5 +326,6 @@ export class AutoChampionConfigMain implements IAkariShardInitDispose { ]) this._handleIpcCall() + this._handleAutoConfig() } } diff --git a/src/renderer-shared/shards/auto-champ-config/index.ts b/src/renderer-shared/shards/auto-champ-config/index.ts index ca1cf712..1256224b 100644 --- a/src/renderer-shared/shards/auto-champ-config/index.ts +++ b/src/renderer-shared/shards/auto-champ-config/index.ts @@ -72,5 +72,9 @@ export class AutoChampConfigRenderer implements IAkariShardInitDispose { ) } + setEnabled(enabled: boolean) { + return this._setting.set(MAIN_SHARD_NAMESPACE, 'enabled', enabled) + } + async onDispose() {} } diff --git a/src/renderer/src-main-window/components/auto-champ-config/ChampionConfig.vue b/src/renderer/src-main-window/components/auto-champ-config/ChampionConfig.vue index 9a1db49e..64edad0a 100644 --- a/src/renderer/src-main-window/components/auto-champ-config/ChampionConfig.vue +++ b/src/renderer/src-main-window/components/auto-champ-config/ChampionConfig.vue @@ -1,216 +1,94 @@