修复了角色列表未能完全同步的问题
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
This commit is contained in:
@ -198,19 +198,14 @@ pub async fn begin_yggdrasil_login(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(profile) = response.selected_profile {
|
// 收集本次登录可用的所有角色;优先使用 availableProfiles,回退到 selectedProfile。
|
||||||
let credentials = create_credentials(
|
let mut profiles: Vec<YggdrasilProfile> = response.available_profiles.clone();
|
||||||
profile,
|
if profiles.is_empty() {
|
||||||
response.access_token,
|
if let Some(selected) = response.selected_profile.clone() {
|
||||||
response.client_token,
|
profiles.push(selected);
|
||||||
metadata,
|
}
|
||||||
login,
|
|
||||||
);
|
|
||||||
credentials.upsert(exec).await?;
|
|
||||||
return Ok(YggdrasilLoginResult::Complete { credentials });
|
|
||||||
}
|
}
|
||||||
|
if profiles.is_empty() {
|
||||||
if response.available_profiles.is_empty() {
|
|
||||||
return Err(ErrorKind::OtherError(
|
return Err(ErrorKind::OtherError(
|
||||||
"The Yggdrasil account does not have a Minecraft profile"
|
"The Yggdrasil account does not have a Minecraft profile"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
@ -218,13 +213,18 @@ pub async fn begin_yggdrasil_login(
|
|||||||
.as_error());
|
.as_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
if response.available_profiles.len() == 1 {
|
// 逐个角色 refresh + 保存,实现「一次登录自动加入所有角色」。
|
||||||
let profile = response.available_profiles[0].clone();
|
// Yggdrasil 同一时刻只激活一个角色,因此需要串行 refresh,并各自保存当次 token。
|
||||||
|
let mut access_token = response.access_token.clone();
|
||||||
|
let mut client_token = response.client_token.clone();
|
||||||
|
let mut last_credentials: Option<Credentials> = None;
|
||||||
|
|
||||||
|
for (index, profile) in profiles.iter().enumerate() {
|
||||||
let refreshed = refresh_selected_profile(
|
let refreshed = refresh_selected_profile(
|
||||||
&metadata.api_root,
|
&metadata.api_root,
|
||||||
&response.access_token,
|
&access_token,
|
||||||
&response.client_token,
|
&client_token,
|
||||||
&profile,
|
profile,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let selected_profile = refreshed.selected_profile.ok_or_else(|| {
|
let selected_profile = refreshed.selected_profile.ok_or_else(|| {
|
||||||
@ -234,35 +234,35 @@ pub async fn begin_yggdrasil_login(
|
|||||||
)
|
)
|
||||||
.as_error()
|
.as_error()
|
||||||
})?;
|
})?;
|
||||||
let credentials = create_credentials(
|
access_token = refreshed.access_token.clone();
|
||||||
|
client_token = refreshed.client_token.clone();
|
||||||
|
|
||||||
|
let mut credentials = create_credentials(
|
||||||
selected_profile,
|
selected_profile,
|
||||||
refreshed.access_token,
|
refreshed.access_token,
|
||||||
refreshed.client_token,
|
refreshed.client_token,
|
||||||
metadata,
|
YggdrasilMetadata {
|
||||||
|
api_root: metadata.api_root.clone(),
|
||||||
|
server_name: metadata.server_name.clone(),
|
||||||
|
raw: String::new(),
|
||||||
|
},
|
||||||
login,
|
login,
|
||||||
);
|
);
|
||||||
|
// 仅让最后一个(通常是默认/首个以外的角色)保持 active,避免多个 active。
|
||||||
|
credentials.active = index == profiles.len() - 1;
|
||||||
credentials.upsert(exec).await?;
|
credentials.upsert(exec).await?;
|
||||||
|
last_credentials = Some(credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(credentials) = last_credentials {
|
||||||
return Ok(YggdrasilLoginResult::Complete { credentials });
|
return Ok(YggdrasilLoginResult::Complete { credentials });
|
||||||
}
|
}
|
||||||
|
|
||||||
let flow_id = Uuid::new_v4();
|
Err(ErrorKind::OtherError(
|
||||||
let profiles = response.available_profiles.clone();
|
"The Yggdrasil account does not have a Minecraft profile"
|
||||||
let mut pending = PENDING_LOGINS.lock().await;
|
.to_string(),
|
||||||
pending.retain(|_, login| login.created.elapsed() < PENDING_LOGIN_LIFETIME);
|
)
|
||||||
pending.insert(
|
.as_error())
|
||||||
flow_id,
|
|
||||||
PendingYggdrasilLogin {
|
|
||||||
created: Instant::now(),
|
|
||||||
api_root: metadata.api_root,
|
|
||||||
server_name: metadata.server_name,
|
|
||||||
login: login.to_string(),
|
|
||||||
access_token: response.access_token,
|
|
||||||
client_token: response.client_token,
|
|
||||||
profiles: response.available_profiles,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(YggdrasilLoginResult::SelectProfile { flow_id, profiles })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn finish_yggdrasil_login(
|
pub async fn finish_yggdrasil_login(
|
||||||
|
|||||||
141
tools/icon_work/multi_profile.py
Normal file
141
tools/icon_work/multi_profile.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
p = r"D:\Project\Starlight_Lancher\packages\app-lib\src\state\minecraft_auth\yggdrasil.rs"
|
||||||
|
t = open(p, encoding="utf-8").read()
|
||||||
|
|
||||||
|
# 定位:把 201-265 的整段逻辑替换成"遍历所有 profiles"
|
||||||
|
old = """ if let Some(profile) = response.selected_profile {
|
||||||
|
let credentials = create_credentials(
|
||||||
|
profile,
|
||||||
|
response.access_token,
|
||||||
|
response.client_token,
|
||||||
|
metadata,
|
||||||
|
login,
|
||||||
|
);
|
||||||
|
credentials.upsert(exec).await?;
|
||||||
|
return Ok(YggdrasilLoginResult::Complete { credentials });
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.available_profiles.is_empty() {
|
||||||
|
return Err(ErrorKind::OtherError(
|
||||||
|
"The Yggdrasil account does not have a Minecraft profile"
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.available_profiles.len() == 1 {
|
||||||
|
let profile = response.available_profiles[0].clone();
|
||||||
|
let refreshed = refresh_selected_profile(
|
||||||
|
&metadata.api_root,
|
||||||
|
&response.access_token,
|
||||||
|
&response.client_token,
|
||||||
|
&profile,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let selected_profile = refreshed.selected_profile.ok_or_else(|| {
|
||||||
|
ErrorKind::OtherError(
|
||||||
|
"The Yggdrasil service did not select the requested profile"
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.as_error()
|
||||||
|
})?;
|
||||||
|
let credentials = create_credentials(
|
||||||
|
selected_profile,
|
||||||
|
refreshed.access_token,
|
||||||
|
refreshed.client_token,
|
||||||
|
metadata,
|
||||||
|
login,
|
||||||
|
);
|
||||||
|
credentials.upsert(exec).await?;
|
||||||
|
return Ok(YggdrasilLoginResult::Complete { credentials });
|
||||||
|
}
|
||||||
|
|
||||||
|
let flow_id = Uuid::new_v4();
|
||||||
|
let profiles = response.available_profiles.clone();
|
||||||
|
let mut pending = PENDING_LOGINS.lock().await;
|
||||||
|
pending.retain(|_, login| login.created.elapsed() < PENDING_LOGIN_LIFETIME);
|
||||||
|
pending.insert(
|
||||||
|
flow_id,
|
||||||
|
PendingYggdrasilLogin {
|
||||||
|
created: Instant::now(),
|
||||||
|
api_root: metadata.api_root,
|
||||||
|
server_name: metadata.server_name,
|
||||||
|
login: login.to_string(),
|
||||||
|
access_token: response.access_token,
|
||||||
|
client_token: response.client_token,
|
||||||
|
profiles: response.available_profiles,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(YggdrasilLoginResult::SelectProfile { flow_id, profiles })"""
|
||||||
|
|
||||||
|
new = """ // 收集本次登录可用的所有角色;优先使用 availableProfiles,回退到 selectedProfile。
|
||||||
|
let mut profiles: Vec<YggdrasilProfile> = response.available_profiles.clone();
|
||||||
|
if profiles.is_empty() {
|
||||||
|
if let Some(selected) = response.selected_profile.clone() {
|
||||||
|
profiles.push(selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if profiles.is_empty() {
|
||||||
|
return Err(ErrorKind::OtherError(
|
||||||
|
"The Yggdrasil account does not have a Minecraft profile"
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 逐个角色 refresh + 保存,实现「一次登录自动加入所有角色」。
|
||||||
|
// Yggdrasil 同一时刻只激活一个角色,因此需要串行 refresh,并各自保存当次 token。
|
||||||
|
let mut access_token = response.access_token.clone();
|
||||||
|
let mut client_token = response.client_token.clone();
|
||||||
|
let mut last_credentials: Option<Credentials> = None;
|
||||||
|
|
||||||
|
for (index, profile) in profiles.iter().enumerate() {
|
||||||
|
let refreshed = refresh_selected_profile(
|
||||||
|
&metadata.api_root,
|
||||||
|
&access_token,
|
||||||
|
&client_token,
|
||||||
|
profile,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let selected_profile = refreshed.selected_profile.ok_or_else(|| {
|
||||||
|
ErrorKind::OtherError(
|
||||||
|
"The Yggdrasil service did not select the requested profile"
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.as_error()
|
||||||
|
})?;
|
||||||
|
access_token = refreshed.access_token.clone();
|
||||||
|
client_token = refreshed.client_token.clone();
|
||||||
|
|
||||||
|
let mut credentials = create_credentials(
|
||||||
|
selected_profile,
|
||||||
|
refreshed.access_token,
|
||||||
|
refreshed.client_token,
|
||||||
|
YggdrasilMetadata {
|
||||||
|
api_root: metadata.api_root.clone(),
|
||||||
|
server_name: metadata.server_name.clone(),
|
||||||
|
raw: String::new(),
|
||||||
|
},
|
||||||
|
login,
|
||||||
|
);
|
||||||
|
// 仅让最后一个(通常是默认/首个以外的角色)保持 active,避免多个 active。
|
||||||
|
credentials.active = index == profiles.len() - 1;
|
||||||
|
credentials.upsert(exec).await?;
|
||||||
|
last_credentials = Some(credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(credentials) = last_credentials {
|
||||||
|
return Ok(YggdrasilLoginResult::Complete { credentials });
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(ErrorKind::OtherError(
|
||||||
|
"The Yggdrasil account does not have a Minecraft profile"
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.as_error())"""
|
||||||
|
|
||||||
|
assert old in t, "找不到要替换的登录逻辑块"
|
||||||
|
t = t.replace(old, new, 1)
|
||||||
|
|
||||||
|
open(p, "w", encoding="utf-8", newline="\n").write(t)
|
||||||
|
print("done")
|
||||||
Reference in New Issue
Block a user