Skip to content

Commit

Permalink
英雄选择期间的自动配置功能
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanxven committed Dec 31, 2024
1 parent 425d1e7 commit c1b61fd
Show file tree
Hide file tree
Showing 6 changed files with 648 additions and 297 deletions.
250 changes: 250 additions & 0 deletions src/main/shards/auto-champ-config/index.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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
Expand Down Expand Up @@ -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()

Expand All @@ -77,5 +326,6 @@ export class AutoChampionConfigMain implements IAkariShardInitDispose {
])

this._handleIpcCall()
this._handleAutoConfig()
}
}
4 changes: 4 additions & 0 deletions src/renderer-shared/shards/auto-champ-config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,9 @@ export class AutoChampConfigRenderer implements IAkariShardInitDispose {
)
}

setEnabled(enabled: boolean) {
return this._setting.set(MAIN_SHARD_NAMESPACE, 'enabled', enabled)
}

async onDispose() {}
}
Loading

0 comments on commit c1b61fd

Please sign in to comment.