Patches: a toggle that changes no patch= lines still has to write the enable list

"I enabled HostFS and it is still off", with the switch sitting on. His game INI
proves it: [Cheats] present but empty, and no [Patches] section at all -- the
enable-list write never ran.

toggleLocalCheat flips the switch optimistically, then bails early when
setBodyEnabled produced an identical body:

    if (newBody == target.body) return   // pushEnableList never reached

setBodyEnabled only comments or uncomments patch= lines, and community pnach files
ship UNCOMMENTED. So for exactly those files enabling is a no-op on the body, the
early return skips the enable list, and Patch.cpp applies a NAMED group only when
its name is in [Patches]/[Cheats] Enable -- unlabelled groups are the only ones
that auto-enable. Switch on, file already correct, patch never applied, nothing
anywhere saying so.

The two writes are independent. Rewrite the body only when it differs; always push
the enable list.

This is what actually blocked the Persona 3 FES mods. The HostFS loader group could
not be enabled at all, so the mod never loaded, and the texture pack keyed to the
modded font stopped matching as a consequence -- which is how it arrived as "my
texture mods broke".
This commit is contained in:
jpolo1224
2026-08-21 23:09:00 -04:00
parent b506fe2683
commit 20a9238b31
@@ -600,7 +600,25 @@ class PatchManagerViewModel(application: Application) : AndroidViewModel(applica
state.value = state.value.copy(
localCheats = state.value.localCheats.map { if (it.name == name) it.copy(enabled = nowEnabled, body = newBody) else it },
)
if (newBody == target.body) return // no patch= lines changed; nothing to write
// ★ The body being unchanged does NOT mean there is nothing to do.
//
// setBodyEnabled only comments or uncomments the patch= lines, and community pnach files
// ship UNCOMMENTED -- so enabling one of those produces an identical body. This used to
// return here, which skipped pushEnableList entirely. Patch.cpp applies a NAMED group only
// when its name is in the [Patches]/[Cheats] Enable list (unlabelled groups auto-enable),
// so the switch flipped on screen, the file was already correct, and the patch still never
// applied. That is "I enabled HostFS and it is still off" -- the enable list was never
// written, and the game INI ended up with no [Patches] section at all.
//
// The two writes are independent: rewrite the body only when it actually differs, but
// always push the enable list.
if (newBody == target.body) {
viewModelScope.launch {
pushEnableList(path)
reloadCore()
}
return
}
viewModelScope.launch {
val ok = withContext(Dispatchers.IO) {
runCatching {