Bug-fix release focused on the gacha and boost-time systems, with three issues healed via auto-applied migrations. No config or schema changes required.
Highlights
- Gacha menu crash fix (#175) — characters whose
gacha_itemscolumn held an empty bytea ('\x') crashed the ZZ client's gacha menu with a buffer overrun. The server now always sends the required leading count byte, andLoadColumnWithDefaulttreats empty bytea the same as NULL. RTTI-confirmed againstCSync_man::putReceive_gacha_item/FUN_11531e90inmhfo-hd.dll; full RE write-up indocs/re_notes/recv_gacha_item_crash.md. - Boost-time consistency fix —
GetBoostTimeLimitwas wrapping pre-1970boost_timevalues through a nakeduint32(int64)cast, producing far-future timestamps that made the client think a boost was permanently active, even thoughGetBoostRightcorrectly reported it as expired. Discovered while testing against a live server where a character'sboost_timewas year 1906. - Missing save fix (#163) — healing migration for characters whose
rasta_idwas clobbered to0by the pre-fixSaveMercenarybug. Silent save failures auto-resolve on upgrade. - Login / boost-time config flags fully honored (#187) —
DisableLoginBoostandDisableBoostTimenow apply to every relevant handler; fresh characters no longer show a phantom "Boost Time" overlay.
All fixes
- Empty-bytea crash in
MSG_MHF_RECEIVE_GACHA_ITEM(#175) - Silent
StructScanfailures inGachaRepository— misconfiguredgacha_itemsrows now log a warn pointing at the likely cause (item_type > 255,item_id/quantity > 65535) - Stray second ACK in
handleMsgMhfGetBoostTimeLimit(latent protocol bug) uint32(int64)wraparound inGetBoostTimeLimitfor pre-1970 / already-expiredboost_time; harmonised withGetBoostRight- Quest tune-value multiplier:
ZennyMultiplier: 0.0no longer silently falls back to 100%; float32 rounding fixed across all 18 multiplier sites DisableLoginBoost/DisableBoostTimenow fully honored (#187)- Playtime rollback across sessions:
updateSaveDataWithStructnow writes the accumulated counter back into the save blob - Softlock on forge purchases and N-points:
MSG_CA_EXCHANGE_ITEMandMSG_MHF_USE_UD_SHOP_COINnow parse the ack handle and respond withdoAckBufFailinstead of dropping the packet
Migrations (auto-applied on startup)
0010_fix_zero_rasta_id— NULLs outrasta_id = 0rows so save loads recover.0011_fix_stale_boost_time— NULLs outboost_timevalues older than 1970 or more than 10 years in the future.
Tooling
protbotgains--action boostand--action gachafor non-destructive live-server regression testing. Usegacha --roll --gacha-id <id>to actually exerciseMSG_MHF_PLAY_NORMAL_GACHA.
Upgrade notes
Fresh build or pull the Docker image, restart the server. Migrations run automatically on startup. No config changes required.
Full changelog: v9.3.1...v9.3.2