mirror of
https://git.srhtnin.garden/sarah/srhtnin.github.io.git
synced 2026-10-13 18:38:11 +02:00
306 lines
5.2 KiB
JavaScript
306 lines
5.2 KiB
JavaScript
const SaveKeyName = "SarahtoninGardenSaveKey";
|
|
const LocalSaveName = "SarahtoninGarden";
|
|
|
|
const ApiUrl = "https://api.srhtnin.garden";
|
|
|
|
|
|
function CreateNewSave() {
|
|
return {
|
|
Version: 1,
|
|
Revision: 0,
|
|
LastSavedAt: Date.now(),
|
|
|
|
Currency: {
|
|
Dew: 0
|
|
},
|
|
|
|
Statistics: {
|
|
CurrencyEarned: {
|
|
Dew: 0
|
|
}
|
|
},
|
|
|
|
Seeds: {
|
|
Unlocked: [
|
|
"Rose"
|
|
]
|
|
},
|
|
|
|
Upgrades: {
|
|
PlotSize: 0
|
|
},
|
|
|
|
Garden: {
|
|
Width: 3,
|
|
Height: 3,
|
|
Plots: Array(9).fill(null)
|
|
},
|
|
|
|
Discoveries: {
|
|
Plants: [
|
|
"Rose"
|
|
],
|
|
|
|
Mutations: []
|
|
},
|
|
|
|
MutationCooldowns: {}
|
|
};
|
|
}
|
|
|
|
|
|
function GetSaveKey() {
|
|
let SaveKey = localStorage.getItem(
|
|
SaveKeyName
|
|
);
|
|
|
|
if (SaveKey !== null) {
|
|
return SaveKey;
|
|
}
|
|
|
|
const Bytes = new Uint8Array(32);
|
|
|
|
crypto.getRandomValues(Bytes);
|
|
|
|
SaveKey = Array.from(
|
|
Bytes,
|
|
Byte => Byte
|
|
.toString(16)
|
|
.padStart(2, "0")
|
|
).join("");
|
|
|
|
localStorage.setItem(
|
|
SaveKeyName,
|
|
SaveKey
|
|
);
|
|
|
|
return SaveKey;
|
|
}
|
|
|
|
|
|
function WriteLocalSave(SaveData) {
|
|
localStorage.setItem(
|
|
LocalSaveName,
|
|
JSON.stringify(SaveData)
|
|
);
|
|
}
|
|
|
|
|
|
function ReadLocalSave() {
|
|
const RawSave = localStorage.getItem(
|
|
LocalSaveName
|
|
);
|
|
|
|
if (RawSave === null) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(RawSave);
|
|
} catch (Error) {
|
|
console.error(
|
|
"Couldn't read local save:",
|
|
Error
|
|
);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
async function WriteRemoteSave(SaveData) {
|
|
const Response = await fetch(
|
|
ApiUrl + "/Save.php",
|
|
{
|
|
method: "POST",
|
|
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
SaveKey: GetSaveKey(),
|
|
SaveData: SaveData
|
|
})
|
|
}
|
|
);
|
|
|
|
if (!Response.ok) {
|
|
throw new Error(
|
|
"Save API returned HTTP " +
|
|
Response.status
|
|
);
|
|
}
|
|
|
|
const Result = await Response.json();
|
|
|
|
if (!Result.Success) {
|
|
throw new Error(
|
|
Result.Error ??
|
|
"Remote save failed."
|
|
);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
async function ReadRemoteSave() {
|
|
const Response = await fetch(
|
|
ApiUrl + "/Load.php",
|
|
{
|
|
method: "POST",
|
|
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
SaveKey: GetSaveKey()
|
|
})
|
|
}
|
|
);
|
|
|
|
if (!Response.ok) {
|
|
throw new Error(
|
|
"Load API returned HTTP " +
|
|
Response.status
|
|
);
|
|
}
|
|
|
|
const Result = await Response.json();
|
|
|
|
if (!Result.Success) {
|
|
throw new Error(
|
|
Result.Error ??
|
|
"Remote load failed."
|
|
);
|
|
}
|
|
|
|
if (!Result.Exists) {
|
|
return null;
|
|
}
|
|
|
|
return Result.SaveData;
|
|
}
|
|
|
|
|
|
async function SaveGame(SaveData) {
|
|
SaveData.Revision++;
|
|
SaveData.LastSavedAt = Date.now();
|
|
|
|
WriteLocalSave(SaveData);
|
|
|
|
try {
|
|
await WriteRemoteSave(SaveData);
|
|
} catch (Error) {
|
|
console.error(
|
|
"Couldn't synchronize garden save:",
|
|
Error
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
async function LoadGame() {
|
|
const LocalSave = ReadLocalSave();
|
|
|
|
let RemoteSave = null;
|
|
|
|
try {
|
|
RemoteSave = await ReadRemoteSave();
|
|
} catch (Error) {
|
|
console.error(
|
|
"Couldn't retrieve remote save:",
|
|
Error
|
|
);
|
|
}
|
|
|
|
|
|
if (
|
|
LocalSave === null &&
|
|
RemoteSave === null
|
|
) {
|
|
const NewSave = CreateNewSave();
|
|
|
|
WriteLocalSave(NewSave);
|
|
|
|
try {
|
|
await WriteRemoteSave(NewSave);
|
|
} catch (Error) {
|
|
console.error(
|
|
"Couldn't create remote save:",
|
|
Error
|
|
);
|
|
}
|
|
|
|
return NewSave;
|
|
}
|
|
|
|
|
|
if (
|
|
LocalSave !== null &&
|
|
RemoteSave === null
|
|
) {
|
|
try {
|
|
await WriteRemoteSave(LocalSave);
|
|
} catch (Error) {
|
|
console.error(
|
|
"Couldn't upload local save:",
|
|
Error
|
|
);
|
|
}
|
|
|
|
return LocalSave;
|
|
}
|
|
|
|
|
|
if (
|
|
LocalSave === null &&
|
|
RemoteSave !== null
|
|
) {
|
|
WriteLocalSave(RemoteSave);
|
|
|
|
return RemoteSave;
|
|
}
|
|
|
|
|
|
if (
|
|
LocalSave.Revision >
|
|
RemoteSave.Revision
|
|
) {
|
|
try {
|
|
await WriteRemoteSave(LocalSave);
|
|
} catch (Error) {
|
|
console.error(
|
|
"Couldn't update remote save:",
|
|
Error
|
|
);
|
|
}
|
|
|
|
return LocalSave;
|
|
}
|
|
|
|
|
|
if (
|
|
RemoteSave.Revision >
|
|
LocalSave.Revision
|
|
) {
|
|
WriteLocalSave(RemoteSave);
|
|
|
|
return RemoteSave;
|
|
}
|
|
|
|
|
|
if (
|
|
RemoteSave.LastSavedAt >
|
|
LocalSave.LastSavedAt
|
|
) {
|
|
WriteLocalSave(RemoteSave);
|
|
|
|
return RemoteSave;
|
|
}
|
|
|
|
return LocalSave;
|
|
}
|