Commit Graph

1035 Commits

Author SHA1 Message Date
Houmgaor
0d07a1f698 refactor(mhfpacket): rename 15 Unk fields with identified meanings
Replace unknown field names with descriptive names based on handler
logic analysis, switch dispatch patterns, DB query context, and
inline comments:

- ObjectHandleID, IsQuest, ItemIDCount, MaxCount, TokenLength,
  FormatVersion, LogoutType (high confidence from comments/constants)
- QueryType, DataType, MissionIndex, CheckOnly, RequestType,
  ExchangeType, TournamentID (confirmed by handler switch/if usage)

Also fix MsgSysLogout.Build calling ReadUint8 instead of WriteUint8.
2026-02-18 21:48:08 +01:00
Houmgaor
2bd5f98f32 docs: add doc.go files and godoc comments to all packages
Add package-level documentation (doc.go) to all 22 first-party
packages and godoc comments to ~150 previously undocumented
exported symbols across common/, network/, and server/.
2026-02-18 21:39:13 +01:00
Houmgaor
b9cb274ced refactor(festa): rename reward fields Unk5/6/7 to MinHR/MinSR/MinGR
Ghidra decompilation of hf_gp_main in the Wii U binary revealed that
these three fields are reward eligibility thresholds checked against
the player's Hunter Rank, max Skill Rank, and G Rank respectively.
2026-02-18 21:35:55 +01:00
Houmgaor
c34f682f70 fix(festa): correct reward field version gate from G1 to G3
The extra reward fields (Unk5, Unk6, Unk7) in the InfoFesta response
were gated at >= G1, but G1 clients do not expect these 5 extra bytes
per reward entry. This caused the entire packet after the rewards
section to be misaligned, corrupting MaximumFP, leaderboards, and
bonus rates — which broke the festa UI including trial voting.

Wii U disassembly of import_festa_info (0x02C470EC, 1068 bytes)
confirms G3-Z2 reads these fields. G1 binary analysis shows only
8 festa packets (vs 12 in ZZ), and the intermediate/personal prize
systems were not added until G5.2/G7 respectively.
2026-02-18 20:59:58 +01:00
Houmgaor
3e4f3a3bc6 chore(api): remove unused test helpers
Remove MockDB, NewTestAPIServer, CleanupTestData, and
GetTestDBConnection — all flagged as unreachable by deadcode.
2026-02-18 20:52:18 +01:00
Houmgaor
9e8dc034be refactor(channelserver): split handlers.go into goocoo, scenario, and misc files
Replace the grab-bag handlers.go with thematically organized files:
- handlers_goocoo.go: Goocoo/Guacot pet handlers
- handlers_scenario.go: Scenario counter struct and handler
- handlers_misc.go: remaining unrelated handlers (etc points, earth,
  equip skin history, trend weapons, minidata, lobby crowd, etc.)
