fix: 登录皮肤站后侧栏立即显示玩家选择器
Some checks failed
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Some checks failed
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
登录 StarLight 皮肤站后,侧栏账户选择器(AccountsCard)不会列出 皮肤站玩家,必须先使用该玩家启动一次实例,玩家才会出现。 原因:账户选择器列出的是 auth::get_users 的账户库,而皮肤站玩家 是 iframe 推送的另一套数据。两者唯一的打通点是 auth|login_skin_site_player(把玩家注册为 yggdrasil 账户),而它 此前只在启动实例选择玩家时被调用。 修复: - instance-player 新增 registerSkinSitePlayers:玩家列表就绪后, 把尚未注册的皮肤站玩家逐个注册为账户。幂等(跳过账户库中已存在 的 profile id)、best-effort(单个失败不影响其余)、每个玩家 单独获取下载 token(皮肤站登录接口可能将 token 绑定到单一玩家)。 - AccountsCard 的玩家监听新增 skinSiteUser 依赖,玩家就绪后调用 注册并刷新账户列表,使玩家无需先启动实例即可在选择器中选择。
This commit is contained in:
@ -291,6 +291,7 @@ import {
|
|||||||
users,
|
users,
|
||||||
} from '@/helpers/auth'
|
} from '@/helpers/auth'
|
||||||
import { process_listener } from '@/helpers/events'
|
import { process_listener } from '@/helpers/events'
|
||||||
|
import { registerSkinSitePlayers } from '@/helpers/instance-player'
|
||||||
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
|
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||||
import type { Skin } from '@/helpers/skins'
|
import type { Skin } from '@/helpers/skins'
|
||||||
import { get_available_skins } from '@/helpers/skins'
|
import { get_available_skins } from '@/helpers/skins'
|
||||||
@ -630,11 +631,22 @@ async function setAccount(account: MinecraftCredential) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
[skinSitePlayers, defaultUser],
|
[skinSitePlayers, defaultUser, skinSiteUser],
|
||||||
([availablePlayers, selectedLocalUser]) => {
|
([availablePlayers, selectedLocalUser, siteUser]) => {
|
||||||
if (!selectedLocalUser && !selectedSkinSitePlayerId.value && availablePlayers.length > 0) {
|
if (!selectedLocalUser && !selectedSkinSitePlayerId.value && availablePlayers.length > 0) {
|
||||||
selectSkinSitePlayer(availablePlayers[0].uuid)
|
selectSkinSitePlayer(availablePlayers[0].uuid)
|
||||||
}
|
}
|
||||||
|
// Register skin-site players as launcher accounts as soon as they are
|
||||||
|
// available, so the account picker shows them without requiring a first
|
||||||
|
// launch. `registerSkinSitePlayers` is idempotent and best-effort.
|
||||||
|
if (siteUser?.uuid && availablePlayers.length > 0) {
|
||||||
|
const pendingIds = availablePlayers.map((player) => player.uuid)
|
||||||
|
void registerSkinSitePlayers(pendingIds, siteUser.uuid)
|
||||||
|
.then(() => refreshValues())
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn('Failed to register skin site players:', error)
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
)
|
)
|
||||||
|
|||||||
@ -56,6 +56,52 @@ export async function authenticateInstancePlayer(player: InstancePlayer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers every skin-site player as a launcher account so they show up in the
|
||||||
|
* account picker immediately after signing in to the skin site, instead of only
|
||||||
|
* after a first launch. Idempotent: players that already exist in the account
|
||||||
|
* list (matched by profile UUID) are skipped, and already-signed-in players are
|
||||||
|
* not re-requested. Best-effort: a single player failing does not abort the rest.
|
||||||
|
*/
|
||||||
|
export async function registerSkinSitePlayers(
|
||||||
|
playerIds: string[],
|
||||||
|
userUuid: string,
|
||||||
|
): Promise<void> {
|
||||||
|
if (playerIds.length === 0) return
|
||||||
|
if (skinSiteStatus.value !== 'signed-in' || skinSiteUser.value?.uuid !== userUuid) return
|
||||||
|
|
||||||
|
let known = new Set<string>()
|
||||||
|
try {
|
||||||
|
const existing = await users()
|
||||||
|
known = new Set(
|
||||||
|
(existing as Array<{ profile?: { id?: string } }>)
|
||||||
|
.map((account) => account?.profile?.id)
|
||||||
|
.filter((id): id is string => typeof id === 'string'),
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
// If the account list cannot be read, still attempt to register; the
|
||||||
|
// backend upsert is idempotent.
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const playerId of playerIds) {
|
||||||
|
if (known.has(playerId)) continue
|
||||||
|
if (skinSiteStatus.value !== 'signed-in' || skinSiteUser.value?.uuid !== userUuid) return
|
||||||
|
try {
|
||||||
|
// Request a fresh download token per player: the skin site login
|
||||||
|
// endpoint may bind a token to a single player id.
|
||||||
|
const token = await requestSkinSiteDownloadToken()
|
||||||
|
await invoke('plugin:auth|login_skin_site_player', {
|
||||||
|
token,
|
||||||
|
playerId,
|
||||||
|
userId: userUuid,
|
||||||
|
})
|
||||||
|
known.add(playerId)
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`Failed to register skin site player ${playerId}:`, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function saveInstancePlayer(instanceId: string, player: InstancePlayer) {
|
export async function saveInstancePlayer(instanceId: string, player: InstancePlayer) {
|
||||||
await authenticateInstancePlayer(player)
|
await authenticateInstancePlayer(player)
|
||||||
await invoke('plugin:auth|set_instance_player', { instanceId, player })
|
await invoke('plugin:auth|set_instance_player', { instanceId, player })
|
||||||
|
|||||||
Reference in New Issue
Block a user