mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-23 16:13:04 +01:00
docs(conquest): document Conquest War RE status and implementation gaps
The feature/conquest branch drifted too far from develop without completing the core gameplay loop. This doc captures all known packet wire formats, handler states, confirmed values from captures, and a prioritised table of unknowns needed before the feature can be implemented cleanly. Also updates unimplemented.md to link to the new reference.
This commit is contained in:
514
docs/conquest-war.md
Normal file
514
docs/conquest-war.md
Normal file
@@ -0,0 +1,514 @@
|
||||
# Conquest War (討伐征戦 / Seibatsu)
|
||||
|
||||
Tracks what is known about the Conquest War event system and what remains to be
|
||||
reverse-engineered before it can be fully implemented in Erupe.
|
||||
|
||||
The `feature/conquest` branch (origin) attempted a partial implementation but drifted too far
|
||||
from `develop` without completing the core gameplay loop and is not mergeable in its current
|
||||
state. Its findings are incorporated below.
|
||||
|
||||
---
|
||||
|
||||
## Game Context
|
||||
|
||||
**Conquest War** (討伐征戦, also called *Seibatsu*) is a weekly rotating time-limited event
|
||||
introduced in the G2 update (July 2013). Players hunt legendary monsters and race to level them
|
||||
up on a per-player leaderboard.
|
||||
|
||||
The event follows a **three-week, three-phase cycle** tracked server-side as the "Earth" system:
|
||||
|
||||
| Week | Phase | Japanese | Description |
|
||||
|------|-------|----------|-------------|
|
||||
| 1 | **Conquest (Seibatsu)** | 討伐征戦 | Hunting phase — players level their monsters |
|
||||
| 2 | **Pallone Festival** | パローネ祭典 | Side festival event concurrent with conquest rewards |
|
||||
| 3 | **Tower (Dure)** | 塔 | Tower climbing event for additional rewards |
|
||||
|
||||
### Conquest Mechanics
|
||||
|
||||
- Each player has their own independent monster (not shared with others).
|
||||
- Players hunt their own monster or join quests at the same or higher level.
|
||||
- A monster starts at level 1 and caps at **9999**.
|
||||
- Level gain per hunt: **+5** (no faints), **+3** (one faint), **+1** (multiple faints).
|
||||
- As the monster levels, its stats scale up, making each subsequent hunt harder.
|
||||
- At week end, rewards are distributed based on the player's rank on the per-monster
|
||||
leaderboard.
|
||||
|
||||
### Target Monsters (configurable)
|
||||
|
||||
The live service used **Shantien**, **Disufiroa**, **G-Rank Black Fatalis**, and
|
||||
**G-Rank Crimson Fatalis**. The branch defaults to monster IDs `[116, 107, 2, 36]`
|
||||
(Deviljho, Rajang, Rathalos, Gore Magala — suitable for G8 and below, where the original
|
||||
four are not available).
|
||||
|
||||
For clients at `RealClientMode <= G8`, only the first 3 monsters are exposed; G9+ exposes 4.
|
||||
|
||||
### Reward Distribution Types
|
||||
|
||||
The `DistributionType` field in reward packets uses these sentinel values:
|
||||
|
||||
| Value | Meaning |
|
||||
|-------|---------|
|
||||
| `7201` | Item reward (ItemID + quantity) |
|
||||
| `7202` | N-Points (currency) |
|
||||
| `7203` | Guild contribution points |
|
||||
|
||||
---
|
||||
|
||||
## Packet Overview
|
||||
|
||||
Thirteen packets implement the Conquest/Earth system. All live in `network/mhfpacket/`.
|
||||
None have `Build()` implemented (all return `NOT IMPLEMENTED`) — responses are built
|
||||
directly in handler code using `byteframe`.
|
||||
|
||||
### `MsgMhfGetEarthStatus` — Client → Server → Client
|
||||
|
||||
Fetches the current Earth event windows and which monsters are active.
|
||||
|
||||
**Request** (`msg_mhf_get_earth_status.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32 — unknown; never used by handler
|
||||
Unk1 uint32 — unknown; never used by handler
|
||||
```
|
||||
|
||||
**Response** (built in `handlers_earth.go → handleMsgMhfGetEarthStatus`):
|
||||
```
|
||||
for each active earth event (up to 3: Conquest, Pallone, Tower):
|
||||
[uint32] StartTime — Unix timestamp
|
||||
[uint32] EndTime — Unix timestamp
|
||||
[int32] StatusID — 1 or 2 (Conquest); 11 (Pallone active) or 12 (Pallone reward); 21 (Tower)
|
||||
[int32] EarthID — unique event ID from DB row
|
||||
[int32] MonsterID × N — active conquest monsters (3 for G8, 4 for G9+)
|
||||
```
|
||||
|
||||
**Status ID semantics**: the difference between `1` and `2` for the Conquest phase is not
|
||||
known. The branch selects `1` when the hunt week is active and `2` otherwise, but this is
|
||||
a guess.
|
||||
|
||||
**Current state**: Implemented. Event windows are generated from a single `events` table row
|
||||
(`event_type = 'earth'`). A 21-day rolling cycle is computed from that row's `start_time`.
|
||||
Debug mode (`EarthDebug = true`) collapses the windows to week boundaries for faster testing.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfGetEarthValue` — Client → Server → Client
|
||||
|
||||
Fetches numeric values associated with the current Earth event (kill counts, floor tallies,
|
||||
special flags).
|
||||
|
||||
**Request** (`msg_mhf_get_earth_value.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32 — unknown
|
||||
Unk1 uint32 — unknown
|
||||
ReqType uint32 — 1, 2, or 3 (see below)
|
||||
Unk3–Unk6 uint32 — unknown; never used by handler
|
||||
```
|
||||
|
||||
**Response**: a variable-length array of 6-uint32 entries, wrapped in `doAckEarthSucceed`.
|
||||
Each entry: `[ID, Value, Unk, Unk, Unk, Unk]`. The last four fields are always zero in
|
||||
known captures.
|
||||
|
||||
| ReqType | Known entries | Notes |
|
||||
|---------|--------------|-------|
|
||||
| 1 | `{1, 100}`, `{2, 100}` | Block + DureSlays count — exact meaning unclear |
|
||||
| 2 | `{1, 5771}`, `{2, 1847}` | Block + Floors? — "Floors?" is a guess |
|
||||
| 3 | `{1001, 36}` getTouhaHistory; `{9001, 3}` getKohouhinDropStopFlag; `{9002, 10, 300}` getKohouhinForceValue | `ttcSetDisableFlag` relationship unknown |
|
||||
|
||||
**Current state**: Implemented with hardcoded values. No database persistence.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfReadBeatLevel` — Client → Server → Client
|
||||
|
||||
Reads the player's current conquest beat levels (monster progress values) from the server.
|
||||
|
||||
**Request** (`msg_mhf_read_beat_level.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32 — always 1 in the JP client (hardcoded literal)
|
||||
ValidIDCount uint32 — always 4 in the JP client
|
||||
IDs [16]uint32 — always [0x74, 0x6B, 0x02, 0x24, 0, 0, ...] (hardcoded)
|
||||
```
|
||||
|
||||
**Response**: `ValidIDCount` entries of `[ID uint32, Value uint32, 0 uint32, 0 uint32]`.
|
||||
Default value if no DB data: `{0,1, 0,1, 0,1, 0,1}` (level 1 for each slot).
|
||||
|
||||
**Current state**: Fully implemented. Beat levels are read from `characters.conquest_data`
|
||||
(16-byte BYTEA). Defaults to level 1 if the column is NULL.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfUpdateBeatLevel` — Client → Server → Client
|
||||
|
||||
Saves the player's updated conquest beat levels after a quest.
|
||||
|
||||
**Request** (`msg_mhf_update_beat_level.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk1 uint32 — unknown
|
||||
Unk2 uint32 — unknown
|
||||
Data1 [16]int32 — unknown purpose; entirely discarded by the handler
|
||||
Data2 [16]int32 — beat level data; only first 4 values are stored
|
||||
```
|
||||
|
||||
**Response**: `{0x00, 0x00, 0x00, 0x00}`.
|
||||
|
||||
**Current state**: Implemented, but incomplete. Only `Data2[0..3]` is written to the DB.
|
||||
`Data1` and `Data2[4..15]` are silently ignored. `Unk1`/`Unk2` purposes are unknown.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfReadBeatLevelAllRanking` — Client → Server → Client
|
||||
|
||||
Fetches the global leaderboard for a given monster.
|
||||
|
||||
**Request** (`msg_mhf_read_beat_level_all_ranking.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32
|
||||
MonsterID int32 — which monster's ranking to fetch
|
||||
Unk2 int32 — unknown
|
||||
```
|
||||
|
||||
**Response structure** (from known captures):
|
||||
```
|
||||
[uint32] Unk
|
||||
[int32] Unk
|
||||
[int32] Unk
|
||||
for each of 100 entries:
|
||||
[uint32] Rank
|
||||
[uint32] Level
|
||||
[32 bytes] HunterName (null-padded)
|
||||
```
|
||||
|
||||
**Current state**: Stubbed. Returns 100 zero-filled entries. No database ranking data exists.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfReadBeatLevelMyRanking` — Client → Server → Client
|
||||
|
||||
Fetches the player's own rank on the conquest leaderboard.
|
||||
|
||||
**Request** (`msg_mhf_read_beat_level_my_ranking.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32
|
||||
Unk1 uint32
|
||||
Unk2 [16]int32 — unknown; possibly the same ID array as ReadBeatLevel
|
||||
```
|
||||
|
||||
**Current state**: Stubbed. Returns an empty buffer. Response format unknown.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfReadLastWeekBeatRanking` — Client → Server → Client
|
||||
|
||||
Purpose is partially understood: the handler comment says "controls the monster headings for
|
||||
the other menus". Likely provides context for which monster's data to display.
|
||||
|
||||
**Request** (`msg_mhf_read_last_week_beat_ranking.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32
|
||||
EarthMonster int32
|
||||
```
|
||||
|
||||
**Response** (current stub): `[EarthMonster uint32, 0, 0, 0]`. Actual format unknown.
|
||||
|
||||
**Current state**: Minimal stub. Response structure not reverse-engineered.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfGetBreakSeibatuLevelReward` — Client → Server → Client
|
||||
|
||||
Returns per-monster level-break milestone rewards (items granted at specific level thresholds).
|
||||
|
||||
**Request** (`msg_mhf_get_break_seibatu_level_reward.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32 — unknown; debug-printed but never used
|
||||
EarthMonster int32
|
||||
```
|
||||
|
||||
**Response**: variable-length array of reward entries via `doAckEarthSucceed`:
|
||||
```
|
||||
[int32] ItemID
|
||||
[int32] Quantity
|
||||
[int32] Level — the level threshold at which this reward unlocks
|
||||
[int32] Unk — always 0 in known data
|
||||
```
|
||||
|
||||
**Current state**: Implemented with hardcoded per-monster reward tables. Item IDs were
|
||||
derived from packet captures. No database backend.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfGetWeeklySeibatuRankingReward` — Client → Server → Client
|
||||
|
||||
Returns reward tables for conquest ranking, Pallone Festival routes, and Tower floors.
|
||||
The most complex handler in the branch.
|
||||
|
||||
**Request** (`msg_mhf_get_weekly_seibatu_ranking_reward.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32 — unknown; debug-printed but never used
|
||||
Operation uint32 — 1 = conquest ranking, 3 = Pallone festival, 5 = event rewards
|
||||
ID uint32 — event/route ID (for Op=1: aligns with EarthStatus 1 and 2)
|
||||
EarthMonster uint32
|
||||
```
|
||||
|
||||
**Response format for Operation = 1** (conquest ranking rewards):
|
||||
```
|
||||
per entry:
|
||||
[int32] Unk0
|
||||
[int32] ItemID
|
||||
[uint32] Amount
|
||||
[int32] PlaceFrom
|
||||
[int32] PlaceTo
|
||||
```
|
||||
|
||||
**Response format for Operations 3 and 5** (Pallone/Tower):
|
||||
```
|
||||
per entry:
|
||||
[int32] Index0 — floor number (Op=5) or place rank (Op=3)
|
||||
[int32] Index1
|
||||
[uint32] Index2 — distribution slot (Op=5 tower dure: 1 or 2)
|
||||
[int32] DistributionType — 7201/7202/7203
|
||||
[int32] ItemID
|
||||
[int32] Amount
|
||||
```
|
||||
|
||||
**Current state**: Implemented with hardcoded tables derived from packet captures.
|
||||
- Operation 1: All four monsters return the same bracket table (ranks 1–100, 101–1000,
|
||||
1000–1001). The tables are identical for all monsters — this may be correct, or captures
|
||||
were only recorded for one monster.
|
||||
- Operation 3 (Pallone): 91 entries across 11 routes, all zero-filled — format is known
|
||||
but content is not.
|
||||
- Operation 5 (Tower): Tower dure kill rewards (260001) and 155-entry floor reward table
|
||||
(260003, floors 1–1500) are hardcoded from captures.
|
||||
|
||||
Note in source: "Can only have 10 in each dist" — the maximum entries per distribution slot
|
||||
before the client discards them is 10.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfGetFixedSeibatuRankingTable` — Client → Server → Client
|
||||
|
||||
Returns a static "fixed" leaderboard (likely a seeded/display ranking, not live player data).
|
||||
The handler notes this packet is *not* triggered when `EarthStatus == 1`, suggesting it
|
||||
belongs to the reward-week display rather than the hunt-week display.
|
||||
|
||||
**Request** (`msg_mhf_get_fixed_seibatu_ranking_table.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint32 — unknown
|
||||
Unk1 int32 — unknown
|
||||
EarthMonster int32
|
||||
Unk3 int32 — unknown
|
||||
Unk4 int32 — unknown
|
||||
```
|
||||
|
||||
**Response**: up to 9 entries:
|
||||
```
|
||||
[int32] Rank
|
||||
[int32] Level
|
||||
[32 bytes] HunterName (null-padded)
|
||||
```
|
||||
|
||||
**Current state**: Implemented with 9 hardcoded "Hunter N" placeholder entries per monster.
|
||||
`Unk1`, `Unk3`, `Unk4` purposes unknown.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfGetSeibattle` — Client → Server → Client
|
||||
|
||||
Fetches Seibattle (guild-vs-guild battle) data. The `GuildID` field suggests this is
|
||||
guild-specific, but the handler ignores it entirely.
|
||||
|
||||
**Request** (`msg_mhf_get_seibattle.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint8
|
||||
Type uint8 — 1=timetable, 3=key score, 4=career, 5=opponent, 6=convention result,
|
||||
7=char score, 8=cur result
|
||||
GuildID uint32
|
||||
Unk3 uint8 — unknown
|
||||
Unk4 uint16 — unknown
|
||||
```
|
||||
|
||||
**Response**: varies by `Type`. Timetable (Type=1) returns 3 eight-hour battle windows
|
||||
computed from midnight. All other types return zero-filled structs.
|
||||
|
||||
**Current state**: Stubbed. No database queries, no guild-specific data. The seibattle
|
||||
guild-vs-guild combat system is entirely unimplemented.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfPostSeibattle` — Client → Server → Client
|
||||
|
||||
Submits a seibattle result. All fields are unknown.
|
||||
|
||||
**Request** (`msg_mhf_post_seibattle.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0 uint8
|
||||
Unk1 uint8
|
||||
Unk2 uint32
|
||||
Unk3 uint8
|
||||
Unk4 uint16
|
||||
Unk5 uint16
|
||||
Unk6 uint8
|
||||
```
|
||||
|
||||
**Current state**: Stubbed. Returns `{0,0,0,0}`. No data is read or persisted.
|
||||
|
||||
---
|
||||
|
||||
### `MsgMhfGetAdditionalBeatReward` — Client → Server → Client
|
||||
|
||||
Purpose unclear. The handler comment states: *"Actual responses in packet captures are all
|
||||
just giant batches of null bytes. I'm assuming this is because it used to be tied to an
|
||||
actual event that no longer triggers in the client."*
|
||||
|
||||
**Request** (`msg_mhf_get_additional_beat_reward.go`):
|
||||
```
|
||||
AckHandle uint32
|
||||
Unk0–Unk3 uint32 — all unknown
|
||||
```
|
||||
|
||||
**Current state**: Returns 260 (`0x104`) zero bytes. Whether real responses were ever
|
||||
non-zero is unknown.
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
The branch adds two migrations:
|
||||
|
||||
```sql
|
||||
-- schemas/patch-schema/23-earth.sql
|
||||
ALTER TYPE event_type ADD VALUE 'earth';
|
||||
|
||||
-- schemas/patch-schema/24-conquest.sql
|
||||
ALTER TABLE public.characters ADD COLUMN IF NOT EXISTS conquest_data BYTEA;
|
||||
```
|
||||
|
||||
And seeds four conquest quests (`schemas/bundled-schema/ConquestQuests.sql`):
|
||||
quest IDs `54257`, `54258`, `54277`, `54370` — all `quest_type = 33`, `max_players = 0`.
|
||||
|
||||
**Missing tables** required for a full implementation:
|
||||
|
||||
| Table | Purpose |
|
||||
|-------|---------|
|
||||
| `conquest_rankings` | Per-player, per-monster beat level leaderboard |
|
||||
| `conquest_reward_claims` | Track which level-break and ranking rewards have been claimed |
|
||||
| `seibattle_scores` | Guild seibattle results and career records |
|
||||
| `seibattle_schedules` | Persistent timetable (currently computed in memory) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
Two keys were added to `config.go` / `config.json` by the branch:
|
||||
|
||||
| Key | Type | Default | Purpose |
|
||||
|-----|------|---------|---------|
|
||||
| `EarthDebug` | bool | `false` | Collapses event windows to week boundaries for testing |
|
||||
| `EarthMonsters` | []int32 | `[116, 107, 2, 36]` | Active conquest target monster IDs |
|
||||
|
||||
---
|
||||
|
||||
## What Is Already Understood
|
||||
|
||||
- The three-phase Earth event cycle (Conquest → Pallone → Tower) and its 21-day rolling
|
||||
window, keyed to a single `events` row.
|
||||
- `GetEarthStatus` response wire format: per-phase `[Start, End, StatusID, EarthID, MonsterIDs…]`.
|
||||
- `ReadBeatLevel` request is fully hardcoded by the JP client (IDs `0x74, 0x6B, 0x02, 0x24`);
|
||||
no dynamic ID resolution is needed.
|
||||
- Per-character beat level storage: 4 × int32, 16 bytes, in `characters.conquest_data`.
|
||||
- Level-break reward item IDs and quantities for monsters 116, 107, 2, 36 (from captures).
|
||||
- Weekly ranking reward brackets for conquest (ranks 1–100, 101–1000, 1000–1001).
|
||||
- Tower floor reward table (floors 1–1500, item IDs and quantities from captures).
|
||||
- Tower dure kill reward distributions (dist 1 and 2, from captures).
|
||||
- `GetWeeklySeibatuRankingReward` response wire format for all three operations.
|
||||
- `GetFixedSeibatuRankingTable` response wire format (rank + level + 32-byte name).
|
||||
- `GetBreakSeibatuLevelReward` response wire format (ItemID + Quantity + Level + Unk).
|
||||
- Distribution type sentinels: `7201` = item, `7202` = N-Points, `7203` = guild contribution.
|
||||
- The 10-entry-per-distribution-slot limit in weekly seibatu ranking rewards.
|
||||
- `GetSeibattle` timetable format: 3 × 8-hour windows from midnight.
|
||||
- Conquest quest IDs: `54257`, `54258`, `54277`, `54370` (type 33).
|
||||
|
||||
---
|
||||
|
||||
## What Needs RE Before Full Implementation
|
||||
|
||||
### High Priority — blocks any functional gameplay
|
||||
|
||||
| Unknown | Where to look | Notes |
|
||||
|---------|---------------|-------|
|
||||
| Semantics of `EarthStatus` IDs 1 vs 2 | Packet captures during hunt week vs reward week | Currently guessed; wrong selection may break phase detection |
|
||||
| `MsgMhfUpdateBeatLevel.Data1[16]` | Captures with known quest outcome | Second int32 array entirely discarded; may carry the level gain delta |
|
||||
| `MsgMhfUpdateBeatLevel.Unk1 / Unk2` | Same captures | May carry monster ID or quest ID needed for routing |
|
||||
| `ReadBeatLevelAllRanking` response structure | Captures from an active leaderboard | Header fields (3 × uint32 before the 100 entries) unknown |
|
||||
| `ReadBeatLevelMyRanking` response structure | Same | Format entirely unknown; returns empty today |
|
||||
| `ReadLastWeekBeatRanking` full response | Captures after week rollover | Only monster ID echoed back today |
|
||||
|
||||
### Medium Priority — required for accurate reward flow
|
||||
|
||||
| Unknown | Where to look | Notes |
|
||||
|---------|---------------|-------|
|
||||
| `MsgMhfPostSeibattle` all fields (`Unk0–Unk6`) | Captures after a seibattle result | Handler does nothing today; this is the score submission path |
|
||||
| `GetSeibattle` types 3–8 response formats | Captures for each `Type` value | Currently all return zero structs |
|
||||
| `GetSeibattle.Unk0 / Unk3 / Unk4` | Same captures | Likely context selectors for guild/season |
|
||||
| `GetEarthValue.Unk0 / Unk1 / Unk3–Unk6` | Captures across different event phases | 6 of the 8 request fields are unknown |
|
||||
| `GetEarthStatus.Unk0 / Unk1` | Captures across phases | Never used by the handler; may be version or session flags |
|
||||
| `GetWeeklySeibatuRankingReward` Op=3 content | Captures during Pallone Festival | 91 entries are zero-filled placeholders |
|
||||
| Claim tracking semantics | Compare reward endpoint with gacha claim flow | No "claimed" flag exists anywhere in the schema |
|
||||
|
||||
### Low Priority — cosmetic / completeness
|
||||
|
||||
| Unknown | Where to look | Notes |
|
||||
|---------|---------------|-------|
|
||||
| `GetFixedSeibatuRankingTable.Unk1 / Unk3 / Unk4` | Captures | Likely unused alignment or version fields |
|
||||
| `GetBreakSeibatuLevelReward.Unk0` | Captures with different monsters | Debug-printed; may be season or event ID |
|
||||
| `ReadBeatLevelAllRanking.Unk0 / Unk2` | Captures | Likely pagination or season selectors |
|
||||
| `GetAdditionalBeatReward` full structure | Captures if the packet is ever non-null | May be permanently dead in the last client version |
|
||||
| Pallone Festival route semantics | JP wiki / community guides | 11 routes × 13 entries, all content unknown |
|
||||
| Original live-service event scheduling cadence | JP wiki archives | Cycle length and reset time not publicly documented |
|
||||
|
||||
---
|
||||
|
||||
## Relation to Other Systems
|
||||
|
||||
**Gacha service** (`svc_gacha.go`): The reward distribution model (distribution type,
|
||||
item ID, amount, rank brackets) is structurally similar to the gacha reward pipeline.
|
||||
Conquest reward claiming can likely reuse or adapt `GachaService.ClaimRewards` and its
|
||||
point transaction infrastructure.
|
||||
|
||||
**Raviente siege** (`sys_channel_server.go`, `handlers_register.go`): Conquest quests may
|
||||
use the same `MsgMhfRegisterEvent` / semaphore pattern for quest slot management, though
|
||||
this has not been confirmed with captures.
|
||||
|
||||
**Tower event** (`feature/tower` branch): The Tower phase is part of the same Earth event
|
||||
cycle. The `GetWeeklySeibatuRankingReward` handler already covers Tower rewards (Op=5).
|
||||
The two branches should be coordinated or merged.
|
||||
|
||||
---
|
||||
|
||||
## Known Code Quality Issues in the Branch
|
||||
|
||||
The following must be fixed before any part of this branch is merged:
|
||||
|
||||
- `fmt.Printf` debug prints left in packet `Parse()` methods:
|
||||
`msg_mhf_get_break_seibatu_level_reward.go`, `msg_mhf_get_weekly_seibatu_ranking_reward.go`,
|
||||
`msg_mhf_get_fixed_seibatu_ranking_table.go`, `msg_mhf_read_last_week_beat_ranking.go`
|
||||
- The `cleanupEarthStatus` function wipes `conquest_data` for all characters on event
|
||||
expiry — this erases history. Completed conquest data should be archived, not deleted.
|
||||
- The branch introduced a large `handlers.go` consolidation file that deleted existing test
|
||||
files (`handlers_achievement_test.go`, `channel_isolation_test.go`, etc.). These must be
|
||||
restored.
|
||||
- DB access in `handlers_earth.go` uses raw `s.server.db` calls instead of the repo pattern.
|
||||
Any merge must route these through `CharacterRepo` and `EventRepo` interfaces.
|
||||
- `EarthMonsters` config currently accepts any IDs; a G9+ client will crash if fewer than 4
|
||||
monsters are configured when `RealClientMode > G8`.
|
||||
@@ -190,7 +190,7 @@ that needs no reply). Others are genuine feature gaps.
|
||||
| Branch | Commits ahead | Handlers targeted |
|
||||
|--------|:---:|-------------------|
|
||||
| `feature/enum-event` | 4 | `EnumerateEvent` scheduling only — not mergeable, see `docs/fort-attack-event.md` |
|
||||
| `feature/conquest` | 4 | Conquest quest handlers |
|
||||
| `feature/conquest` | 4 | Conquest quest handlers — not mergeable, see `docs/conquest-war.md` |
|
||||
| `feature/tower` | 4 | Tower handlers |
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user