Skip to content

feat: support KIOU 1.1.0 (build 15) - #22

Merged
tkgstrator merged 3 commits into
developfrom
feat/kiou-1.1.0-support-v2
Aug 1, 2026
Merged

feat: support KIOU 1.1.0 (build 15)#22
tkgstrator merged 3 commits into
developfrom
feat/kiou-1.1.0-support-v2

Conversation

@tkgstrator

Copy link
Copy Markdown
Contributor

Summary

Brings KiouForge up to KIOU 1.1.0. __TEXT grew from 0x8274000 to 0x94BC000 in that build, so not one 1.0.2 address survives — the old dylib branches into arbitrary code on launch.

  • TARGET_VERSION defaults to 1.1.0; 1.0.1 / 1.0.2 still build by passing it explicitly. The Makefile maps the version to KIOU-Hook's KIOU_HOOK_TARGET_BUILD so the dylib and the recipe can't disagree about which addresses to bake in, and errors on an unknown version rather than silently falling back to whatever the catalog defaults to.
  • The five direct-call RVAs the KIF pipeline uses (GetUSIText, ToSFEN, ParseUSI, KIFWriteOptions..ctor, KIFWriter.Write) move from hardcoded defines in Kif/Helpers.m to the KIOU-Hook catalog, so they track TARGET_VERSION like every other site instead of needing a hand edit per release.
  • make deploy accepts THEOS_DEVICE_PORT — needed when the device is reached through an iproxy forward on the host, where port 22 is the host's own sshd rather than the phone. Defaults to 22, so LAN setups are unaffected. Builds on the helper discovery from feat(deploy): support TrollStore Lite in make deploy #21.
  • FPS override logging only reports transitions. KIOU re-applies its own target every ~5 s, and logging each one buried everything else (198 of 242 lines in one session).
  • Submodules: KIOU-Hook → 8ab5868 (per-version rva/ headers, recipes/v1_1_0.py), Kanade → develop via feat(build_patched_ipa): --bundle-id-suffix flag Kanade#21.

Struct offsets

Every offset the KIF pipeline reads is unchanged between 1.0.2 and 1.1.0 — verified by diffing the two dump.cs files across GameController, MatchConfig, PlayerInfo, GameStateStore, OnlinePvPMode, TimeControlConfig, ShogiGameAdapter, each IMatchMode's _gameAdapter, KIFWriteOptions, and SyncSearchResult. No source change needed.

The one offset a dump can't confirm is RP_OFF_CURRENT_VALUE — the dumper reports offset 0x0 for every ReactiveProperty<T> instantiation. Verified on-device instead; see below.

Why Kanade moves to develop

The old pin sat on feat/bundle-id-suffix, which forked before Kanade #17-#19 and so lacked two things 1.1.0 needs: verify_sites overload resolution (5 of 56 sites fail to resolve without it) and caves.py placeholder rows, which 1.1.0 requires because BeginnerSupportEvaluator.EnsureInitializedLocked is gone from the build. Kanade#21 rebuilt --bundle-id-suffix on top of develop so the side-by-side install path still works from the new pin.

Test plan

  • verify_sites — 55/55 (1.1.0), 56/56 (1.0.2). 1.1.0 is 55 because the EnsureInitializedLocked row is a placeholder.
  • make ipa for both versions — 17 sites patched, no cave overflow
  • make ipa BUNDLE_ID_SUFFIX=chinlancom.neconome.shogi.chinlan; no rewrite without the suffix
  • Unknown TARGET_VERSION fails the build instead of silently mis-targeting
  • Binary check on the built dylib: 1.1.0 RVAs present, no 1.0.2 leftovers; reverses when TARGET_VERSION=1.0.2
  • On-device (iPhone 8, chinlan build, deployed over an iproxy forward):
    • cave_start=0x94b8024 count=56 at startup — the 1.1.0 geometry
    • FPS override fires and now logs one line instead of one every 5 s
    • Login, x-user-id header swap, and profile fetch all resolve
    • Kifu autosave wrote a valid 81-move KIF from an online match
    • RP_OFF_CURRENT_VALUE confirmed — the KIF carries the opponent's real name (後手:パウ), not the プレイヤー placeholder it falls back to when that offset is wrong

