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

3.2 KiB

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:
    [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:
    [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.