[Bug] [Beta] Fix renaming runs (#6268)

Rename run name field, don't encrypt before updating
This commit is contained in:
Sirz Benjie 2025-08-14 16:57:01 -05:00 committed by GitHub
parent ee4950633e
commit b2990aaa15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 96 additions and 95 deletions

View File

@ -29,6 +29,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@ls-lint/ls-lint": "2.3.1",
"@types/crypto-js": "^4.2.0",
"@types/jsdom": "^21.1.7",
"@types/node": "^22.16.5",
"@vitest/coverage-istanbul": "^3.2.4",

View File

@ -48,6 +48,9 @@ importers:
'@ls-lint/ls-lint':
specifier: 2.3.1
version: 2.3.1
'@types/crypto-js':
specifier: ^4.2.0
version: 4.2.2
'@types/jsdom':
specifier: ^21.1.7
version: 21.1.7
@ -718,6 +721,9 @@ packages:
'@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
'@types/crypto-js@4.2.2':
resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==}
'@types/deep-eql@4.0.2':
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
@ -2525,6 +2531,8 @@ snapshots:
'@types/cookie@0.6.0': {}
'@types/crypto-js@4.2.2': {}
'@types/deep-eql@4.0.2': {}
'@types/estree@1.0.8': {}

View File

@ -17,45 +17,42 @@ export function initLoggedInUser(): void {
};
}
export function updateUserInfo(): Promise<[boolean, number]> {
return new Promise<[boolean, number]>(resolve => {
if (bypassLogin) {
loggedInUser = {
username: "Guest",
lastSessionSlot: -1,
discordId: "",
googleId: "",
hasAdminRole: false,
};
let lastSessionSlot = -1;
for (let s = 0; s < 5; s++) {
if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {
lastSessionSlot = s;
break;
}
export async function updateUserInfo(): Promise<[boolean, number]> {
if (bypassLogin) {
loggedInUser = {
username: "Guest",
lastSessionSlot: -1,
discordId: "",
googleId: "",
hasAdminRole: false,
};
let lastSessionSlot = -1;
for (let s = 0; s < 5; s++) {
if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {
lastSessionSlot = s;
break;
}
loggedInUser.lastSessionSlot = lastSessionSlot;
// Migrate old data from before the username was appended
["data", "sessionData", "sessionData1", "sessionData2", "sessionData3", "sessionData4"].map(d => {
const lsItem = localStorage.getItem(d);
if (lsItem && !!loggedInUser?.username) {
const lsUserItem = localStorage.getItem(`${d}_${loggedInUser.username}`);
if (lsUserItem) {
localStorage.setItem(`${d}_${loggedInUser.username}_bak`, lsUserItem);
}
localStorage.setItem(`${d}_${loggedInUser.username}`, lsItem);
localStorage.removeItem(d);
}
});
return resolve([true, 200]);
}
pokerogueApi.account.getInfo().then(([accountInfo, status]) => {
if (!accountInfo) {
resolve([false, status]);
return;
loggedInUser.lastSessionSlot = lastSessionSlot;
// Migrate old data from before the username was appended
["data", "sessionData", "sessionData1", "sessionData2", "sessionData3", "sessionData4"].forEach(d => {
const lsItem = localStorage.getItem(d);
if (lsItem && !!loggedInUser?.username) {
const lsUserItem = localStorage.getItem(`${d}_${loggedInUser.username}`);
if (lsUserItem) {
localStorage.setItem(`${d}_${loggedInUser.username}_bak`, lsUserItem);
}
localStorage.setItem(`${d}_${loggedInUser.username}`, lsItem);
localStorage.removeItem(d);
}
loggedInUser = accountInfo;
resolve([true, 200]);
});
});
return [true, 200];
}
const [accountInfo, status] = await pokerogueApi.account.getInfo();
if (!accountInfo) {
return [false, status];
}
loggedInUser = accountInfo;
return [true, 200];
}

View File

@ -56,15 +56,15 @@ export class PokerogueSessionSavedataApi extends ApiBase {
/**
* Update a session savedata.
* @param params The {@linkcode UpdateSessionSavedataRequest} to send
* @param rawSavedata The raw savedata (as `string`)
* @param params - The request to send
* @param rawSavedata - The raw, unencrypted savedata
* @returns An error message if something went wrong
*/
public async update(params: UpdateSessionSavedataRequest, rawSavedata: string) {
public async update(params: UpdateSessionSavedataRequest, rawSavedata: string): Promise<string> {
try {
const urlSearchParams = this.toUrlSearchParams(params);
const response = await this.doPost(`/savedata/session/update?${urlSearchParams}`, rawSavedata);
const response = await this.doPost(`/savedata/session/update?${urlSearchParams}`, rawSavedata);
return await response.text();
} catch (err) {
console.warn("Could not update session savedata!", err);

View File

@ -128,7 +128,8 @@ export interface SessionSaveData {
battleType: BattleType;
trainer: TrainerData;
gameVersion: string;
runNameText: string;
/** The player-chosen name of the run */
name: string;
timestamp: number;
challenges: ChallengeData[];
mysteryEncounterType: MysteryEncounterType | -1; // Only defined when current wave is ME,
@ -986,51 +987,45 @@ export class GameData {
}
async renameSession(slotId: number, newName: string): Promise<boolean> {
return new Promise(async resolve => {
if (slotId < 0) {
return resolve(false);
}
const sessionData: SessionSaveData | null = await this.getSession(slotId);
if (slotId < 0) {
return false;
}
if (newName === "") {
return true;
}
const sessionData: SessionSaveData | null = await this.getSession(slotId);
if (!sessionData) {
return resolve(false);
}
if (!sessionData) {
return false;
}
if (newName === "") {
return resolve(true);
}
sessionData.name = newName;
// update timestamp by 1 to ensure the session is saved
sessionData.timestamp += 1;
const updatedDataStr = JSON.stringify(sessionData);
const encrypted = encrypt(updatedDataStr, bypassLogin);
const secretId = this.secretId;
const trainerId = this.trainerId;
sessionData.runNameText = newName;
const updatedDataStr = JSON.stringify(sessionData);
const encrypted = encrypt(updatedDataStr, bypassLogin);
const secretId = this.secretId;
const trainerId = this.trainerId;
if (bypassLogin) {
localStorage.setItem(
`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`,
encrypt(updatedDataStr, bypassLogin),
);
return true;
}
if (bypassLogin) {
localStorage.setItem(
`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`,
encrypt(updatedDataStr, bypassLogin),
);
resolve(true);
return;
}
pokerogueApi.savedata.session
.update({ slot: slotId, trainerId, secretId, clientSessionId }, encrypted)
.then(error => {
if (error) {
console.error("Failed to update session name:", error);
resolve(false);
} else {
localStorage.setItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`, encrypted);
updateUserInfo().then(success => {
if (success !== null && !success) {
return resolve(false);
}
});
resolve(true);
}
});
});
const response = await pokerogueApi.savedata.session.update(
{ slot: slotId, trainerId, secretId, clientSessionId },
updatedDataStr,
);
if (response) {
return false;
}
localStorage.setItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`, encrypted);
const success = await updateUserInfo();
return !(success !== null && !success);
}
loadSession(slotId: number, sessionData?: SessionSaveData): Promise<boolean> {

View File

@ -208,7 +208,7 @@ export class RunInfoUiHandler extends UiHandler {
headerText.setOrigin(0, 0);
headerText.setPositionRelative(headerBg, 8, 4);
this.runContainer.add(headerText);
const runName = addTextObject(0, 0, this.runInfo.runNameText, TextStyle.WINDOW);
const runName = addTextObject(0, 0, this.runInfo.name, TextStyle.WINDOW);
runName.setOrigin(0, 0);
runName.setPositionRelative(headerBg, 60, 4);
this.runContainer.add(runName);

View File

@ -377,7 +377,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
"select_cursor_highlight_thick",
undefined,
294,
this.sessionSlots[prevSlotIndex ?? 0]?.saveData?.runNameText ? 50 : 60,
this.sessionSlots[prevSlotIndex ?? 0]?.saveData?.name ? 50 : 60,
6,
6,
6,
@ -553,10 +553,10 @@ class SessionSlot extends Phaser.GameObjects.Container {
}
async setupWithData(data: SessionSaveData) {
const hasName = data?.runNameText;
const hasName = data?.name;
this.remove(this.loadingLabel, true);
if (hasName) {
const nameLabel = addTextObject(8, 5, data.runNameText, TextStyle.WINDOW);
const nameLabel = addTextObject(8, 5, data.name, TextStyle.WINDOW);
this.add(nameLabel);
} else {
const fallbackName = this.decideFallback(data);

View File

@ -45,17 +45,17 @@ export function deepMergeSpriteData(dest: object, source: object) {
}
export function encrypt(data: string, bypassLogin: boolean): string {
return (bypassLogin
? (data: string) => btoa(encodeURIComponent(data))
: (data: string) => AES.encrypt(data, saveKey))(data) as unknown as string; // TODO: is this correct?
if (bypassLogin) {
return btoa(encodeURIComponent(data));
}
return AES.encrypt(data, saveKey).toString();
}
export function decrypt(data: string, bypassLogin: boolean): string {
return (
bypassLogin
? (data: string) => decodeURIComponent(atob(data))
: (data: string) => AES.decrypt(data, saveKey).toString(enc.Utf8)
)(data);
if (bypassLogin) {
return decodeURIComponent(atob(data));
}
return AES.decrypt(data, saveKey).toString(enc.Utf8);
}
// the latest data saved/loaded for the Starter Preferences. Required to reduce read/writes. Initialize as "{}", since this is the default value and no data needs to be stored if present.