breakout71/src/migrations.ts

144 lines
3.9 KiB
TypeScript
Raw Normal View History

2025-04-02 17:03:53 +02:00
import { RunHistoryItem } from "./types";
2025-04-06 18:21:53 +02:00
import _appVersion from "./data/version.json";
2025-04-07 14:08:48 +02:00
import { generateSaveFileContent } from "./generateSaveFileContent";
2025-04-08 14:03:38 +02:00
import { getLevelUnlockCondition, reasonLevelIsLocked } from "./game_utils";
import { allLevels } from "./loadGameData";
2025-04-20 15:04:53 +02:00
import { toast } from "./toast";
2025-04-06 18:21:53 +02:00
// The page will be reloaded if any migrations were run
2025-04-07 14:08:48 +02:00
let migrationsRun = 0;
2025-04-02 17:03:53 +02:00
function migrate(name: string, cb: () => void) {
if (!localStorage.getItem(name)) {
try {
cb();
console.debug("Ran migration : " + name);
localStorage.setItem(name, "" + Date.now());
2025-04-07 14:08:48 +02:00
migrationsRun++;
2025-04-02 17:03:53 +02:00
} catch (e) {
2025-04-20 15:04:53 +02:00
toast((e as Error).message);
2025-04-02 17:03:53 +02:00
console.warn("Migration " + name + " failed : ", e);
}
}
}
2025-04-08 14:03:38 +02:00
function afterMigration() {
// Avoid a boot loop by setting the hash before reloading
// We can't set the query string as it is used for other things
if (migrationsRun && !window.location.hash) {
window.location.hash = "#reloadAfterMigration";
window.location.reload();
}
if (!migrationsRun) {
window.location.hash = "";
}
2025-04-08 10:36:30 +02:00
}
2025-04-02 17:03:53 +02:00
2025-04-07 14:08:48 +02:00
migrate("save_data_before_upgrade_to_" + _appVersion, () => {
localStorage.setItem(
"recovery_data",
JSON.stringify(generateSaveFileContent()),
);
2025-04-06 18:21:53 +02:00
});
2025-04-02 17:03:53 +02:00
migrate("migrate_high_scores", () => {
const old = localStorage.getItem("breakout-3-hs");
if (old) {
localStorage.setItem("breakout-3-hs-short", old);
localStorage.removeItem("breakout-3-hs");
}
});
migrate("recover_high_scores", () => {
let runsHistory = JSON.parse(
localStorage.getItem("breakout_71_runs_history") || "[]",
) as RunHistoryItem[];
runsHistory.forEach((r) => {
const currentHS = parseInt(
localStorage.getItem("breakout-3-hs-" + (r.mode || "short")) || "0",
);
if (r.score > currentHS) {
localStorage.setItem(
"breakout-3-hs-" + (r.mode || "short"),
"" + r.score,
);
}
});
});
2025-04-06 10:13:10 +02:00
migrate("remove_long_and_creative_mode_data", () => {
let runsHistory = JSON.parse(
localStorage.getItem("breakout_71_runs_history") || "[]",
) as RunHistoryItem[];
2025-04-06 15:38:30 +02:00
let cleaned = runsHistory.filter((r) => {
2025-04-07 14:08:48 +02:00
if (!r.perks) return false;
2025-04-06 15:38:30 +02:00
if ("mode" in r) {
if (r.mode !== "short") {
return false;
2025-04-06 10:13:10 +02:00
}
}
2025-04-06 15:38:30 +02:00
return true;
});
if (cleaned.length !== runsHistory.length)
localStorage.setItem("breakout_71_runs_history", JSON.stringify(cleaned));
2025-04-06 10:13:10 +02:00
});
2025-04-06 18:21:53 +02:00
2025-04-19 17:26:45 +02:00
migrate("compact_runs_data_again", () => {
2025-04-06 18:21:53 +02:00
let runsHistory = JSON.parse(
localStorage.getItem("breakout_71_runs_history") || "[]",
) as RunHistoryItem[];
2025-04-19 17:26:45 +02:00
runsHistory = runsHistory.filter((r) => {
if (!r.perks) return false;
if ("mode" in r) {
if (r.mode !== "short") {
return false;
}
delete r.mode;
}
2025-04-06 18:21:53 +02:00
2025-04-19 17:26:45 +02:00
return true;
});
2025-04-06 18:21:53 +02:00
runsHistory.forEach((r) => {
2025-04-07 14:08:48 +02:00
r.runTime = Math.round(r.runTime);
2025-04-19 17:26:45 +02:00
if (r.perks) {
for (let key in r.perks) {
if (!r.perks[key]) {
delete r.perks[key];
}
2025-04-06 18:21:53 +02:00
}
}
2025-04-07 14:08:48 +02:00
if ("best_level_score" in r) {
delete r.best_level_score;
2025-04-07 08:24:17 +02:00
}
2025-04-07 14:08:48 +02:00
if ("worst_level_score" in r) {
delete r.worst_level_score;
2025-04-07 08:24:17 +02:00
}
2025-04-06 18:21:53 +02:00
});
2025-04-07 08:24:17 +02:00
2025-04-06 18:21:53 +02:00
localStorage.setItem("breakout_71_runs_history", JSON.stringify(runsHistory));
});
2025-04-08 14:03:38 +02:00
migrate("set_breakout_71_unlocked_levels" + _appVersion, () => {
2025-04-08 10:36:30 +02:00
// We want to lock any level unlocked by an app upgrade too
2025-04-08 14:03:38 +02:00
let runsHistory = JSON.parse(
2025-04-08 10:36:30 +02:00
localStorage.getItem("breakout_71_runs_history") || "[]",
) as RunHistoryItem[];
2025-04-08 14:03:38 +02:00
let breakout_71_unlocked_levels = JSON.parse(
2025-04-08 10:36:30 +02:00
localStorage.getItem("breakout_71_unlocked_levels") || "[]",
) as string[];
2025-04-08 14:03:38 +02:00
allLevels
.filter((l, li) => !reasonLevelIsLocked(li, runsHistory, false))
.forEach((l) => {
if (!breakout_71_unlocked_levels.includes(l.name)) {
breakout_71_unlocked_levels.push(l.name);
2025-04-08 10:36:30 +02:00
}
2025-04-08 14:03:38 +02:00
});
localStorage.setItem(
"breakout_71_unlocked_levels",
JSON.stringify(breakout_71_unlocked_levels),
);
2025-04-08 10:36:30 +02:00
});
2025-04-08 14:03:38 +02:00
afterMigration();