fix login issues
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -22,4 +22,7 @@ odinsea-*.tar
|
|||||||
# Temporary files, for example, from tests.
|
# Temporary files, for example, from tests.
|
||||||
/tmp/
|
/tmp/
|
||||||
|
|
||||||
/.elixir_ls
|
/.elixir_ls
|
||||||
|
|
||||||
|
/*.md
|
||||||
|
!/README.md
|
||||||
|
|||||||
@@ -1,433 +0,0 @@
|
|||||||
# Java TODOs Analysis for Odinsea Elixir Port
|
|
||||||
|
|
||||||
**Analysis Date:** 2026-02-14
|
|
||||||
**Java Source:** `/home/ra/lucid/src`
|
|
||||||
**Elixir Target:** `/home/ra/odinsea-elixir`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Total TODOs/FIXMEs/XXXs found in Java source: **87+**
|
|
||||||
|
|
||||||
After analysis, these fall into several categories:
|
|
||||||
1. **Critical Gameplay TODOs** - Missing functionality that affects core gameplay
|
|
||||||
2. **Version/Region-Specific TODOs** (TODO JUMP/GMS) - Code branches for different versions
|
|
||||||
3. **LEGEND TODOs** - High-level content/skills not fully implemented
|
|
||||||
4. **Low-Priority TODOs** - Nice-to-have features, optimizations, or minor fixes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Critical TODOs Requiring Port to Elixir
|
|
||||||
|
|
||||||
### 1. Energy Charge Bar Decay (MapleCharacter.java:3034)
|
|
||||||
|
|
||||||
**Java Location:** `src/client/MapleCharacter.java:3034`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/character.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
// TODO: bar going down
|
|
||||||
if (energyLevel < 10000) {
|
|
||||||
energyLevel += (echeff.getX() * targets);
|
|
||||||
// ... energy charge handling
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** The energy charge system for characters (like Aran) doesn't implement the energy bar decay over time. Currently energy only increases with attacks but doesn't decrease when not attacking.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Add energy charge decay timer in Character GenServer
|
|
||||||
- Decay energy when not attacking for X seconds
|
|
||||||
- Update client with energy bar changes
|
|
||||||
|
|
||||||
**Priority:** HIGH - Affects Aran and similar class gameplay
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. Party Quest Stats Tracking (MapleCharacter.java:7115)
|
|
||||||
|
|
||||||
**Java Location:** `src/client/MapleCharacter.java:7115`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/character.ex` (party quest stats)
|
|
||||||
|
|
||||||
```java
|
|
||||||
// TODO: gvup, vic, lose, draw, VR
|
|
||||||
public boolean startPartyQuest(final int questid) {
|
|
||||||
// ... quest initialization with stats
|
|
||||||
updateInfoQuest(questid, "min=0;sec=0;date=0000-00-00;have=0;rank=F;try=0;cmp=0;CR=0;VR=0;gvup=0;vic=0;lose=0;draw=0");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Party quest statistics (victories, losses, draws, VR rating) are stored but not calculated or updated.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Track PQ completion stats
|
|
||||||
- Calculate VR (Victory Rating)
|
|
||||||
- Implement gvup (give up?) tracking
|
|
||||||
|
|
||||||
**Priority:** MEDIUM - Nice for PQ ranking but not blocking
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. Player Movement Validation (PlayerHandler.java:1207)
|
|
||||||
|
|
||||||
**Java Location:** `src/handling/channel/handler/PlayerHandler.java:1207`
|
|
||||||
**Elixir Target:** `lib/odinsea/channel/handler/player.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
if (res != null && c.getPlayer().getMap() != null) { // TODO more validation of input data
|
|
||||||
if (packet.length() < 11 || packet.length() > 26) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Movement packet validation is minimal. Need more comprehensive validation to prevent speed hacking and teleport exploits.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Validate movement distances against character speed stats
|
|
||||||
- Check for impossible position changes
|
|
||||||
- Validate foothold transitions
|
|
||||||
|
|
||||||
**Priority:** HIGH - Security/anti-cheat concern
|
|
||||||
|
|
||||||
**Note:** Elixir already has `Odinsea.Game.Movement` with validation - verify it covers these cases.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. Party Invitation Pending Storage (PartyHandler.java:159)
|
|
||||||
|
|
||||||
**Java Location:** `src/handling/channel/handler/PartyHandler.java:159`
|
|
||||||
**Elixir Target:** `lib/odinsea/world/party.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
// TODO store pending invitations and check against them
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Party invitations are not tracked, allowing potential exploits or duplicate invitations.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Store pending party invitations in ETS or GenServer state
|
|
||||||
- Validate accept/deny against pending list
|
|
||||||
- Add expiration for pending invites
|
|
||||||
|
|
||||||
**Priority:** MEDIUM - Prevents invitation spam/exploits
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. Summon Damage Validation (SummonHandler.java:226)
|
|
||||||
|
|
||||||
**Java Location:** `src/handling/channel/handler/SummonHandler.java:226`
|
|
||||||
**Elixir Target:** `lib/odinsea/channel/handler/summon.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
// TODO : Check player's stat for damage checking.
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Summon damage lacks proper validation against player stats, allowing potential damage hacking.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Validate summon damage against calculated max damage
|
|
||||||
- Apply same anti-cheat checks as player attacks
|
|
||||||
|
|
||||||
**Priority:** HIGH - Security/anti-cheat concern
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6. Multi-Summon BuffStat Handling (SummonHandler.java:260)
|
|
||||||
|
|
||||||
**Java Location:** `src/handling/channel/handler/SummonHandler.java:260`
|
|
||||||
**Elixir Target:** `lib/odinsea/channel/handler/summon.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
//TODO: Multi Summoning, must do something about hack buffstat
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** When a player has multiple summons, buff stat handling needs refinement to prevent exploits.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Track multiple active summons per player
|
|
||||||
- Handle buff stat stacking correctly
|
|
||||||
|
|
||||||
**Priority:** MEDIUM - Affects Mechanic and similar multi-summon classes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 7. NPC Repair Price Calculation (NPCHandler.java:467)
|
|
||||||
|
|
||||||
**Java Location:** `src/handling/channel/handler/NPCHandler.java:467`
|
|
||||||
**Elixir Target:** `lib/odinsea/channel/handler/npc.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
//TODO: need more data on calculating off client
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Equipment durability repair prices may not match client calculations.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Verify repair price formula matches client
|
|
||||||
- Ensure consistent pricing across server/client
|
|
||||||
|
|
||||||
**Priority:** LOW - Minor economic issue
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 8. Monster Revive Spawn Effect (MapleMap.java:1503)
|
|
||||||
|
|
||||||
**Java Location:** `src/server/maps/MapleMap.java:1503`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/map.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
c.sendPacket(MobPacket.spawnMonster(monster, monster.getStats().getSummonType() <= 1 ? -3 : monster.getStats().getSummonType(), oid)); // TODO effect
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Monster revive spawning doesn't show the proper spawn effect.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Send proper spawn effect packet when monsters revive
|
|
||||||
- Match visual effect to summon type
|
|
||||||
|
|
||||||
**Priority:** LOW - Visual polish only
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 9. Monster Party EXP Distribution (MapleMonster.java:1712)
|
|
||||||
|
|
||||||
**Java Location:** `src/server/life/MapleMonster.java:1712`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/monster.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
// TODO actually this causes wrong behaviour when the party changes between attacks
|
|
||||||
// only the last setup will get exp - but otherwise we'd have to store the full party
|
|
||||||
// constellation for every attack/everytime it changes, might be wanted/needed in the
|
|
||||||
// future but not now
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** When party composition changes during combat, EXP distribution may be unfair.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Store party snapshot at time of attack
|
|
||||||
- Distribute EXP based on party composition at attack time, not kill time
|
|
||||||
|
|
||||||
**Priority:** MEDIUM - Fairness issue in party play
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 10. Speed Run Rank Calculation (MapleMap.java:3244)
|
|
||||||
|
|
||||||
**Java Location:** `src/server/maps/MapleMap.java:3244`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/map.ex` (speed run feature)
|
|
||||||
|
|
||||||
```java
|
|
||||||
//TODO revamp
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Speed run ranking calculation needs improvement to properly track rankings.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Implement proper speed run leaderboard ranking
|
|
||||||
- Cache rank information efficiently
|
|
||||||
|
|
||||||
**Priority:** LOW - Feature enhancement
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 11. Anti-Cheat Attack Timing (CheatTracker.java:96,117)
|
|
||||||
|
|
||||||
**Java Location:** `src/client/anticheat/CheatTracker.java:96,117`
|
|
||||||
**Elixir Target:** `lib/odinsea/anticheat.ex` or `lib/odinsea/anticheat/monitor.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
if (Server_ClientAtkTickDiff - STime_TC > 1000) { // 250 is the ping, TODO
|
|
||||||
// ...
|
|
||||||
if (STime_TC < AtkDelay) { // 250 is the ping, TODO
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Anti-cheat ping buffer is hardcoded at 250ms but should be dynamic per-player.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Track per-player average ping
|
|
||||||
- Adjust attack timing thresholds based on actual latency
|
|
||||||
|
|
||||||
**Priority:** MEDIUM - Reduces false positives for laggy players
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 12. Death Bug - Player Spawn (MapleStatEffect.java:1296)
|
|
||||||
|
|
||||||
**Java Location:** `src/server/MapleStatEffect.java:1296`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/stat_effect.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
applyto.setMoveAction(0); //TODO fix death bug, player doesnt spawn on other screen
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** When a player is resurrected, they may not appear correctly on other players' screens.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Fix spawn broadcast packet for resurrected players
|
|
||||||
- Ensure proper visibility state sync
|
|
||||||
|
|
||||||
**Priority:** HIGH - Affects gameplay visibility
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 13. UnifiedDB Character Deletion Cleanup (UnifiedDB.java:168,177,188)
|
|
||||||
|
|
||||||
**Java Location:** `src/service/UnifiedDB.java:168,177,188`
|
|
||||||
**Elixir Target:** `lib/odinsea/database/context.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
World.Guild.deleteGuildCharacter(nGuildId, nCharId); // TODO: Write method for this
|
|
||||||
pFamily.leaveFamily(nCharId); // TODO: Write method for this
|
|
||||||
pSidekick.eraseToDB(); // TODO: Write method for this
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Character deletion doesn't properly clean up guild, family, and sidekick associations.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Implement `delete_guild_character/2` in Guild service
|
|
||||||
- Implement `leave_family/2` for character deletion case
|
|
||||||
- Implement sidekick cleanup
|
|
||||||
|
|
||||||
**Priority:** HIGH - Data integrity issue
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 14. Mini-Game Score Formula (MapleMiniGame.java:276)
|
|
||||||
|
|
||||||
**Java Location:** `src/server/shops/MapleMiniGame.java:276`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/mini_game.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
public int getScore(MapleCharacter chr) {
|
|
||||||
//TODO: Fix formula
|
|
||||||
int score = 2000;
|
|
||||||
// ... basic calculation
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Mini-game (Omok/Match Card) scoring formula is placeholder.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Implement proper ELO or ranking formula
|
|
||||||
- Balance win/loss/tie point values
|
|
||||||
|
|
||||||
**Priority:** LOW - Mini-games are side content
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 15. Mini-Game Record Points (MapleMiniGame.java:297)
|
|
||||||
|
|
||||||
**Java Location:** `src/server/shops/MapleMiniGame.java:297`
|
|
||||||
**Elixir Target:** `lib/odinsea/game/mini_game.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
//TODO: record points
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Mini-game points are not persisted to database.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Add mini-game stats table
|
|
||||||
- Persist wins/losses/ties
|
|
||||||
|
|
||||||
**Priority:** LOW - Mini-games are side content
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 16. Family Splitting Logic (MapleFamily.java:690)
|
|
||||||
|
|
||||||
**Java Location:** `src/handling/world/family/MapleFamily.java:690`
|
|
||||||
**Elixir Target:** `lib/odinsea/world/family.ex`
|
|
||||||
|
|
||||||
```java
|
|
||||||
// TODO: MapleFamily: If errors persist, consider no handling family splitting
|
|
||||||
// inside the check of whether the family should be disbanded,
|
|
||||||
// and instead handle it in the caller after this function returns.
|
|
||||||
```
|
|
||||||
|
|
||||||
**Description:** Family splitting logic during disband check may cause issues.
|
|
||||||
|
|
||||||
**Implementation Needed:**
|
|
||||||
- Review family splitting algorithm
|
|
||||||
- Consider moving logic to caller
|
|
||||||
|
|
||||||
**Priority:** MEDIUM - Stability improvement
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Version-Specific TODOs (TODO JUMP / TODO LEGEND)
|
|
||||||
|
|
||||||
These TODOs indicate code that needs adjustment for different MapleStory versions (GMS vs SEA) or LEGEND content.
|
|
||||||
|
|
||||||
### TODO JUMP Items
|
|
||||||
- `ClientPacket.java:218` - Version-specific opcode handling
|
|
||||||
- `LoopbackPacket.java:345` - Version-specific packet format
|
|
||||||
- `MapleStatEffect.java:573,664,1014,1035,2323` - Version-specific skill behavior
|
|
||||||
- `PlayerHandler.java:365` - Version-specific movement
|
|
||||||
- `PartyHandler.java:31,235` - Version-specific party actions
|
|
||||||
- `InventoryHandler.java:1603` - Version-specific mount handling
|
|
||||||
- `MobPacket.java:399,420,474` - Version-specific monster packets
|
|
||||||
- `PacketHelper.java:371` - Version-specific character encoding
|
|
||||||
- `MaplePacketCreator.java:146,1243,1290,1330,1370,1941,2635,2652,5497,5511,5660` - Version-specific packets
|
|
||||||
|
|
||||||
### TODO LEGEND Items
|
|
||||||
- `ReactorActionManager.java:257` - Harvesting system (LEGEND profession system)
|
|
||||||
- `LoginInformationProvider.java:125` - LEGEND-specific login info
|
|
||||||
- `PlayerStats.java:947,2554` - LEGEND class skills (Demon Slayer, etc.)
|
|
||||||
- `MapleStatEffect.java:727,881` - Mercedes and other LEGEND skills
|
|
||||||
|
|
||||||
**Priority Assessment:** These should be deferred until base GMS v342 is fully stable.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## TODOs Already Implemented in Elixir
|
|
||||||
|
|
||||||
Based on PORT_PROGRESS.md, these Java TODOs appear to be already addressed:
|
|
||||||
|
|
||||||
1. **Movement System** - Elixir has comprehensive `Odinsea.Game.Movement` with validation
|
|
||||||
2. **Combat/Damage** - Elixir has `Odinsea.Game.DamageCalc` and `Odinsea.Game.AttackInfo`
|
|
||||||
3. **Drop System** - Elixir has `Odinsea.Game.DropSystem` fully implemented
|
|
||||||
4. **Quest System** - Elixir has complete quest implementation
|
|
||||||
5. **Skill System** - Elixir has `Odinsea.Game.Skill` and `Odinsea.Game.StatEffect`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Port Priority Matrix
|
|
||||||
|
|
||||||
| Priority | Count | Description |
|
|
||||||
|----------|-------|-------------|
|
|
||||||
| **CRITICAL** | 4 | Data integrity, security exploits, game-breaking bugs |
|
|
||||||
| **HIGH** | 3 | Core gameplay features, anti-cheat, visibility |
|
|
||||||
| **MEDIUM** | 6 | Fairness, stability, feature completeness |
|
|
||||||
| **LOW** | 10+ | Visual polish, side content, optimizations |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Recommended Implementation Order
|
|
||||||
|
|
||||||
### Phase 1: Critical Fixes
|
|
||||||
1. ✅ UnifiedDB character deletion cleanup (Guild/Family/Sidekick)
|
|
||||||
2. ✅ Death bug - player spawn on resurrection
|
|
||||||
3. ✅ Summon damage validation
|
|
||||||
4. ✅ Movement validation enhancement
|
|
||||||
|
|
||||||
### Phase 2: Core Features
|
|
||||||
5. ✅ Energy charge bar decay
|
|
||||||
6. ✅ Monster party EXP distribution fix
|
|
||||||
7. ✅ Party invitation tracking
|
|
||||||
8. ✅ Anti-cheat ping adjustment
|
|
||||||
|
|
||||||
### Phase 3: Polish
|
|
||||||
9. Mini-game improvements
|
|
||||||
10. Speed run ranking
|
|
||||||
11. Visual effects (monster spawn)
|
|
||||||
12. Version-specific content (TODO JUMP/LEGEND)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- The Elixir port has excellent coverage of core systems (movement, combat, drops, quests)
|
|
||||||
- Most critical TODOs are around data integrity (character deletion) and anti-cheat
|
|
||||||
- Version-specific TODOs (TODO JUMP/LEGEND) should be deferred
|
|
||||||
- Several TODOs in Java are minor visual/economic issues that can be addressed later
|
|
||||||
3205
PORT_PROGRESS.md
3205
PORT_PROGRESS.md
File diff suppressed because it is too large
Load Diff
@@ -1,397 +0,0 @@
|
|||||||
# WZ Data Export Utility Guide
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The Elixir port uses JSON files for game data instead of parsing WZ files directly. This document describes how to create a Java utility to export WZ data to JSON format.
|
|
||||||
|
|
||||||
## Required Exports
|
|
||||||
|
|
||||||
### 1. Item Strings (`priv/data/item_strings.json`)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"2000000": "Red Potion",
|
|
||||||
"2000001": "Orange Potion",
|
|
||||||
"1002000": "Blue Bandana",
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Java Source:**
|
|
||||||
```java
|
|
||||||
// Use MapleItemInformationProvider
|
|
||||||
// Iterate over all items, extract names from String.wz
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Items (`priv/data/items.json`)
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"item_id": 2000000,
|
|
||||||
"name": "Red Potion",
|
|
||||||
"slot_max": 100,
|
|
||||||
"price": 50.0,
|
|
||||||
"whole_price": 50,
|
|
||||||
"req_level": 0,
|
|
||||||
"tradeable": true,
|
|
||||||
"cash": false,
|
|
||||||
"recover_hp": 50,
|
|
||||||
"recover_mp": 0
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fields to Export:**
|
|
||||||
- item_id, name, desc
|
|
||||||
- slot_max, price, whole_price
|
|
||||||
- req_level, req_job, req_str, req_dex, req_int, req_luk
|
|
||||||
- cash, tradeable, quest, time_limited
|
|
||||||
- recover_hp, recover_mp, buff_time
|
|
||||||
- meso, monster_book, mob_id
|
|
||||||
- All flags and properties
|
|
||||||
|
|
||||||
**Java Source:**
|
|
||||||
```java
|
|
||||||
// MapleItemInformationProvider.getAllItems()
|
|
||||||
// Convert ItemInformation to JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Equipment (`priv/data/equips.json`)
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"item_id": 1002000,
|
|
||||||
"str": 0,
|
|
||||||
"dex": 0,
|
|
||||||
"int": 0,
|
|
||||||
"luk": 0,
|
|
||||||
"hp": 0,
|
|
||||||
"mp": 0,
|
|
||||||
"watk": 0,
|
|
||||||
"matk": 0,
|
|
||||||
"wdef": 5,
|
|
||||||
"mdef": 5,
|
|
||||||
"acc": 0,
|
|
||||||
"avoid": 0,
|
|
||||||
"speed": 0,
|
|
||||||
"jump": 0,
|
|
||||||
"slots": 7,
|
|
||||||
"tuc": 7,
|
|
||||||
"item_level": 1
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fields to Export:**
|
|
||||||
- All stat fields (str, dex, int, luk, hp, mp)
|
|
||||||
- Attack/defense (watk, matk, wdef, mdef)
|
|
||||||
- Accuracy/avoidance (acc, avoid)
|
|
||||||
- Movement (speed, jump)
|
|
||||||
- Upgrade slots (slots, tuc)
|
|
||||||
- All equipment properties
|
|
||||||
|
|
||||||
**Java Source:**
|
|
||||||
```java
|
|
||||||
// MapleItemInformationProvider.getAllItems()
|
|
||||||
// Filter by MapleInventoryType.EQUIP
|
|
||||||
// Extract equip stats
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Monsters (`priv/data/monsters.json`)
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"mob_id": 100100,
|
|
||||||
"name": "Blue Snail",
|
|
||||||
"level": 1,
|
|
||||||
"hp": 50,
|
|
||||||
"mp": 0,
|
|
||||||
"exp": 3,
|
|
||||||
"physical_attack": 8,
|
|
||||||
"magic_attack": 8,
|
|
||||||
"physical_defense": 10,
|
|
||||||
"magic_defense": 10,
|
|
||||||
"accuracy": 5,
|
|
||||||
"evasion": 3,
|
|
||||||
"speed": 50,
|
|
||||||
"boss": false,
|
|
||||||
"undead": false,
|
|
||||||
"flying": false,
|
|
||||||
"skills": [],
|
|
||||||
"revives": []
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fields to Export:**
|
|
||||||
- All stats from MapleMonsterStats
|
|
||||||
- Behavioral flags (boss, undead, flying, friendly, etc.)
|
|
||||||
- Skills, revives
|
|
||||||
- All combat properties
|
|
||||||
|
|
||||||
**Java Source:**
|
|
||||||
```java
|
|
||||||
// MapleLifeFactory.getAllMonster()
|
|
||||||
// Convert MapleMonsterStats to JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. NPCs (`priv/data/npcs.json`)
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"npc_id": 1012000,
|
|
||||||
"name": "Athena Pierce",
|
|
||||||
"has_shop": false,
|
|
||||||
"shop_id": null,
|
|
||||||
"script": null
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Java Source:**
|
|
||||||
```java
|
|
||||||
// MapleLifeFactory.getAllNPC()
|
|
||||||
// MapleNPC.npcShopIDs for shop data
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Maps (`priv/data/maps.json`)
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"map_id": 100000000,
|
|
||||||
"map_name": "Henesys",
|
|
||||||
"street_name": "Victoria Island",
|
|
||||||
"return_map": 100000000,
|
|
||||||
"forced_return": 100000000,
|
|
||||||
"mob_rate": 1.0,
|
|
||||||
"field_limit": 0,
|
|
||||||
"time_limit": -1,
|
|
||||||
"bgm": "Bgm04/PlayWithMe",
|
|
||||||
"portals": [
|
|
||||||
{
|
|
||||||
"id": 0,
|
|
||||||
"name": "sp",
|
|
||||||
"type": "sp",
|
|
||||||
"x": -1283,
|
|
||||||
"y": 86,
|
|
||||||
"target_map": 999999999,
|
|
||||||
"target_portal": "",
|
|
||||||
"script": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "market00",
|
|
||||||
"type": "pv",
|
|
||||||
"x": -1183,
|
|
||||||
"y": 86,
|
|
||||||
"target_map": 910000000,
|
|
||||||
"target_portal": "market01",
|
|
||||||
"script": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"footholds": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"x1": -1400,
|
|
||||||
"y1": 120,
|
|
||||||
"x2": -1200,
|
|
||||||
"y2": 120,
|
|
||||||
"prev": 0,
|
|
||||||
"next": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"top": -400,
|
|
||||||
"bottom": 300,
|
|
||||||
"left": -1600,
|
|
||||||
"right": 1200
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fields to Export:**
|
|
||||||
- Map metadata (id, name, street_name)
|
|
||||||
- Return maps (return_map, forced_return)
|
|
||||||
- Rates (mob_rate, recovery_rate)
|
|
||||||
- Limits (field_limit, time_limit)
|
|
||||||
- All portals with full data
|
|
||||||
- All footholds with connections
|
|
||||||
- Bounds (top, bottom, left, right)
|
|
||||||
- BGM, scripts, properties
|
|
||||||
|
|
||||||
**Java Source:**
|
|
||||||
```java
|
|
||||||
// MapleMapFactory.loadAllFieldTemplates()
|
|
||||||
// FieldTemplate contains all data
|
|
||||||
// Extract portals from MaplePortal
|
|
||||||
// Extract footholds from MapleFootholdTree
|
|
||||||
```
|
|
||||||
|
|
||||||
## Implementation Guide
|
|
||||||
|
|
||||||
### Create Export Utility Class
|
|
||||||
|
|
||||||
```java
|
|
||||||
package tools;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import server.*;
|
|
||||||
import server.life.*;
|
|
||||||
import server.maps.*;
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.file.*;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class WZExporter {
|
|
||||||
|
|
||||||
private static final Gson gson = new GsonBuilder()
|
|
||||||
.setPrettyPrinting()
|
|
||||||
.create();
|
|
||||||
|
|
||||||
private static final String OUTPUT_DIR = "../odinsea-elixir/priv/data/";
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
System.out.println("Starting WZ data export...");
|
|
||||||
|
|
||||||
exportItemStrings();
|
|
||||||
exportItems();
|
|
||||||
exportEquips();
|
|
||||||
exportMonsters();
|
|
||||||
exportNPCs();
|
|
||||||
exportMaps();
|
|
||||||
|
|
||||||
System.out.println("Export complete!");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void exportItemStrings() {
|
|
||||||
// Implementation here
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void exportItems() {
|
|
||||||
// Implementation here
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... other export methods
|
|
||||||
|
|
||||||
private static void writeJson(String filename, Object data) {
|
|
||||||
try {
|
|
||||||
Path path = Paths.get(OUTPUT_DIR + filename);
|
|
||||||
Files.createDirectories(path.getParent());
|
|
||||||
|
|
||||||
String json = gson.toJson(data);
|
|
||||||
Files.write(path, json.getBytes());
|
|
||||||
|
|
||||||
System.out.println("Wrote: " + filename);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Run Export
|
|
||||||
|
|
||||||
1. Add WZExporter.java to Java project
|
|
||||||
2. Ensure all providers are loaded (items, maps, life)
|
|
||||||
3. Run: `java tools.WZExporter`
|
|
||||||
4. Check output in `../odinsea-elixir/priv/data/`
|
|
||||||
5. Verify JSON files are valid
|
|
||||||
6. Test in Elixir by reloading data providers
|
|
||||||
|
|
||||||
## Data Validation
|
|
||||||
|
|
||||||
After export, validate data:
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
# In Elixir IEx console
|
|
||||||
Odinsea.Game.ItemInfo.reload()
|
|
||||||
Odinsea.Game.MapFactory.reload()
|
|
||||||
Odinsea.Game.LifeFactory.reload()
|
|
||||||
|
|
||||||
# Check counts
|
|
||||||
:ets.info(:odinsea_item_cache, :size) # Should be 10000+
|
|
||||||
:ets.info(:odinsea_map_templates, :size) # Should be 1000+
|
|
||||||
:ets.info(:odinsea_monster_stats, :size) # Should be 5000+
|
|
||||||
|
|
||||||
# Test lookups
|
|
||||||
Odinsea.Game.ItemInfo.get_name(2000000) # "Red Potion"
|
|
||||||
Odinsea.Game.MapFactory.get_map_name(100000000) # "Henesys"
|
|
||||||
Odinsea.Game.LifeFactory.get_monster_name(100100) # "Blue Snail"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Performance Considerations
|
|
||||||
|
|
||||||
- Export can take 5-10 minutes for full WZ data
|
|
||||||
- JSON files will be 50-100MB total
|
|
||||||
- Consider compressing (gzip) for distribution
|
|
||||||
- ETS loading takes <1 second with JSON
|
|
||||||
- Memory usage: ~100MB for all cached data
|
|
||||||
|
|
||||||
## Incremental Export
|
|
||||||
|
|
||||||
For development, export subsets:
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Export only common maps
|
|
||||||
if (mapId < 110000000 && mapId >= 100000000) {
|
|
||||||
exportMap(mapId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export only beginner monsters
|
|
||||||
if (mobId < 9999999 && level <= 30) {
|
|
||||||
exportMonster(mobId);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
**Problem:** JSON parsing fails in Elixir
|
|
||||||
- Check JSON syntax with `jq` or online validator
|
|
||||||
- Ensure UTF-8 encoding
|
|
||||||
- Check for special characters in names
|
|
||||||
|
|
||||||
**Problem:** Missing data in exports
|
|
||||||
- Verify Java providers are fully initialized
|
|
||||||
- Check for null values
|
|
||||||
- Add default values in Java export code
|
|
||||||
|
|
||||||
**Problem:** Export crashes or hangs
|
|
||||||
- Add try/catch around each item
|
|
||||||
- Log progress every 100 items
|
|
||||||
- Export in smaller batches
|
|
||||||
|
|
||||||
## Future Improvements
|
|
||||||
|
|
||||||
1. **Incremental Updates**
|
|
||||||
- Track WZ file changes
|
|
||||||
- Only export modified data
|
|
||||||
- Generate diff files
|
|
||||||
|
|
||||||
2. **Validation**
|
|
||||||
- Schema validation
|
|
||||||
- Referential integrity checks
|
|
||||||
- Detect missing required fields
|
|
||||||
|
|
||||||
3. **Compression**
|
|
||||||
- GZIP JSON files
|
|
||||||
- Binary format (MessagePack)
|
|
||||||
- Reduce file sizes 80%
|
|
||||||
|
|
||||||
4. **Automation**
|
|
||||||
- CI/CD integration
|
|
||||||
- Auto-export on WZ updates
|
|
||||||
- Version tracking
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Next Step:** Create `WZExporter.java` in Java project and run export!
|
|
||||||
Reference in New Issue
Block a user