Files
test/Documentation/FLASHMOVE_PROTOCOL_COMPARISON.md
2026-03-13 16:03:47 +07:00

79 lines
3.2 KiB
Markdown

# Flash Move Skill Protocol Comparison: C++ vs C#
## Summary
**Both C++ and C# send the same command ID (89) for CAST_POS_SKILL**, but they use different protocol wrappers.
## C++ Implementation
### Log Evidence (EC.log)
```
[17:10:03.501] [FLASH_SKILL_PROTOCOL] c2s_SendCmdCastPosSkill: Sending protocol C2S::CAST_POS_SKILL (command ID=89), skillID=58, pos=(858.33, 60.93, -149.44), byPVPMask=0, targetCount=0
[17:10:03.501] [FLASH_SKILL_PROTOCOL] c2s_SendCmdCastPosSkill: Protocol packet size=20 bytes
[17:10:03.501] CLIENT - CAST_POS_SKILL(89)
```
### Code Location
- **File:** `EC_SendC2SCmds.cpp`
- **Function:** `c2s_SendCmdCastPosSkill()` (line 1030-1068)
- **Protocol:** Sends `C2S::CAST_POS_SKILL` directly as protocol command
- **Command ID:** 89 (from enum `C2S::CAST_POS_SKILL`)
- **Packet Structure:**
```cpp
[cmd_header] + [cmd_cast_pos_skill]
- cmd_header.cmd = C2S::CAST_POS_SKILL (89)
- cmd_cast_pos_skill contains: skill_id, pos, force_attack, target_count, targets[]
```
## C# Implementation
### Log Evidence (SessionLog)
```
[16:58:15.286] [DISTANCE_DEBUG] CastSkill: Before sending c2s_CmdCastPosSkill (flashmove self), skillID=58, hostPos=(860.71, 59.59, -130.28), destPos=(860.62, 60.73, -145.39), flashDistance=16.00, byPVPMask=0
[16:58:15.286] [GameSession] Sending protocol: gamedatasend (Type: PROTOCOL_GAMEDATASEND) + Type=34 - CMD_ID: CAST_POS_SKILL
```
### Code Location
- **File:** `C2SCommand.cs`
- **Enum:** `CommandID.CAST_POS_SKILL = 89` (line 118)
- **Protocol:** Wraps command in `PROTOCOL_GAMEDATASEND` (Type=34)
- **Command ID:** 89 (stored in first 2 bytes of Data field)
- **Packet Structure:**
```csharp
[PROTOCOL_GAMEDATASEND header] + [Data field]
- Protocol Type = 34 (PROTOCOL_GAMEDATASEND)
- Data[0-1] = CommandID.CAST_POS_SKILL (89) as ushort
- Data[2+] = CMD_CastPosSkill structure (skillId, pos, pvpMask, targetCount, targets[])
```
## Key Differences
| Aspect | C++ | C# |
|--------|-----|-----|
| **Protocol Type** | Direct command (89) | Wrapped in PROTOCOL_GAMEDATASEND (34) |
| **Command ID** | 89 (C2S::CAST_POS_SKILL) | 89 (CommandID.CAST_POS_SKILL) |
| **Packet Structure** | `[cmd_header][cmd_cast_pos_skill]` | `[PROTOCOL_GAMEDATASEND][Data with CMD_ID][CMD_CastPosSkill]` |
| **Packet Size** | 20 bytes (for skillID=58, no targets) | Larger (includes PROTOCOL_GAMEDATASEND wrapper) |
## Conclusion
✅ **The command ID is the same (89)** in both implementations.
⚠️ **The protocol wrapper is different:**
- **C++** sends the command directly as protocol 89
- **C#** wraps it in `PROTOCOL_GAMEDATASEND` (34) and puts the command ID (89) in the Data field
This is a **protocol architecture difference**, not a bug. The C# implementation uses a unified `GameDataSend` protocol that wraps all game commands, while the C++ implementation sends commands directly. The server should handle both formats correctly if it recognizes:
1. Direct protocol 89 (C++ style)
2. Protocol 34 with command ID 89 in the data (C# style)
## Verification
Both logs show:
- **Skill ID:** 58 (same flash move skill)
- **Command ID:** 89 (CAST_POS_SKILL)
- **Position data:** Present in both
- **PVP Mask:** 0 in both
- **Target Count:** 0 in both
The actual command data is **identical**; only the protocol wrapper differs.