Pseudo-Corp / SynergismOfficial

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Interval clearing logic in importSynergism doesn't work right

kewne7768 opened this issue · comments

commented

In trying to debug some time-related C15 issues in V2.1.2 (debugging the reason why 0.11s reincs give full obt for some people but not others), I noticed that the intervalHold splicing logic is broken and will result in half of the timers from the previous import remaining. This is broken in an identical way on both the TS rewrite and V2.1.2.

export const importSynergism = (input: string) => {
const d = LZString.decompressFromBase64(input);
const f: Player = d ? JSON.parse(d) : JSON.parse(atob(input));
if (
(f.exporttest === "YES!" || f.exporttest === true) ||
(f.exporttest === false && isTesting)
) {
intervalHold.forEach(clearInt);
intervalHold.length = 0;
localStorage.setItem('Synergysave2', btoa(JSON.stringify(f)));
constantIntervals();
createTimer();
loadSynergy();
}
}

This calls clearInt, which splices the elements from the array during the forEach loop. Then, forEach continues on the next array index. Because the indexes shift during the forEach and browsers implemented it stupidly, the result is that half of the elements are skipped. Then, the .length = 0 clears the array without ever calling clearInterval on the remaining half, "leaking" the timers. The net result is that after importing a save a couple of times, updateAll() ends up being called much more often. This causes stuff like autobuyers and some recalculations to tick much more often than they normally would, changing the game behavior in a rather unstable but good-for-the-player way.

This is most easily tested on V2.1.2 by just running intervalHold.forEach(clearInt); from the console and then checking intervalHold. I confirmed that the TS rewrite is also broken by exporting a bunch of stuff to the window and messing around with it. It'll look like this (V2.1.2, Firefox 85):
image

This can be fixed in a bunch of different ways, Sets supposedly have a stable forEach (according to MDN, haven't tested if it actually is) but it's also possible to just swap that one forEach over to the regular browser clearInterval instead, because the array is cleared by hand immediately after anyway. Every other call to clearInt in the game is fine because it's not a loop.

Looking over this again - I'm not sure why I chose an array over Set in the first place. So much was wrong with this implementation.

Thanks for the awesome bug hunting, should be fixed with 6c44320. Was fixed in my testing but if the issue persists feel free to @ me on Discord/DMs.