🤖 Generated with Claude Code

tkgstrator and others added 3 commits August 1, 2026 12:54
__TEXT grew from 0x8274000 to 0x94BC000 in 1.1.0, so not one 1.0.2
address survives — the old dylib branches into arbitrary code on launch.

TARGET_VERSION now defaults to 1.1.0 and maps to KIOU-Hook's
KIOU_HOOK_TARGET_BUILD, so the dylib and the recipe can't disagree about
which addresses to bake in; an unknown version is an error rather than a
silent fallback to whatever the catalog defaults to.

The five direct-call RVAs the KIF pipeline uses move from hardcoded
defines to the KIOU-Hook catalog, so they track TARGET_VERSION like every
other site instead of needing a hand edit per release.

Every struct offset the KIF pipeline reads is unchanged from 1.0.2,
confirmed by diffing the two dump.cs files. The one offset a dump can't
confirm — RP_OFF_CURRENT_VALUE, which the dumper reports as 0x0 for every
generic instantiation — was verified on-device: the KIF from an online
match carries the opponent's real name, not the placeholder it falls back
to when that offset is wrong.

Kanade moves to develop, which carries the verify_sites overload
resolution and the caves.py placeholder rows 1.1.0 needs (1.1.0 has a
recipe row whose method no longer exists in the build).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The deploy target assumed the device answers on port 22. That holds for a
device on the LAN, but not when it is reached through an iproxy forward
on the host (THEOS_DEVICE_IP=host.docker.internal) — there port 22 is the
host's own sshd, so scp lands the IPA on the wrong machine and the
install silently targets nothing.

Defaults to 22, so LAN setups are unaffected.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
KIOU re-applies its own frame-rate target every ~5 s, so the override
logged an identical line each time — 198 of 242 lines in one session,
burying everything else in the log.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@tkgstrator
tkgstrator merged commit 39887b7 into develop Aug 1, 2026
4 checks passed
@tkgstrator
tkgstrator deleted the feat/kiou-1.1.0-support-v2 branch August 1, 2026 12:57
tkgstrator added a commit that referenced this pull request Aug 2, 2026
* feat: support KIOU 1.1.0 (build 15)

__TEXT grew from 0x8274000 to 0x94BC000 in 1.1.0, so not one 1.0.2
address survives — the old dylib branches into arbitrary code on launch.

TARGET_VERSION now defaults to 1.1.0 and maps to KIOU-Hook's
KIOU_HOOK_TARGET_BUILD, so the dylib and the recipe can't disagree about
which addresses to bake in; an unknown version is an error rather than a
silent fallback to whatever the catalog defaults to.

The five direct-call RVAs the KIF pipeline uses move from hardcoded
defines to the KIOU-Hook catalog, so they track TARGET_VERSION like every
other site instead of needing a hand edit per release.

Every struct offset the KIF pipeline reads is unchanged from 1.0.2,
confirmed by diffing the two dump.cs files. The one offset a dump can't
confirm — RP_OFF_CURRENT_VALUE, which the dumper reports as 0x0 for every
generic instantiation — was verified on-device: the KIF from an online
match carries the opponent's real name, not the placeholder it falls back
to when that offset is wrong.

Kanade moves to develop, which carries the verify_sites overload
resolution and the caves.py placeholder rows 1.1.0 needs (1.1.0 has a
recipe row whose method no longer exists in the build).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* build(deploy): accept THEOS_DEVICE_PORT

The deploy target assumed the device answers on port 22. That holds for a
device on the LAN, but not when it is reached through an iproxy forward
on the host (THEOS_DEVICE_IP=host.docker.internal) — there port 22 is the
host's own sshd, so scp lands the IPA on the wrong machine and the
install silently targets nothing.

Defaults to 22, so LAN setups are unaffected.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(hooks): log FPS overrides only on transition

KIOU re-applies its own frame-rate target every ~5 s, so the override
logged an identical line each time — 198 of 242 lines in one session,
burying everything else in the log.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: tkgstrator <tkgstrator@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant