Fix/non steam installs support - #48
Conversation
The install type came from argv[0], which on Steam is the asset decryption
key. That is circular on a copy that has no key, and two things broke because
of it:
- encryption.js always read data/System.KEL to get the asset key. On a
plaintext install that file does not exist, so it threw during startup
and left _modloader_encryption undefined.
- every injection point used the encrypted names (.KEL, .PLUTO, .HERO,
.AUBREY, .OMORI, .rpgmvp). A game asking for stock RPG Maker MV names
matched nothing in the overlay, so mods silently did nothing.
The install is now detected from whether data/System.KEL is on disk, and the
targets and encryption follow from that:
steam .KEL/.PLUTO/.HERO/.AUBREY/.OMORI + AES / rpgmaker XOR
plaintext stock RPG Maker MV names + pass-through
Only Steam builds are asked for a launch argument now, since a non-Steam copy
starts without one.
The language mount point also comes from the game's own
Text_Language_Processor parameters in both branches, and plugins.js is read
relative to the game directory rather than the working directory. The old
relative read quietly fell back to "en" any time the process started
somewhere else.
Steam and playtest rule sets come out byte for byte the same as before.
Image deltas had .rpgmvp hardcoded in five places, so .olid patching pointed at a file name that only exists on the encrypted Steam build. Take the extension from the active configuration instead. That also fixes image deltas under --test, where pictures were already mounted as .png while the delta applier still looked for .rpgmvp.
Non-Steam copies launch with no arguments, so the shadowed argv came out as
[undefined]: length 1, holding nothing. Utils.isOptionValid checks
argv.length > 0 and then calls argv[0].split('&'), which throws.
The first caller is SceneManager.preferableRendererType, which runs at the
second step of boot, before Graphics exists. Graphics.printError then threw
on its own inside _clearUpperCanvas, so what actually surfaced was "Cannot
read property 'getContext' of undefined" and the real cause was gone.
Graphics.printError throws inside _clearUpperCanvas when it runs before the canvases exist. Anything failing during SceneManager.initialize therefore reports as "Cannot read property 'getContext' of undefined" whatever the actual cause was, so every early boot failure looks the same and none of them name anything. Wrap SceneManager.catchException so the true stack reaches latest.log first. Scripts that fail to load, and anything escaping window.onload(), are logged as well.
main.js calls PluginManager.setup, which appends one <script> per plugin. Normally the browser's load event holds off until those have run, so every plugin is applied before SceneManager.run. The loader replaces index.html and calls window.onload() itself, which loses that guarantee, and SceneManager.initialize ended up running against a stock engine with none of the game's overrides applied. On OMORI that showed up as "FPSMeter is not defined". A plugin replaces Graphics._createFPSMeter and it had not run yet, so the stock version asked for a global the game never loads. The plugin scripts turned up about 30ms after the crash. Each plugin script is now tracked as it is queued, and awaited before boot. Failed loads resolve as well, so one broken plugin cannot stall startup, and a 60s race guard stops the boot hanging outright. js/libs/fpsmeter.js is added to the script list too. It ships with the game and belongs to the stock RPG Maker MV library set, but the loader never loaded it, so the vanilla path had nothing to fall back on. The five second isInTestMode sleep works around the same problem. Left it alone, since it also covers playtest asset loading.
|
AI slop. Also: One condition where plaintext might seem enticing is an "SDK Build" - but even then it's needless. Just launch the game with the key passed into argv. For the other fixes, I will have a look at them and see if they are actually needed. Again, a lot of the assumptions in oneloader hold for the ancient version of nw.js we are on, and the specific environment omori sets up and needs. I am open to improvements regarding the bootup flow, and will likely cherrypick the error handling changes (without the unnecessary AI garbage comments). |
|
@rphsoftware As for the playtest part, even when bypassing the argv, Oneloader had issues related to FPS meter, and multiple crashes. So no idea if my version (OMORI1.0.8d) was related to this. Oneloader can also be applied for a playtest version right ? If yes then my version of the game is the issue not Oneloader. Again, for the AI part, this one is on my end. I need time to get properly accustomed to a new codebase. Hit me up if anything came up 🫡 Happy to help even a little 😁 |
Okay. This PR fixes a handful of bugs and introduces more bugs for future releases (~ ̄▽ ̄)~ (ohh read all of the PR message and enjoy the show 😊).
Note for anyone who isn't a dev: nothing here changes how you use OneLoader, you can stop reading (❁´◡`❁) . Though let's be honest, nobody reads a PR body ㄟ( ▔, ▔ )ㄏ (right ? 👀)
Decrypted Version / Non-Steam Support
Oneloader now supports already decrypted versions (non-Steam versions, annnd I won't ask how you got them (●'◡'●) , but naah this also has legitimate cases, I hope (゜ー゜) ).
Oneloader when starting the game assumes you have an
argv[0]. This is the Steam decryption key, so using it to decide "is this Steam?" is a bit circular on a copy that doesn't have one (*  ̄︿ ̄).Two things were broken because of that:
encryption.jsalways readdata/System.KELto bootstrap the asset key. No such file, so it throws during startup and_modloader_encryptionis undefined forever.Items.jsonwas filed asdata/items.KELwhile the game politely asked fordata/items.json. Never matched. Mods silently did nothing, which is a fun thing to debug.Detection now checks for
data/System.KEL(MY FAVVVV KEL 😍, but naah I love all the characters (YES even Sweetheart 👀)). Every RPG Maker MV game has aSystem.json, so on an encrypted copy its Kel-flavoured twin is always sitting at a known path..AUBREY,.HEROand.OMORIwork as signals too, but those filenames vary so you'd be listing directories instead of checking one path (so I picked KEL to check 👀, fight me in the comments (●'◡'●) )Encrypted installs keep AES + rpgmaker XOR exactly as before. Plaintext ones get pass-through and stock RPG Maker MV names. The Steam launch argument is only demanded of Steam builds now, since a plaintext copy starts without one.
The language mount point also comes from the game's own
Text_Language_Processorparameters in both branches, andplugins.jsis read relative to the game directory rather than the working directory. The old relative read quietly fell back to"en"whenever the process started anywhere else 🙃Steam and playtest rule sets come out byte for byte identical to before. I actually checked, I didn't just say it.
argv crashes any launch without arguments
Speaking of
argv[0], here's the fun part. The argv shadow was built as[key]. No key means[undefined], an array of length 1 holding absolutely nothing. Then:( THE FOLLOWING IS A CLAUDE SENTENCE, and I couldn't do it better than him :-) )
Length check passes ✅ then
.splitruns on nothing 💀 First caller isSceneManager.preferableRendererType, i.e. step two of boot, i.e. before Graphics exists, i.e. see the next section about why you couldn't read the error (. ❛ ᴗ ❛.)Empty argv is now
[].Boot errors are readable now (related to #45, #46)
Graphics.printErrorthrows inside_clearUpperCanvaswhen it runs before the canvases exist. So when the game dies early, the error handler dies while handling the error, and the thing you actually see is the handler's corpse:Cannot read property 'getContext' of undefined. Every single time. Regardless of cause.Which is why a solid chunk of the open issues are just screenshots of that same message, unanswerable since 2021 (#6 says "latest.log is also unhelpful", #45 says the error is literally drawn on top of itself). Love that for us ㄟ( ▔, ▔ )ㄏ
The real stack now goes to
latest.logbeforeprintErrorgets to bury it, along with any script that fails to load. This isn't a repair for #45 or #46, but those people can finally post something that names a cause instead of vibes.Fixes #44 (ReferenceError: FPSMeter is not defined)
main.jsappends one<script>per plugin, and normally the browser's load event politely waits for those to run. OneLoader replacesindex.htmland callswindow.onload()by hand, so nothing waits, and the engine boots with zero of the game's plugins loaded.It then reaches
Graphics._createFPSMeterand asks for a global that a plugin was going to replace roughly 30ms later w(゚Д゚)wThis is not a decrypted-copy problem. It's a race, so it hits anyone whose scripts resolve slowly, Steam included (see #45, on Wine). Plugin scripts are now tracked and awaited before boot. Failed ones resolve too so a single broken plugin can't stall startup, with a 60s cap so it can never hang outright.
Also adds
js/libs/fpsmeter.jsto the script list. It ships with the game, it's part of the stock RPG Maker MV library set, OneLoader just never loaded it (●'◡'●)Also, while I was in there
Image deltas had
.rpgmvphardcoded in five places, so.olidpatching pointed at a filename that only exists on encrypted builds. That was broken under--testtoo, where pictures are already mounted as.png. Free bug fix for people who never touched a decrypted copy in their life (❁´◡`❁)Each commit explains its own change if you want the details (THANK YOUU CLAUDYYY (●'◡'●), what I call claude 😊), I'm not retyping all of it here 👀
Call it 1.6 or don't, I'm a PR message not a person (ask Issa about the version, or fight him (. ❛ ᴗ ❛.) )
SEEE YAAAAA
here is a picture of a cat drinking coffe (ME AT 1 AM doing this PR (. ❛ ᴗ ❛.))

Disclaimer: This was test ONLY on my version (1.0.8d) I KNOW it needs more testing, feel free to tell me if anything isn't working 😊