2026-02-18 19:42:59 +01:00
Houmgaor
e5802a053e refactor(channelserver): extract CharacterSaveData model into model_character.go
Move SavePointer type/constants, CharacterSaveData struct, getPointers,
Compress, Decompress, and save data serialization methods out of
handlers_character.go into a dedicated model file.
2026-02-18 19:40:33 +01:00
Houmgaor
264b0ced6b refactor(channelserver): extract Raviente struct and methods into raviente.go
Consolidate Raviente-related code from sys_channel_server.go and
handlers_register.go into a dedicated file for better organization.
2026-02-18 19:38:22 +01:00
Houmgaor
ed2a9597f2 refactor(channelserver): extract guild model, chat commands, and seibattle
Split three large files into focused modules:
- handlers_guild.go: extract types/ORM into guild_model.go
- handlers_cast_binary.go: extract command parser into handlers_commands.go
- handlers.go: move seibattle types/handlers into handlers_seibattle.go
2026-02-18 18:24:36 +01:00
Houmgaor
3f5651209d refactor(channelserver): split handlers_shop_gacha.go into shop and gacha
Separate the two distinct systems into focused files:
- handlers_shop.go: item shops, exchange shops, frontier point trading
- handlers_gacha.go: normal/stepup/box/free gacha, coin management
2026-02-18 18:17:21 +01:00
Houmgaor
433de4e21d fix(rengoku): prevent Sky Corridor race condition from wiping skill data (#85)
The client's Sky Corridor area transition handler saves rengoku data
before the load response is parsed into the character data area,
producing saves with zeroed skill fields but preserved point totals.

Detect this pattern server-side and merge existing skill data from the
database. Also reject sentinel-zero saves when valid data already exists.
2026-02-18 18:10:34 +01:00
Houmgaor
cc7883b8a1 refactor(channelserver): split handlers.go into sub-files
Extract from the 1638-line catch-all handlers.go into focused files:
- handlers_helpers.go: shared doAck* helpers and updateRights
- handlers_session.go: login/logout, save, system protocol handlers
- handlers_items.go: items, prices, stamps, stampcard
- handlers.go: remaining misc handlers (goocoo, earth, seibattle, etc.)
2026-02-18 17:59:15 +01:00
Houmgaor
a2609e26a0 fix: resolve 4 pre-existing test failures in channelserver
- Guard nil listener/acceptConns in Server.Shutdown() to prevent panic
  in test servers that don't bind a network listener
- Remove redundant userBinaryPartsLock in TestHandleMsgMhfLoaddata that
  caused a deadlock with handleMsgMhfLoaddata's own lock acquisition
- Increase test save blob size from 200 to 150000 bytes to accommodate
  ZZ save pointer offsets (up to 146728)
- Initialize MHFEquipment.Sigils[].Effects slices in test data to
  prevent index-out-of-range panic in SerializeWarehouseEquipment
- Insert warehouse row before updating it (UPDATE on 0 rows is not an
  error, so the INSERT fallback never triggered)
- Use COALESCE for nullable kouryou_point column in kill counter test
- Fix duplicate-add test expectation (CSV helper correctly deduplicates)
2026-02-18 15:59:36 +01:00
Houmgaor
898ada3d99 fix(api): prevent path traversal in ScreenShot endpoint
Anchor the token regex to ^[A-Za-z0-9]+$ so partial matches on
traversal strings like "../../etc/passwd" are rejected. Refactor
the handler to use early returns so execution stops immediately
on validation failure instead of falling through to os.Create
with tainted input.
2026-02-18 14:10:45 +01:00
Houmgaor
9832f68f1c fix: soft-delete guild posts instead of hard-deleting
Use a `deleted` boolean column (matching characters and mail tables)
instead of permanently removing guild_posts rows. This makes excess
post purging and manual deletion reversible.
2026-02-18 13:57:49 +01:00
Houmgaor
e353906e1c refactor(channelserver): split handlers_data.go into sub-files
Separate the 1,580-line handlers_data.go into three focused files:
- handlers_data.go (~210 lines): character save/load handlers
- handlers_data_paper.go (~616 lines): tower/paper types and handler
- handlers_data_paper_tables.go (~765 lines): paperGiftData reward map

Mirrors the earlier handlers_guild.go split pattern.
2026-02-18 00:47:14 +01:00
Houmgaor
35665a46d8 refactor(channelserver): split handlers_guild.go into sub-files
handlers_guild.go was 2090 lines mixing unrelated guild subsystems.
Extract handlers into focused files following the existing pattern:

- handlers_guild_ops.go: OperateGuild switch + member operations
- handlers_guild_info.go: InfoGuild + EnumerateGuild display
- handlers_guild_mission.go: guild mission system
- handlers_guild_cooking.go: meals, weekly bonus, hunt data
- handlers_guild_board.go: message board system

Core types, methods, and DB functions remain in handlers_guild.go
(now ~1000 lines).
2026-02-18 00:19:11 +01:00
Houmgaor
c64dabc3ba fix: check all Close() return values for errcheck lint
Add explicit error discards (_ =) for Close() calls on network
connections, SQL rows, and file handles across 28 files. Also add
.golangci.yml with standard linter defaults to match CI configuration.
2026-02-17 23:57:14 +01:00
Houmgaor
47f7a1f636 fix(channelserver): handle bare Exec errors and filter expected ErrNoRows
138 bare db.Exec calls across 22 handler files silently dropped write
errors. Each is now wrapped with error check and zap logging.

4 QueryRow sites that legitimately return sql.ErrNoRows during normal
operation (new player mezfes, festa rankings, empty guild item box)
now filter it out to reduce log noise.
2026-02-17 23:33:44 +01:00
Houmgaor
88fc17e790 fix: purge excess guild posts and clarify alliance TODO
Purge oldest guild posts beyond the limit (100 messages, 4 news) after
each new post is created. Replace misleading alliance application TODO
with a note that the feature is not yet implemented.
2026-02-17 18:12:07 +01:00
Houmgaor
46bbb6adf9 fix: resolve all remaining lint errors (errcheck) across 49 files
Fix unchecked error returns on bf.Seek(), db.Exec(), QueryRow().Scan(),
pkt.Build(), logger.Sync(), and binary.Write() calls. The linter now
passes with 0 errors, build compiles, and all tests pass with -race.
2026-02-17 18:07:38 +01:00
Houmgaor
2a0e3e2c84 fix: re-enable CI lint job and fix ~65 lint errors (partial)
Re-enable the golangci-lint job in CI (disabled Oct 2025), update to
Go 1.25 and golangci-lint-action v7. Fix errcheck, gosimple S1009,
staticcheck SA4031 and SA2001 errors across 54 files. Remaining ~39
lint errors will be addressed in follow-up commits.
2026-02-17 17:59:00 +01:00
Houmgaor
d2b5bb72f8 refactor: extract gametime package, replace fmt.Printf with zap logging
Move time utilities (TimeAdjusted, TimeMidnight, TimeWeekStart, TimeWeekNext,
TimeGameAbsolute) from channelserver into common/gametime to break the
inappropriate dependency where signserver, entranceserver, and api imported
the 38K-line channelserver package just for time functions.

Replace all fmt.Printf debug logging in sys_session.go and handlers_object.go
with structured zap logging for consistent observability.
2026-02-17 17:54:51 +01:00
Houmgaor
fb3e86f429 fix: handle Query/QueryRow/transaction errors in channel server handlers
Add error checking and logging for ~25 database call sites that were
silently dropping errors, preventing resource leaks (unclosed rows),
nil pointer panics, and silent data corruption in festa transactions.
2026-02-17 17:44:35 +01:00
Houmgaor
645c4ddd38 test: increase code coverage from 45.1% to 48.3%
Add unit tests across multiple packages:
- byteframe: SetBE/SetLE byte order switching
- config: Mode.String() for all safe version ranges
- mhfpacket: 28 Parse methods, 5 Build methods, empty packet builds,
  variable-length packets, NOT IMPLEMENTED error paths, UpdateWarehouse
- network: PacketID.String() for known IDs, out-of-range, and all valid
- channelserver: handleMsgMhfGetPaperData (6 switch cases), grpToGR
  (11 input values), gacha handlers, TimeGameAbsolute, equipSkinHistSize
  (4 config branches), guild mission handlers, dumpSaveData disabled path
- entranceserver: makeHeader with various inputs
2026-02-17 17:32:54 +01:00
Houmgaor
85cdac036e fix: validate quest file existence in seasonConversion fallbacks
The final fallback in seasonConversion blindly constructed a filename
without checking if it existed on disk. When the file was missing,
handleMsgSysGetFile would send doAckBufFail, but the original Frontier
client does not gracefully handle this during quest loading — causing a
softlock instead of showing the built-in error dialog.

Now every fallback path validates file existence before returning, and
also tries the opposite time-of-day variant as a last resort. If no
file variant exists at all, the original filename is returned with a
warning log so the failure ack is still sent.
2026-02-17 01:19:26 +01:00
Houmgaor
0bd724f74e test: backport remaining test files from v9.2.x-stable
Import 18 network packet test files and 5 server infrastructure test
files, adapted for main branch APIs: fix config import alias (_config),
remove non-existent DevMode field, use global handlerTable instead of
per-server handlers map, and correct validateToken mock expectations
to include both token and tokenID arguments.

Adds go-sqlmock dependency for database mocking in signserver tests.
2026-02-17 00:09:41 +01:00
Houmgaor
be4cd2001c test: import 38 channelserver test files from v9.2.x-stable
Port test files from v9.2.x-stable branch to increase channelserver
coverage from 13.8% to 25.6% (556 tests passing).

Adapted all files to main's struct definitions: config import alias,
Airou/CatDefinition rename, packet field mismatches, Raviente struct
differences, and maxPlayers defaults. Removed tests referencing
production code not yet on main (Player, FestivalColour, etc.).
Excluded handlers_register_test.go (Raviente completely redesigned).
2026-02-16 22:19:44 +01:00
Houmgaor
b1c8b2848f security: fix CodeQL warnings for integer overflow and workflow permissions
- handlers_tower.go: add bounds checks before int-to-int16 and int-to-uint16
  conversions to prevent overflow/wraparound (CodeQL #7, #8)
- go-improved.yml, go.yml: add top-level `permissions: contents: read` to
  restrict workflow token scope (CodeQL #15, #16, #17)
2026-02-16 19:14:14 +01:00
Houmgaor
10e09630a6 fix: send failure ack for missing quest/scenario files instead of crashing client
When a quest or scenario file was missing, handleMsgSysGetFile sent nil
data via doAckBufSucceed, which crashed the game client. Now sends
doAckBufFail so the client can handle the missing file gracefully.

Closes #109
2026-02-16 18:35:44 +01:00
Houmgaor
7dfc3e6049 Merge upstream/main into main
Resolve conflict in handlers_stage.go: keep lock-free packet
building pattern (copy session list, release lock, then build)
over upstream's in-lock QueueSendMHF approach.

Fix test compilation: remove objectIDs field references after
upstream removed it from Server struct.

Resync vendor directory with updated go.mod dependencies.
2026-02-16 11:31:42 +01:00
wish
e9bd0b2ddb Merge pull request #151 from Mezeporta/test/aobp 2025-12-17 09:27:56 +11:00
Houmgaor
0fac429fac fix(transmog): fix transmog issues.
Untested commit.
2025-11-09 11:57:28 +01:00
Houmgaor
36065ce273 fix(plate data): was not save, nor transmog data. 2025-11-01 18:14:30 +01:00
Houmgaor
3da54fade8 chore: adds remaining logging for Hunter Navi and Plate data. 2025-11-01 17:14:05 +01:00
Houmgaor
afc554f1ec fix(save): avoid double-save.
feat(logging): more complete logging data.
2025-11-01 00:37:59 +01:00
Houmgaor
18592c5ded fix(handlers): trying to fix issues with incomplete saves. 2025-10-31 13:10:17 +01:00
Houmgaor
2d3edcfd10 test: session lifecycle tests to reveal issues with sessions configuration. 2025-10-31 12:59:32 +01:00
Houmgaor
d3fd0c72b0 tests: extra tests for Dicord bit and nullcomp. 2025-10-27 12:33:33 +01:00
Houmgaor
25d218fbcd tests(integration): more complete tests with integration of a test database, 2025-10-27 11:58:12 +01:00
Houmgaor
e1a461e892 fix(stage): fix deadlock that was preventing stage change. 2025-10-27 01:13:43 +01:00
Houmgaor
5aa17a749f test(api): comprehensive test suite for server/api. 2025-10-21 01:09:37 +02:00
Houmgaor
73e874f43f fix: array bound crashes on clans. 2025-10-21 00:21:50 +02:00
Houmgaor
060635e422 fix(stage): fix race condition with stages. 2025-10-21 00:00:08 +02:00
Houmgaor
1c32be98cc fix(session): race condition. 2025-10-19 23:49:23 +02:00
Houmgaor
4908731773 fix(ci): remove linting, fix not passing test. 2025-10-19 23:39:23 +02:00
Houmgaor
c55f23442b fix(lint): fixing go static check failing. 2025-10-19 22:52:58 +02:00
Houmgaor
fc6e479df9 fix(lint): fixing more complex formatters problems. 2025-10-19 22:46:21 +02:00
Houmgaor
1398383a8d fix(lint): automated linting, with simple formatter. 2025-10-19 22:43:05 +02:00
Houmgaor
f79e05c0c9 feat(go): upgrade from go 1.21 to 1.23
BREAKING CHANGE: will not work properly with Go 1.21.
2025-10-19 22:24:48 +02:00