Build 29084606

This commit is contained in:
Renan LE CARO 2025-04-19 17:26:45 +02:00
parent 603ebf319a
commit 6adab3d07f
9 changed files with 87 additions and 82 deletions

View file

@ -27,6 +27,11 @@ Other translation are very welcome, contact me if you'd like to submit one.
## Done ## Done
## 29084571
- simpler and more readable encoding for save files
- removed check of payload signature on save file, seemed to fail because of the poor encoding of the name of the "côte d'ivoire" level
- automatic detection of the number of steps required for physics - automatic detection of the number of steps required for physics
- trial runs detection fix - trial runs detection fix

View file

@ -29,8 +29,8 @@ android {
applicationId = "me.lecaro.breakout" applicationId = "me.lecaro.breakout"
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 29084571 versionCode = 29084606
versionName = "29084571" versionName = "29084606"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
useSupportLibrary = true useSupportLibrary = true

File diff suppressed because one or more lines are too long

53
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
// The version of the cache. // The version of the cache.
const VERSION = "29084571"; const VERSION = "29084606";
// The name of the cache // The name of the cache
const CACHE_NAME = `breakout-71-${VERSION}`; const CACHE_NAME = `breakout-71-${VERSION}`;

View file

@ -1 +1 @@
"29084571" "29084606"

View file

@ -708,24 +708,16 @@ async function openSettingsMenu() {
text: t("settings.download_save_file"), text: t("settings.download_save_file"),
help: t("settings.download_save_file_help"), help: t("settings.download_save_file_help"),
async value() { async value() {
const signedPayload = generateSaveFileContent();
const dlLink = document.createElement("a"); const dlLink = document.createElement("a");
const obj = {
dlLink.setAttribute(
"href",
"data:application/json;base64," +
btoa(
JSON.stringify({
fileType: "B71-save-file", fileType: "B71-save-file",
appVersion, appVersion,
signedPayload, payload: generateSaveFileContent(),
key: hashCode( };
"Security by obscurity, but really the game is oss so eh" + const json = JSON.stringify(obj, null, 2);
signedPayload, dlLink.setAttribute(
), "href",
}), "data:application/json;charset=utf-8," + encodeURIComponent(json),
),
); );
dlLink.setAttribute( dlLink.setAttribute(
@ -735,7 +727,7 @@ async function openSettingsMenu() {
.toISOString() .toISOString()
.slice(0, 19) .slice(0, 19)
.replace(/[^0-9]+/gi, "-") + .replace(/[^0-9]+/gi, "-") +
".b71", ".json",
); );
document.body.appendChild(dlLink); document.body.appendChild(dlLink);
dlLink.click(); dlLink.click();
@ -772,37 +764,22 @@ async function openSettingsMenu() {
reader.readAsText(file); reader.readAsText(file);
}); });
const { const { fileType, signedPayload, payload } = JSON.parse(content);
fileType,
appVersion: fileVersion,
signedPayload,
key,
} = JSON.parse(content);
if (fileType !== "B71-save-file") if (fileType !== "B71-save-file")
throw new Error("Not a B71 save file"); throw new Error("Not a B71 save file");
// Actually, loading a save file to an older version is pretty useful if (payload) {
// if (fileVersion > appVersion) localStorage.clear();
// throw new Error( for (let key in payload) {
// "Please update your app first, this file is for version " + localStorage.setItem(key, JSON.stringify(payload[key]));
// fileVersion +
// " or newer.",
// );
if (
key !==
hashCode(
"Security by obscurity, but really the game is oss so eh" +
signedPayload,
)
) {
throw new Error("Key does not match content.");
} }
} else if (signedPayload) {
// Old file format
const localStorageContent = JSON.parse(signedPayload); const localStorageContent = JSON.parse(signedPayload);
localStorage.clear(); localStorage.clear();
for (let key in localStorageContent) { for (let key in localStorageContent) {
localStorage.setItem(key, localStorageContent[key]); localStorage.setItem(key, localStorageContent[key]);
} }
}
await asyncAlert({ await asyncAlert({
title: t("settings.save_file_loaded"), title: t("settings.save_file_loaded"),
content: [ content: [

View file

@ -5,8 +5,10 @@ export function generateSaveFileContent() {
const key = localStorage.key(i) as string; const key = localStorage.key(i) as string;
// Avoid including recovery info in the recovery info // Avoid including recovery info in the recovery info
if (["recovery_data"].includes(key)) continue; if (["recovery_data"].includes(key)) continue;
try {
const value = localStorage.getItem(key) as string; const value = localStorage.getItem(key) as string;
localStorageContent[key] = value; localStorageContent[key] = JSON.parse(value);
} catch (e) {}
} }
return JSON.stringify(localStorageContent); return localStorageContent;
} }

View file

@ -80,18 +80,30 @@ migrate("remove_long_and_creative_mode_data", () => {
localStorage.setItem("breakout_71_runs_history", JSON.stringify(cleaned)); localStorage.setItem("breakout_71_runs_history", JSON.stringify(cleaned));
}); });
migrate("compact_runs_data", () => { migrate("compact_runs_data_again", () => {
let runsHistory = JSON.parse( let runsHistory = JSON.parse(
localStorage.getItem("breakout_71_runs_history") || "[]", localStorage.getItem("breakout_71_runs_history") || "[]",
) as RunHistoryItem[]; ) as RunHistoryItem[];
runsHistory = runsHistory.filter((r) => {
if (!r.perks) return false;
if ("mode" in r) {
if (r.mode !== "short") {
return false;
}
delete r.mode;
}
return true;
});
runsHistory.forEach((r) => { runsHistory.forEach((r) => {
r.runTime = Math.round(r.runTime); r.runTime = Math.round(r.runTime);
if (r.perks) {
for (let key in r.perks) { for (let key in r.perks) {
if (r.perks && !r.perks[key]) { if (!r.perks[key]) {
delete r.perks[key]; delete r.perks[key];
} }
} }
}
if ("best_level_score" in r) { if ("best_level_score" in r) {
delete r.best_level_score; delete r.best_level_score;
} }