From cda1c73bd38aad41f3b0fe62eac2209a593fd8fe Mon Sep 17 00:00:00 2001 From: rtw1x1 Date: Sun, 8 Feb 2026 07:36:07 +0000 Subject: [PATCH] Networking Overhaul: Modern packets, buffers, handshake, dispatch & security hardening See Readme --- README.md | 194 +- src/EffectLib/EffectElementBase.cpp | 29 - src/EffectLib/SimpleLightData.cpp | 28 - src/EterBase/Debug.cpp | 5 +- src/EterBase/SecureCipher.cpp | 61 +- src/EterBase/SecureCipher.h | 16 +- src/EterGrnLib/Material.cpp | 50 - src/EterGrnLib/Mesh.cpp | 28 +- .../ModelInstanceCollisionDetection.cpp | 123 - src/EterGrnLib/ModelInstanceRender.cpp | 106 - src/EterGrnLib/Util.cpp | 43 - src/EterLib/CollisionData.cpp | 79 - src/EterLib/ControlPackets.h | 73 + src/EterLib/Decal.cpp | 45 - src/EterLib/NetDatagram.cpp | 99 - src/EterLib/NetDatagram.h | 28 - src/EterLib/NetDatagramReceiver.cpp | 105 - src/EterLib/NetDatagramReceiver.h | 36 - src/EterLib/NetDatagramSender.cpp | 58 - src/EterLib/NetDatagramSender.h | 27 - src/EterLib/NetPacketHeaderMap.h | 8 +- src/EterLib/NetStream.cpp | 726 +++--- src/EterLib/NetStream.h | 45 +- src/EterLib/PacketReader.h | 157 ++ src/EterLib/PacketWriter.h | 139 + src/EterLib/Profiler.h | 263 -- src/EterLib/RingBuffer.h | 191 ++ src/GameLib/ActorInstance.cpp | 27 - src/GameLib/ActorInstanceData.cpp | 30 - src/GameLib/Area.cpp | 101 - src/GameLib/GameUtil.cpp | 228 +- src/GameLib/MapOutdoor.cpp | 55 - src/GameLib/MapOutdoorQuadtree.cpp | 51 - src/UserInterface/AbstractPlayer.h | 1 - src/UserInterface/AccountConnector.cpp | 159 +- src/UserInterface/AccountConnector.h | 10 +- src/UserInterface/CameraProcedure.cpp | 49 - src/UserInterface/GuildMarkDownloader.cpp | 162 +- src/UserInterface/GuildMarkDownloader.h | 5 +- src/UserInterface/GuildMarkUploader.cpp | 144 +- src/UserInterface/GuildMarkUploader.h | 12 +- src/UserInterface/InstanceBase.cpp | 28 - src/UserInterface/InstanceBase.h | 1 - src/UserInterface/InstanceBaseEffect.cpp | 84 +- src/UserInterface/Packet.h | 1540 +++++------ src/UserInterface/PythonApplication.cpp | 88 - src/UserInterface/PythonApplication.h | 2 - src/UserInterface/PythonMessenger.cpp | 8 - src/UserInterface/PythonMessenger.h | 1 - src/UserInterface/PythonNetworkDatagram.cpp | 213 -- src/UserInterface/PythonNetworkDatagram.h | 58 - .../PythonNetworkDatagramModule.cpp | 29 - src/UserInterface/PythonNetworkStream.cpp | 584 +++-- src/UserInterface/PythonNetworkStream.h | 115 +- .../PythonNetworkStreamCommand.cpp | 14 - .../PythonNetworkStreamModule.cpp | 66 +- .../PythonNetworkStreamPhaseGame.cpp | 2254 +++++++---------- .../PythonNetworkStreamPhaseGameActor.cpp | 2 +- .../PythonNetworkStreamPhaseGameItem.cpp | 114 +- .../PythonNetworkStreamPhaseHandShake.cpp | 180 +- .../PythonNetworkStreamPhaseLoading.cpp | 202 +- .../PythonNetworkStreamPhaseLogin.cpp | 75 +- .../PythonNetworkStreamPhaseOffline.cpp | 15 +- .../PythonNetworkStreamPhaseSelect.cpp | 119 +- src/UserInterface/PythonPlayer.cpp | 15 - src/UserInterface/PythonPlayer.h | 8 - .../PythonPlayerEventHandler.cpp | 5 +- src/UserInterface/PythonPlayerInput.cpp | 89 - src/UserInterface/PythonPlayerModule.cpp | 24 +- src/UserInterface/ServerStateChecker.cpp | 36 +- src/UserInterface/StdAfx.h | 1 - src/UserInterface/UserInterface.cpp | 1 - 72 files changed, 3612 insertions(+), 6155 deletions(-) create mode 100644 src/EterLib/ControlPackets.h delete mode 100644 src/EterLib/NetDatagram.cpp delete mode 100644 src/EterLib/NetDatagram.h delete mode 100644 src/EterLib/NetDatagramReceiver.cpp delete mode 100644 src/EterLib/NetDatagramReceiver.h delete mode 100644 src/EterLib/NetDatagramSender.cpp delete mode 100644 src/EterLib/NetDatagramSender.h create mode 100644 src/EterLib/PacketReader.h create mode 100644 src/EterLib/PacketWriter.h create mode 100644 src/EterLib/RingBuffer.h delete mode 100644 src/UserInterface/PythonNetworkDatagram.cpp delete mode 100644 src/UserInterface/PythonNetworkDatagram.h delete mode 100644 src/UserInterface/PythonNetworkDatagramModule.cpp diff --git a/README.md b/README.md index 06c6af7..385aa8c 100644 --- a/README.md +++ b/README.md @@ -55,13 +55,199 @@ The entire legacy encryption system has been replaced with [libsodium](https://d * **libsodium-based pack encryption** — `PackLib` now uses XChaCha20-Poly1305 for pack file encryption, replacing the legacy Camellia/XTEA system * **Secure key derivation** — Pack encryption keys are derived using `crypto_pwhash` (Argon2id) -
-
+--- + +### Networking Modernization Roadmap + +A 5-phase modernization of the entire client/server networking stack — packet format, buffer management, handshake protocol, connection architecture, and packet dispatching. Every phase is complete and verified on both client and server. --- -
-
+#### Phase 1 — Packet Format + Buffer System + Memory Safety + +Replaced the legacy 1-byte packet headers and raw C-style buffers with a modern, uniform protocol. + +##### What changed +* **2-byte headers + 2-byte length prefix** — All packet types (`CG::`, `GC::`, `GG::`, `GD::`, `DG::`) now use `uint16_t` header + `uint16_t` length. This increases the addressable packet space from 256 to 65,535 unique packet types and enables safe variable-length parsing +* **Namespaced packet headers** — All headers moved from flat `HEADER_CG_*` defines to C++ namespaces: `CG::MOVE`, `GC::PING`, `GG::LOGIN`, `GD::PLAYER_SAVE`, `DG::BOOT`. Subheaders similarly namespaced: `GuildSub::GC::LOGIN`, `ShopSub::CG::BUY`, etc. +* **RAII RingBuffer** — All raw `buffer_t` / `LPBUF` / `new[]`/`delete[]` patterns replaced with a single `RingBuffer` class featuring lazy compaction at 50% read position, exponential growth, and inlined accessors +* **PacketReader / PacketWriter** — Type-safe helpers that wrap buffer access with bounds checking, eliminating raw pointer arithmetic throughout the codebase +* **Sequence system modernized** — Packet sequence tracking retained for debugging but fixed to byte offset 4 (after header + length) +* **SecureCipher** — XChaCha20-Poly1305 stream cipher for all post-handshake traffic (see Encryption section above) + +##### What was removed +* `buffer.h` / `buffer.cpp` (legacy C buffer library) +* All `LPBUF`, `buffer_new()`, `buffer_delete()`, `buffer_read()`, `buffer_write()` calls +* Raw `new[]`/`delete[]` buffer allocations in DESC classes +* 1-byte header constants (`HEADER_CG_*`, `HEADER_GC_*`, etc.) + +##### Why +The legacy 1-byte header system limited the protocol to 256 packet types (already exhausted), raw C buffers had no bounds checking and were prone to buffer overflows, and the flat namespace caused header collisions between subsystems. + +--- + +#### Phase 2 — Modern Buffer System *(merged into Phase 1)* + +All connection types now use `RingBuffer` uniformly. + +##### What changed +* **All DESC types** (`DESC`, `CLIENT_DESC`, `DESC_P2P`) use `RingBuffer` for `m_inputBuffer`, `m_outputBuffer`, and `m_bufferedOutputBuffer` +* **PeerBase** (db layer) ported to `RingBuffer` +* **TEMP_BUFFER** (local utility for building packets) backed by `RingBuffer` + +##### What was removed +* `libthecore/buffer.h` and `libthecore/buffer.cpp` — the entire legacy buffer library + +##### Why +The legacy buffer system used separate implementations across different connection types, had no RAII semantics (manual malloc/free), and offered no protection against buffer overflows. + +--- + +#### Phase 3 — Simplified Handshake + +Replaced the legacy multi-step handshake (4+ round trips with time synchronization and UDP binding) with a streamlined 1.5 round-trip flow. + +##### What changed +* **1.5 round-trip handshake** — Server sends `GC::KEY_CHALLENGE` (with embedded time sync), client responds with `CG::KEY_RESPONSE`, server confirms with `GC::KEY_COMPLETE`. Session is encrypted from that point forward +* **Time sync embedded** — Initial time synchronization folded into `GC::KEY_CHALLENGE`; periodic time sync handled by `GC::PING` / `CG::PONG` +* **Handshake timeout** — 5-second expiry on handshake phase; stale connections are automatically cleaned up in `DestroyClosed()` + +##### What was removed +* **6 dead packet types**: `CG_HANDSHAKE`, `GC_HANDSHAKE`, `CG_TIME_SYNC`, `GC_TIME_SYNC`, `GC_HANDSHAKE_OK`, `GC_BINDUDP` +* **Server functions**: `StartHandshake()`, `SendHandshake()`, `HandshakeProcess()`, `CreateHandshake()`, `FindByHandshake()`, `m_map_handshake` +* **Client functions**: `RecvHandshakePacket()`, `RecvHandshakeOKPacket()`, `m_HandshakeData`, `SendHandshakePacket()` +* ~12 server files and ~10 client files modified + +##### Why +The original handshake required 4+ round trips, included dead UDP binding steps, had no timeout protection (stale connections could linger indefinitely), and the time sync was a separate multi-step sub-protocol that added latency to every new connection. + +--- + +#### Phase 4 — Unified Connection (Client-Side Deduplication) + +Consolidated duplicated connection logic into the base `CNetworkStream` class. + +##### What changed +* **Key exchange** (`RecvKeyChallenge` / `RecvKeyComplete`) moved from 4 separate implementations to `CNetworkStream` base class +* **Ping/pong** (`RecvPingPacket` / `SendPongPacket`) moved from 3 separate implementations to `CNetworkStream` base class +* **CPythonNetworkStream** overrides `RecvKeyChallenge` only for time sync, delegates all crypto to base +* **CGuildMarkDownloader/Uploader** — `RecvKeyCompleteAndLogin` wraps base + sends `CG::MARK_LOGIN` +* **CAccountConnector** — Fixed raw `crypto_aead` bug (now uses base class `cipher.DecryptToken`) +* **Control-plane structs** extracted to `EterLib/ControlPackets.h` (Phase, Ping, Pong, KeyChallenge, KeyResponse, KeyComplete) +* **CGuildMarkUploader** — `m_pbySymbolBuf` migrated from `new[]`/`delete[]` to `std::vector` + +##### What was removed +* ~200 lines of duplicated code across `CAccountConnector`, `CGuildMarkDownloader`, `CGuildMarkUploader`, and `CPythonNetworkStream` + +##### Why +The same key exchange and ping/pong logic was copy-pasted across 3-4 connection subclasses, leading to inconsistent behavior (the `CAccountConnector` had a raw crypto bug), difficult maintenance, and unnecessary code volume. + +--- + +#### Phase 5 — Packet Handler Registration / Dispatcher + +Replaced giant `switch` statements with `std::unordered_map` dispatch tables for O(1) packet routing. + +##### What changed + +**Client:** +* `CPythonNetworkStream` — Phase-specific handler maps for Game, Loading, Login, Select, and Handshake phases +* Registration pattern: `m_gameHandlers[GC::MOVE] = &CPythonNetworkStream::RecvCharacterMovePacket;` +* Dispatch: `DispatchPacket(m_gameHandlers)` — reads header, looks up handler, calls it + +**Server:** +* `CInputMain`, `CInputDead`, `CInputAuth`, `CInputLogin`, `CInputP2P`, `CInputHandshake`, `CInputDB` — all converted to dispatch tables +* `CInputDB` uses 3 template adapters (`DataHandler`, `DescHandler`, `TypedHandler`) + 14 custom adapters for the diverse DB callback signatures + +##### What was removed +* All `switch (header)` blocks across 7 server input processors and 5 client phase handlers +* ~3,000 lines of switch/case boilerplate + +##### Why +The original dispatch used switch statements with 50-100+ cases each. Adding a new packet required modifying a massive switch block, which was error-prone and caused merge conflicts. The table-driven approach enables O(1) lookup, self-documenting handler registration, and trivial addition of new packet types. + +--- + +### Post-Phase 5 Cleanup + +Follow-up tasks after the core roadmap was complete. + +#### One-Liner Adapter Reformat +* 24 adapter methods across 4 server files (`input_main.cpp`, `input_p2p.cpp`, `input_auth.cpp`, `input_login.cpp`) reformatted from single-line to multi-line for readability + +#### MAIN_CHARACTER Packet Merge +* **4 mutually exclusive packets** (`GC::MAIN_CHARACTER`, `MAIN_CHARACTER2_EMPIRE`, `MAIN_CHARACTER3_BGM`, `MAIN_CHARACTER4_BGM_VOL`) merged into a single unified `GC::MAIN_CHARACTER` packet +* Single struct always includes BGM fields (zero when unused — 29 extra bytes on a one-time-per-load packet) +* 4 nearly identical client handlers merged into 1 +* 3 redundant server send paths merged into 1 + +#### UDP Leftover Removal +* **7 client files deleted**: `NetDatagram.h/.cpp`, `NetDatagramReceiver.h/.cpp`, `NetDatagramSender.h/.cpp`, `PythonNetworkDatagramModule.cpp` +* **8 files edited**: Removed dead stubs (`PushUDPState`, `initudp`, `netSetUDPRecvBufferSize`, `netConnectUDP`), declarations, and Python method table entries +* **Server**: Removed `socket_udp_read()`, `socket_udp_bind()`, `__UDP_BLOCK__` define + +#### Subheader Dispatch +* Extended the Phase 5 table-driven pattern to subheader switches with 8+ cases +* **Client**: Guild (19 sub-handlers), Shop (10), Exchange (8) in `PythonNetworkStreamPhaseGame.cpp` +* **Server**: Guild (15 sub-handlers) in `input_main.cpp` +* Small switches intentionally kept as-is: Messenger (5), Fishing (6), Dungeon (2), Server Shop (4) + +--- + +### Performance Audit & Optimization + +Comprehensive audit of all Phase 1-5 changes to identify and eliminate performance overhead. + +#### Debug Logging Cleanup +* **Removed all hot-path `TraceError`/`Tracef`/`sys_log`** from networking code on both client and server +* Client: `NetStream.cpp`, `SecureCipher.cpp`, `PythonNetworkStream*.cpp` — eliminated per-frame and per-packet traces that caused disk I/O every frame +* Server: `desc.cpp`, `input.cpp`, `input_login.cpp`, `input_auth.cpp`, `SecureCipher.cpp` — eliminated `[SEND]`, `[RECV]`, `[CIPHER]` logs that fired on every packet + +#### Packet Processing Throughput +* **`MAX_RECV_COUNT` 4 → 32** — Game phase now processes up to 32 packets per frame (was 4, severely limiting entity spawning on map entry) +* **Loading phase while-loop** — Changed from processing 1 packet per frame to draining all available packets, making phase transitions near-instant + +#### Flood Check Optimization +* **Replaced `get_dword_time()` with `thecore_pulse()`** in `DESC::CheckPacketFlood()` — eliminates a `gettimeofday()` syscall on every single packet received. `thecore_pulse()` is cached once per game-loop iteration + +#### Flood Protection +* **Per-IP connection limits** — Configurable maximum connections per IP address (`flood_max_connections_per_ip`, default: 10) +* **Global connection limits** — Configurable maximum total connections (`flood_max_global_connections`, default: 8192) +* **Per-second packet rate limiting** — Connections exceeding `flood_max_packets_per_sec` (default: 300) are automatically disconnected +* **Handshake timeout** — 5-second expiry prevents connection slot exhaustion from incomplete handshakes + +--- + +### Pre-Phase 3 Cleanup + +Preparatory cleanup performed before the handshake simplification. + +* **File consolidation** — Merged scattered packet definitions into centralized header files +* **Alias removal** — Removed legacy `#define` aliases that mapped old names to new identifiers +* **Monarch system removal** — Completely removed the unused Monarch (emperor) system from both client and server, including all related packets, commands, quest functions, and UI code +* **TrafficProfiler removal** — Removed the `TrafficProfiler` class and all references (unnecessary runtime overhead) +* **Quest management stub removal** — Removed empty `questlua_mgmt.cpp` (monarch-era placeholder with no functions) + +--- + +### Summary of Removed Legacy Systems + +A consolidated reference of all legacy systems, files, and dead code removed across the entire modernization effort. + +| System | What was removed | Replaced by | +|--------|-----------------|-------------| +| **Legacy C buffer** | `buffer.h`, `buffer.cpp`, all `LPBUF`/`buffer_new()`/`buffer_delete()` calls, raw `new[]`/`delete[]` buffer allocations | RAII `RingBuffer` class | +| **1-byte packet headers** | All `HEADER_CG_*`, `HEADER_GC_*`, `HEADER_GG_*`, `HEADER_GD_*`, `HEADER_DG_*` defines | 2-byte namespaced headers (`CG::`, `GC::`, `GG::`, `GD::`, `DG::`) | +| **Old handshake protocol** | 6 packet types (`CG_HANDSHAKE`, `GC_HANDSHAKE`, `CG_TIME_SYNC`, `GC_TIME_SYNC`, `GC_HANDSHAKE_OK`, `GC_BINDUDP`), all handshake functions and state | 1.5 round-trip key exchange (`KEY_CHALLENGE`/`KEY_RESPONSE`/`KEY_COMPLETE`) | +| **UDP networking** | 7 client files (`NetDatagram*.h/.cpp`, `PythonNetworkDatagramModule.cpp`), server `socket_udp_read()`/`socket_udp_bind()`/`__UDP_BLOCK__` | Removed entirely (game is TCP-only) | +| **Old sequence system** | `m_seq`, `SetSequence()`, `GetSequence()`, old sequence variables | Modernized sequence at fixed byte offset 4 | +| **TrafficProfiler** | `TrafficProfiler` class and all references | Removed entirely | +| **Monarch system** | All monarch/emperor packets, commands (`do_monarch_*`), quest functions (`questlua_monarch.cpp`, `questlua_mgmt.cpp`), UI code, GM commands | Removed entirely (unused feature) | +| **Legacy crypto** | Crypto++, Panama cipher, TEA, DH2, Camellia, XTEA, `adwClientKey[4]`, `LSS_SECURITY_KEY` | libsodium (X25519 + XChaCha20-Poly1305) | +| **Switch-based dispatch** | Giant `switch (header)` blocks (50-100+ cases each) across 7 server input processors and 5 client phase handlers | `std::unordered_map` dispatch tables | +| **Duplicated connection code** | Key exchange and ping/pong copy-pasted across 3-4 client subclasses | Consolidated in `CNetworkStream` base class | + +--- # Installation/Configuration This is the third part of the entire project and it's about the client binary, the executable of the game. diff --git a/src/EffectLib/EffectElementBase.cpp b/src/EffectLib/EffectElementBase.cpp index f7da1cf..2fa2641 100644 --- a/src/EffectLib/EffectElementBase.cpp +++ b/src/EffectLib/EffectElementBase.cpp @@ -7,35 +7,6 @@ void CEffectElementBase::GetPosition(float fTime, D3DXVECTOR3 & rPosition) rPosition = GetTimeEventBlendValue(fTime, m_TimeEventTablePosition); } -/* -bool CEffectElementBase::isVisible(float fTime) -{ - for (DWORD i = 0; i < m_TimeEventTableVisible.size(); ++i) - { - float fPointTime = m_TimeEventTableVisible[i]; - - if (fTime < fPointTime) - { - if (1 == i % 2) - return true; - else - return false; - } - } - - return 1 == (m_TimeEventTableVisible.size() % 2); -} - -void CEffectElementBase::GetAlpha(float fTime, float * pAlpha) -{ - GetTimeEventBlendValue(fTime, m_TimeEventAlpha, pAlpha); -} - -void CEffectElementBase::GetScale(float fTime, float * pScale) -{ - GetTimeEventBlendValue(fTime, m_TimeEventScale, pScale); -} -*/ bool CEffectElementBase::isData() { diff --git a/src/EffectLib/SimpleLightData.cpp b/src/EffectLib/SimpleLightData.cpp index 8357111..6994f20 100644 --- a/src/EffectLib/SimpleLightData.cpp +++ b/src/EffectLib/SimpleLightData.cpp @@ -60,34 +60,6 @@ void CLightData::GetRange(float fTime, float& rRange) if (rRange<0.0f) rRange = 0.0f; return; - /* - float vecLastRange = m_TimeEventTableRange[0].m_Value; - - for (DWORD dwIndex = 0; dwIndex < m_TimeEventTableRange.size(); ++dwIndex) - { - if(fTime < m_TimeEventTableRange[dwIndex].m_fTime) - { - break; - } - } - - if (dwIndex >= m_TimeEventTableRange.size()) - { - rRange = m_TimeEventTableRange[m_TimeEventTableRange.size()-1].m_Value * m_fMaxRange; - if (rRange<0.0f) - rRange = 0.0f; - return; - } - - TTimeEventTypeFloat & rEffectRange = m_TimeEventTableRange[dwIndex]; - TTimeEventTypeFloat & rPrevEffectRange = m_TimeEventTableRange[dwIndex-1]; - - float Head = fabs(rEffectRange.m_fTime - fTime) / fabs(rEffectRange.m_fTime - rPrevEffectRange.m_fTime); - float Tail = 1.0f - fabs(rEffectRange.m_fTime - fTime) / fabs(rEffectRange.m_fTime - rPrevEffectRange.m_fTime); - rRange = ((rPrevEffectRange.m_Value*Head) + (rEffectRange.m_Value*Tail) )*m_fMaxRange; - if (rRange<0.0f) - rRange = 0.0f; - */ } bool CLightData::OnIsData() diff --git a/src/EterBase/Debug.cpp b/src/EterBase/Debug.cpp index ef99f7c..a10ecf9 100644 --- a/src/EterBase/Debug.cpp +++ b/src/EterBase/Debug.cpp @@ -345,9 +345,8 @@ static struct TSyserrBuffer memcpy(buffer + pos, msg, len); pos += len; - DWORD now = ELTimer_GetMSec(); - if (now - lastFlushMs > 500 || pos > BUFFER_SIZE * 3 / 4) - Flush(); + // DEBUG: Force flush every write to capture crash traces + Flush(); } void Flush() diff --git a/src/EterBase/SecureCipher.cpp b/src/EterBase/SecureCipher.cpp index 4db474f..6209b3f 100644 --- a/src/EterBase/SecureCipher.cpp +++ b/src/EterBase/SecureCipher.cpp @@ -1,5 +1,6 @@ #include "StdAfx.h" #include "SecureCipher.h" +#include "Debug.h" // Static initialization flag for libsodium static bool s_sodiumInitialized = false; @@ -57,6 +58,7 @@ bool SecureCipher::Initialize() void SecureCipher::CleanUp() { // Securely erase all sensitive key material + sodium_memzero(m_pk, sizeof(m_pk)); sodium_memzero(m_sk, sizeof(m_sk)); sodium_memzero(m_tx_key, sizeof(m_tx_key)); sodium_memzero(m_rx_key, sizeof(m_rx_key)); @@ -95,6 +97,7 @@ bool SecureCipher::ComputeClientKeys(const uint8_t* server_pk) sodium_memzero(m_rx_stream_nonce, NONCE_SIZE); m_rx_stream_nonce[0] = 0x01; + Tracef("[CIPHER] Client keys computed\n"); return true; } @@ -172,64 +175,6 @@ void SecureCipher::ApplyStreamCipher(void* buffer, size_t len, } } -size_t SecureCipher::Encrypt(const void* plaintext, size_t plaintext_len, void* ciphertext) -{ - if (!m_activated) - { - return 0; - } - - // AEAD encryption uses a random nonce (not the stream nonce) - uint8_t nonce[NONCE_SIZE]; - randombytes_buf(nonce, NONCE_SIZE); - - unsigned long long ciphertext_len = 0; - - if (crypto_aead_xchacha20poly1305_ietf_encrypt( - (uint8_t*)ciphertext, &ciphertext_len, - (const uint8_t*)plaintext, plaintext_len, - nullptr, 0, - nullptr, - nonce, - m_tx_key) != 0) - { - return 0; - } - - return (size_t)ciphertext_len; -} - -size_t SecureCipher::Decrypt(const void* ciphertext, size_t ciphertext_len, void* plaintext) -{ - if (!m_activated) - { - return 0; - } - - if (ciphertext_len < TAG_SIZE) - { - return 0; - } - - uint8_t nonce[NONCE_SIZE]; - randombytes_buf(nonce, NONCE_SIZE); - - unsigned long long plaintext_len = 0; - - if (crypto_aead_xchacha20poly1305_ietf_decrypt( - (uint8_t*)plaintext, &plaintext_len, - nullptr, - (const uint8_t*)ciphertext, ciphertext_len, - nullptr, 0, - nonce, - m_rx_key) != 0) - { - return 0; - } - - return (size_t)plaintext_len; -} - void SecureCipher::EncryptInPlace(void* buffer, size_t len) { if (!m_activated || len == 0) diff --git a/src/EterBase/SecureCipher.h b/src/EterBase/SecureCipher.h index 8ec6f72..b9fb7dd 100644 --- a/src/EterBase/SecureCipher.h +++ b/src/EterBase/SecureCipher.h @@ -37,14 +37,6 @@ public: void ComputeChallengeResponse(const uint8_t* challenge, uint8_t* out_response); bool VerifyChallengeResponse(const uint8_t* challenge, const uint8_t* response); - // AEAD encryption - output is len + TAG_SIZE bytes - // Returns actual ciphertext length (plaintext_len + TAG_SIZE) - size_t Encrypt(const void* plaintext, size_t plaintext_len, void* ciphertext); - - // AEAD decryption - input must be ciphertext_len bytes (includes TAG_SIZE) - // Returns actual plaintext length, or 0 on failure - size_t Decrypt(const void* ciphertext, size_t ciphertext_len, void* plaintext); - // In-place stream encryption for network buffers (XChaCha20, no tag overhead) // Same length in/out. Nonce counter prevents replay. void EncryptInPlace(void* buffer, size_t len); @@ -69,14 +61,8 @@ public: uint64_t GetTxNonce() const { return m_tx_nonce; } uint64_t GetRxNonce() const { return m_rx_nonce; } - // Access keys directly (for special decrypt operations like session token) + // Direct key access (for session token decryption) const uint8_t* GetRxKey() const { return m_rx_key; } - const uint8_t* GetTxKey() const { return m_tx_key; } - - // Alias for convenience - void ComputeResponse(const uint8_t* challenge, uint8_t* out_response) { - ComputeChallengeResponse(challenge, out_response); - } private: bool m_initialized = false; diff --git a/src/EterGrnLib/Material.cpp b/src/EterGrnLib/Material.cpp index 7d38b2e..6d26f1b 100644 --- a/src/EterGrnLib/Material.cpp +++ b/src/EterGrnLib/Material.cpp @@ -508,53 +508,3 @@ DWORD CGrannyMaterialPalette::GetMaterialCount() const return m_mtrlVector.size(); } -/* -void CActorInstance::BeginSpecularRender() -{ - // NOTE - Blending해서 찍는 부분은 Specular를 적용시키지 않는다 - [levites] - STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - - STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, m_AddColor.r)); - STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - -// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); -// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); -// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); -// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); -// -// STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); -// STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); -// STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); -// STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); -// STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - -// D3DXMATRIX texMatrix; -// GetSphereMatrix(&texMatrix); -// STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &texMatrix); -// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - // Type 1 -// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); -// // Type 2 -// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL); -} - -void CActorInstance::EndSpecularRender() -{ -// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); -// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); -} -*/ diff --git a/src/EterGrnLib/Mesh.cpp b/src/EterGrnLib/Mesh.cpp index ee56296..70c7835 100644 --- a/src/EterGrnLib/Mesh.cpp +++ b/src/EterGrnLib/Mesh.cpp @@ -215,33 +215,7 @@ bool CGrannyMesh::LoadTriGroupNodeList(CGrannyMaterialPalette& rkMtrlPal) void CGrannyMesh::RebuildTriGroupNodeList() { - assert(!"CGrannyMesh::RebuildTriGroupNodeList() - 왜 리빌드를 하는가- -?"); - /* - int mtrlCount = m_pgrnMesh->MaterialBindingCount; - int GroupNodeCount = GrannyGetMeshTriangleGroupCount(m_pgrnMesh); - - if (GroupNodeCount <= 0) - return; - - const granny_tri_material_group * c_pgrnTriGroups = GrannyGetMeshTriangleGroups(m_pgrnMesh); - - for (int g = 0; g < GroupNodeCount; ++g) - { - const granny_tri_material_group& c_rgrnTriGroup = c_pgrnTriGroups[g]; - TTriGroupNode * pTriGroupNode = m_triGroupNodes + g; - - int iMtrl = c_rgrnTriGroup.MaterialIndex; - - if (iMtrl >= 0 && iMtrl < mtrlCount) - { - CGrannyMaterial & rMtrl = m_mtrls[iMtrl]; - - pTriGroupNode->lpd3dTextures[0] = rMtrl.GetD3DTexture(0); - pTriGroupNode->lpd3dTextures[1] = rMtrl.GetD3DTexture(1); - - } - } - */ + assert(!"CGrannyMesh::RebuildTriGroupNodeList() - should not be called"); } bool CGrannyMesh::LoadMaterials(CGrannyMaterialPalette& rkMtrlPal) diff --git a/src/EterGrnLib/ModelInstanceCollisionDetection.cpp b/src/EterGrnLib/ModelInstanceCollisionDetection.cpp index 44ff77e..f595126 100644 --- a/src/EterGrnLib/ModelInstanceCollisionDetection.cpp +++ b/src/EterGrnLib/ModelInstanceCollisionDetection.cpp @@ -90,90 +90,6 @@ bool CGrannyModelInstance::Intersect(const D3DXMATRIX * c_pMatrix, return true; -/* - TBoundBox* boundBoxs = s_boundBoxPool.base(); - for (int i = 0; i < s_boundBoxPool.size(); ++i) - { - TBoundBox& rcurBoundBox=boundBoxs[i]; - - if (!IntersectBoundBox(c_pMatrix, rcurBoundBox, &u, &v, &t)) - continue; - - granny_matrix_4x4* pgrnMatCompositeBuffer = GrannyGetWorldPoseComposite4x4Array(m_pgrnWorldPose); - const CGrannyMesh* c_pMesh = m_pModel->GetMeshPointer(rcurBoundBox.meshIndex); - const granny_mesh* c_pgrnMesh = c_pMesh->GetGrannyMeshPointer(); - - if (!GrannyMeshIsRigid(c_pgrnMesh)) - { - //continue; - ret = true; - } - else - { - D3DXMATRIX matMesh; - int* toBoneIndices = c_pMesh->GetBoneIndices(); - D3DXMatrixMultiply(&matMesh, (D3DXMATRIX*) pgrnMatCompositeBuffer[toBoneIndices[0]], c_pMatrix); - - granny_tri_material_group* pgrnTriGroups = GrannyGetMeshTriangleGroups(c_pgrnMesh); - int mtrlCount = c_pMesh->GetGrannyMeshPointer()->MaterialBindingCount; - int vtxCount = GrannyGetMeshVertexCount(c_pgrnMesh); - int groupCount = GrannyGetMeshTriangleGroupCount(c_pgrnMesh); - - TIndex* modelIndices; - TPNTVertex* modelVertices; - - if (m_pModel->LockVertices((void**)&modelIndices, (void**)&modelVertices)) - { - TIndex* meshIndices = modelIndices + c_pMesh->GetIndexBasePosition(); - TPNTVertex* meshVertices = modelVertices + c_pMesh->GetVertexBasePosition(); - - for (int i = 0; i < groupCount; ++i) - { - granny_tri_material_group& rgrnTriGroup = pgrnTriGroups[i]; - - if (rgrnTriGroup.MaterialIndex < 0 || rgrnTriGroup.MaterialIndex >= mtrlCount) - continue; - - if (IntersectMesh(&matMesh, - meshVertices, - sizeof(TPNTVertex), - vtxCount, - meshIndices, - GrannyGetMeshIndexCount(c_pgrnMesh), - ms_vtPickRayOrig, - ms_vtPickRayDir, - &u, &v, &t)) - { - ret = true; - break; - } - } - - m_pModel->UnlockVertices(); - } - } - - if (ret) - { - *pu = u; - *pv = v; - *pt = -t; - - if (c_szModelName) - { - if (!strncmp(c_pgrnMesh->Name, c_szModelName, strlen(c_szModelName))) - return ret; - - ret = false; - continue; - } - - return ret; - } - } - - return (ret); -*/ } #include "EterBase/Timer.h" @@ -226,42 +142,3 @@ bool CGrannyModelInstance::GetMeshMatrixPointer(int iMesh, const D3DXMATRIX ** c return true; } -/* -void CGraphicThingInstance::DrawBoundBox() -{ - if (!mc_pMeshVector) - return; - - if (!m_pgrnWorldPose) - return; - - D3DXVECTOR3 vtMin; - D3DXVECTOR3 vtMax; - - SetDiffuseColor(0.0f, 1.0f, 0.0f); - // 캐릭터 꽉차는 바운딩 박스 - //GetBoundBox(&vtMin, &vtMax); - //DrawLineCube(vtMin.x, vtMin.y, vtMin.z, vtMax.x, vtMax.y, vtMax.z); - //const CThing::TMeshVector& rmeshVector=mc_pModel->meshVector; - ms_lpd3dMatStack->LoadMatrix(&m_Matrix); - - for (size_t m=0; msize(); ++m) - { - const CThing::TMesh& rmesh=mc_pMeshVector->at(m); - - for (int b=0; bBoneBindingCount; ++b) - { - granny_bone_binding& rgrnBoneBinding=rmesh.pgrnMesh->BoneBindings[b]; - - int* toBoneIndices=GrannyGetMeshBindingToBoneIndices(rmesh.pgrnMeshBinding); - - D3DXMATRIX* pmat=(D3DXMATRIX*)GrannyGetWorldPose4x4(m_pgrnWorldPose, toBoneIndices[b]); - - D3DXVec3TransformCoord(&vtMin, &D3DXVECTOR3(rgrnBoneBinding.OBBMin), pmat); - D3DXVec3TransformCoord(&vtMax, &D3DXVECTOR3(rgrnBoneBinding.OBBMax), pmat); - - DrawLineCube(vtMin.x, vtMin.y, vtMin.z, vtMax.x, vtMax.y, vtMax.z); - } - } -} -*/ diff --git a/src/EterGrnLib/ModelInstanceRender.cpp b/src/EterGrnLib/ModelInstanceRender.cpp index 02ddb0a..eceaaa8 100644 --- a/src/EterGrnLib/ModelInstanceRender.cpp +++ b/src/EterGrnLib/ModelInstanceRender.cpp @@ -299,109 +299,3 @@ void CGrannyModelInstance::RenderMeshNodeListWithoutTexture(CGrannyMesh::EType e } } -/* -void CGrannyModelInstance::RenderMeshNodeList(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) -{ - assert(m_pModel != NULL); - - LPDIRECT3DINDEXBUFFER9 lpd3dIdxBuf = m_pModel->GetD3DIndexBuffer(); - assert(lpd3dIdxBuf != NULL); - - const CGrannyModel::TMeshNode * pMeshNode = m_pModel->GetMeshNodeList(eMeshType, eMtrlType); - - while (pMeshNode) - { - const CGrannyMesh * pMesh = pMeshNode->pMesh; - int vtxMeshBasePos = pMesh->GetVertexBasePosition(); - - STATEMANAGER.SetIndices(lpd3dIdxBuf, vtxMeshBasePos); - STATEMANAGER.SetTransform(D3DTS_WORLD, &m_meshMatrices[pMeshNode->iMesh]); - - ///// - const CGrannyMesh::TTriGroupNode* pTriGroupNode = pMesh->GetTriGroupNodeList(eMtrlType); - int vtxCount = pMesh->GetVertexCount(); - while (pTriGroupNode) - { - ms_faceCount += pTriGroupNode->triCount; - STATEMANAGER.SetTexture(0, pTriGroupNode->lpd3dTextures[0]); - - if (pTriGroupNode->lpd3dTextures[1]) - STATEMANAGER.SetTexture(1, pTriGroupNode->lpd3dTextures[1]); - else - { - STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - STATEMANAGER.SetTexture(1, m_FogInstance.GetTexturePointer()->GetD3DTexture()); - - D3DXMATRIX mat; - memset(&mat, 0, sizeof(D3DXMATRIX)); - mat._31 = -0.001f; - mat._41 = -7.0f; - mat._42 = 0.5f; - STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &mat); - } - - STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, vtxCount, pTriGroupNode->idxPos, pTriGroupNode->triCount); - - if (!pTriGroupNode->lpd3dTextures[1]) - { - STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - - pTriGroupNode = pTriGroupNode->pNextTriGroupNode; - } - ///// - - pMeshNode = pMeshNode->pNextMeshNode; - } -} -void CGrannyModelInstance::RenderToShadowMap() -{ - if (IsEmpty()) - return; - - STATEMANAGER.SetFVF(ms_pntVS); - -// LPDIRECT3DVERTEXBUFFER9 lpd3dDynamicPNTVtxBuf = m_dynamicPNTVtxBuf.GetD3DVertexBuffer(); - LPDIRECT3DVERTEXBUFFER9 lpd3dDeformPNTVtxBuf = m_dynamicPNTVtxBuf.GetD3DVertexBuffer(); - LPDIRECT3DVERTEXBUFFER9 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); - -// STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); -// STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0); -// STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL); -// -// if (lpd3dDynamicPNTVtxBuf) -// { -// STATEMANAGER.SetStreamSource(0, lpd3dDynamicPNTVtxBuf, sizeof(TPNTVertex)); -// RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_BLEND_PNT); -// } -// -// STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); -// STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); -// STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); - - if (lpd3dDeformPNTVtxBuf) - { - STATEMANAGER.SetStreamSource(0, lpd3dDeformPNTVtxBuf, sizeof(TPNTVertex)); - RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_DIFFUSE_PNT); - } - - if (lpd3dRigidPNTVtxBuf) - { - STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNTVertex)); - RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_DIFFUSE_PNT); - } -} -*/ diff --git a/src/EterGrnLib/Util.cpp b/src/EterGrnLib/Util.cpp index 054579e..84e24fd 100644 --- a/src/EterGrnLib/Util.cpp +++ b/src/EterGrnLib/Util.cpp @@ -1,50 +1,7 @@ #include "StdAfx.h" #include "Util.h" -/* -bool GrannyMeshGetTextureAnimation(granny_mesh* pgrnMesh, float* puVelocity, float* pvVelocity) -{ - static granny_data_type_definition s_UVType[] = - { - {GrannyInt32Member, "UV Animation Flag"}, - {GrannyInt32Member, "X Velocity"}, - {GrannyInt32Member, "Y Velocity"}, - {GrannyEndMember} - }; - typedef struct SUVData - { - granny_int32 UVAnimationFlag; - granny_int32 xVelocity; - granny_int32 yVelocity; - } TUVData; - - TUVData UVData; - - granny_variant& rExtendedData = pgrnMesh->ExtendedData; - GrannyConvertSingleObject(rExtendedData.Type, rExtendedData.Object, s_UVType, &UVData); - - *puVelocity = float(UVData.xVelocity) / 100000.0f; - *pvVelocity = float(UVData.yVelocity) / 100000.0f; - - return UVData.UVAnimationFlag ? true : false; -} -*/ - -/* -bool GrannyMeshIsTextureAnimation(granny_mesh* pgrnMesh) -{ - if (GrannyMeshIsRigid(pgrnMesh)) - { - float xVelocity, yVelocity; - - if (GrannyMeshGetTextureAnimation(pgrnMesh, &xVelocity, &yVelocity)) - return true; - } - - return false; -} -*/ bool GrannyMeshIsDeform(granny_mesh* pgrnMesh) { diff --git a/src/EterLib/CollisionData.cpp b/src/EterLib/CollisionData.cpp index 4f97f0b..6cebc34 100644 --- a/src/EterLib/CollisionData.cpp +++ b/src/EterLib/CollisionData.cpp @@ -374,61 +374,14 @@ D3DXVECTOR3 CPlaneCollisionInstance::OnGetCollisionMovementAdjust(const CDynamic const auto vv = (s.v3Position - m_attribute.v3Position); float t= - D3DXVec3Dot(&m_attribute.v3Normal, &vv)/d; - //D3DXVECTOR3 onplane = s.v3Position+t*advance; - if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) { - //return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); return t*advance -s.fRadius*m_attribute.v3Normal; } else { - //return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); return t*advance +s.fRadius*m_attribute.v3Normal; } - - - - /*if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) - { - Tracef("%f %f\n",s.fRadius,-(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))); - return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); - } - else - { - Tracef("%f %f\n",(s.fRadius),(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))); - return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); - }*/ - - - /* - D3DXVECTOR3 advance = s.v3Position-s.v3LastPosition; - D3DXVECTOR3 slide(-advance.y,advance.x,advance.z); - slide = m_attribute.v3Normal; - - D3DXVECTOR3 radius_adjust = advance; - D3DXVec3Normalize(&radius_adjust,&radius_adjust); - radius_adjust*=s.fRadius; - - float d = D3DXVec3Dot(&m_attribute.v3Normal, &slide); - if (d>=-0.0001 && d<=0.0001) - return D3DXVECTOR3(0.0f,0.0f,0.0f); - - float t= - D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position+radius_adjust-m_attribute.v3Position)) - / d;*/ - - //D3DXVECTOR3 nextposition; - //nextposition = s.v3Position + t*slide; - //Tracef("$T %f",t); - //if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) - // return (t*slide - m_attribute.v3Normal * s.fRadius)/**gc_fReduceMove*/; - //else - // return (t*slide + m_attribute.v3Normal * s.fRadius)/*gc_fReduceMove*/; - //if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) - // return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/** s.fRadius*/)*gc_fReduceMove; - //else - // return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/*s.fRadius*/)*gc_fReduceMove; - // } void CPlaneCollisionInstance::Render(D3DFILLMODE /*d3dFillMode*/) @@ -462,12 +415,6 @@ bool CCylinderCollisionInstance::CollideCylinderVSDynamicSphere(const TCylinderD if (s.v3Position.z - s.fRadius > c_rattribute.v3Position.z + c_rattribute.fHeight) return false; - /*D3DXVECTOR2 v2curDistance(s.v3Position.x - c_rattribute.v3Position.x, s.v3Position.y - c_rattribute.v3Position.y); - float fDistance = D3DXVec2Length(&v2curDistance); - if (fDistance <= s.fRadius + c_rattribute.fRadius) - return true; - */ - D3DXVECTOR3 oa, ob; IntersectLineSegments(c_rattribute.v3Position, D3DXVECTOR3(c_rattribute.v3Position.x,c_rattribute.v3Position.y,c_rattribute.v3Position.z+c_rattribute.fHeight), s.v3LastPosition, s.v3Position, oa, ob); const auto vv = (oa - ob); @@ -671,32 +618,6 @@ bool CAABBCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstan D3DXVECTOR3 CAABBCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const { - //Tracef("OnGetCollisionMovementAdjust v3Min.x = %f, v3Max.x = %f\n", m_attribute.v3Min.x, m_attribute.v3Max.x); - /* - float fARadius = D3DXVec3Length(&(m_attribute.v3Min - m_attribute.v3Max)); - if (D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)))>=(s.fRadius+fARadius)*(fARadius+s.fRadius)) - return D3DXVECTOR3(0.0f,0.0f,0.0f); - D3DXVECTOR3 c; - D3DXVec3Cross(&c, &(s.v3Position-s.v3LastPosition), &D3DXVECTOR3(0.0f,0.0f,1.0f) ); - - float sum = - D3DXVec3Dot(&c,&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min))); - float mul = (s.fRadius+fARadius)*(s.fRadius+fARadius)-D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min))); - - if (sum*sum-4*mul<=0) - return D3DXVECTOR3(0.0f,0.0f,0.0f); - float sq = sqrt(sum*sum-4*mul); - float t1=-sum-sq, t2=-sum+sq; - t1*=0.5f; - t2*=0.5f; - - if (fabs(t1)<=fabs(t2)) - { - return (gc_fReduceMove*t1)*c; - } - else - return (gc_fReduceMove*t2)*c; - */ - D3DXVECTOR3 v3Temp; if(s.v3Position.x + s.fRadius <= m_attribute.v3Min.x) { v3Temp.x = m_attribute.v3Min.x; } else if(s.v3Position.x - s.fRadius >= m_attribute.v3Max.x) { v3Temp.x = m_attribute.v3Max.x; } diff --git a/src/EterLib/ControlPackets.h b/src/EterLib/ControlPackets.h new file mode 100644 index 0000000..34147a5 --- /dev/null +++ b/src/EterLib/ControlPackets.h @@ -0,0 +1,73 @@ +#pragma once + +// Control-plane packet structs used by all CNetworkStream subclasses. +// Extracted from UserInterface/Packet.h so the base class (EterLib) +// can handle key exchange, ping/pong, and phase transitions without +// depending on UserInterface. + +#include + +// Control-plane header constants (subset of CG::/GC:: namespaces). +// The full CG/GC namespaces live in Packet.h which includes this file, +// so all existing code sees these via Packet.h as before. +namespace CG +{ + constexpr uint16_t PONG = 0x0006; + constexpr uint16_t KEY_RESPONSE = 0x000A; +} +namespace GC +{ + constexpr uint16_t PING = 0x0007; + constexpr uint16_t PHASE = 0x0008; + constexpr uint16_t KEY_CHALLENGE = 0x000B; + constexpr uint16_t KEY_COMPLETE = 0x000C; +} + +#pragma pack(push, 1) + +struct TPacketGCPhase +{ + uint16_t header; + uint16_t length; + uint8_t phase; +}; + +struct TPacketGCPing +{ + uint16_t header; + uint16_t length; + uint32_t server_time; +}; + +struct TPacketCGPong +{ + uint16_t header; + uint16_t length; +}; + +struct TPacketGCKeyChallenge +{ + uint16_t header; + uint16_t length; + uint8_t server_pk[32]; + uint8_t challenge[32]; + uint32_t server_time; +}; + +struct TPacketCGKeyResponse +{ + uint16_t header; + uint16_t length; + uint8_t client_pk[32]; + uint8_t challenge_response[32]; +}; + +struct TPacketGCKeyComplete +{ + uint16_t header; + uint16_t length; + uint8_t encrypted_token[32 + 16]; + uint8_t nonce[24]; +}; + +#pragma pack(pop) diff --git a/src/EterLib/Decal.cpp b/src/EterLib/Decal.cpp index 173a6e3..a28f292 100644 --- a/src/EterLib/Decal.cpp +++ b/src/EterLib/Decal.cpp @@ -240,48 +240,3 @@ void CDecal::Render() sizeof(TPDTVertex)); } -/* -////////////////////////////////////////////////////////////////////////// -// CDecalManager -////////////////////////////////////////////////////////////////////////// -CDecalManager aDecalManager; - -CDecalManager::CDecalManager() -{ - m_DecalPtrVector.clear(); -} - -CDecalManager::~CDecalManager() -{ - m_DecalPtrVector.clear(); -} - -void CDecalManager::Add(CDecal * pDecal) -{ - m_DecalPtrVector.push_back(pDecal); -} - -void CDecalManager::Remove(CDecal * pDecal) -{ - std::vector::iterator aIterator; - for (aIterator = m_DecalPtrVector.begin(); aIterator != m_DecalPtrVector.end();) - { - if (*aIterator == pDecal) - aIterator = m_DecalPtrVector.erase(aIterator); - else - ++aIterator; - } -} - -void CDecalManager::Update() -{ - for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi) - m_DecalPtrVector[dwi]->Update(); -} - -void CDecalManager::Render() -{ - for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi) - m_DecalPtrVector[dwi]->Render(); -} -*/ diff --git a/src/EterLib/NetDatagram.cpp b/src/EterLib/NetDatagram.cpp deleted file mode 100644 index 2020d98..0000000 --- a/src/EterLib/NetDatagram.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "StdAfx.h" -#include "NetDatagram.h" - -CNetworkDatagram::CNetworkDatagram() -{ - __Initialize(); -} - -CNetworkDatagram::~CNetworkDatagram() -{ - Destroy(); -} - -void CNetworkDatagram::Destroy() -{ - if (INVALID_SOCKET==m_sock) - return; - - closesocket(m_sock); - - __Initialize(); -} - -bool CNetworkDatagram::Create(UINT uPort) -{ - assert(INVALID_SOCKET==m_sock); - m_sock = socket(AF_INET, SOCK_DGRAM, 0); - - DWORD arg = 1; - ioctlsocket(m_sock, FIONBIO, &arg); // Non-blocking mode - - SOCKADDR_IN sockAddrIn; - memset(&sockAddrIn, 0, sizeof(SOCKADDR_IN)); - sockAddrIn.sin_family = AF_INET; - sockAddrIn.sin_addr.s_addr = INADDR_ANY; - sockAddrIn.sin_port = htons(uPort); - - if (SOCKET_ERROR == bind(m_sock, (PSOCKADDR)&sockAddrIn, sizeof(SOCKADDR_IN))) - { - return false; - } - - return true; -} - -#pragma warning(push) -#pragma warning(disable:4127) -void CNetworkDatagram::Update() -{ - if (m_sock == INVALID_SOCKET) - return; - - FD_ZERO(&m_fdsRecv); - FD_ZERO(&m_fdsSend); - - FD_SET(m_sock, &m_fdsRecv); - FD_SET(m_sock, &m_fdsSend); - - TIMEVAL delay; - - delay.tv_sec = 0; - delay.tv_usec = 0; - - if (select(0, &m_fdsRecv, &m_fdsSend, NULL, &delay) == SOCKET_ERROR) - return; -} -#pragma warning(pop) - -bool CNetworkDatagram::CanRecv() -{ - if (FD_ISSET(m_sock, &m_fdsRecv)) - return true; - - return false; -} - - -int CNetworkDatagram::PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn) -{ - int nSockAddrInLen=sizeof(SOCKADDR_IN); - return recvfrom(m_sock, (char*)pvBuf, uBufLen, MSG_PEEK, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen); -} - -int CNetworkDatagram::RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn) -{ - int nSockAddrInLen=sizeof(SOCKADDR_IN); - return recvfrom(m_sock, (char*)pvBuf, uBufLen, 0, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen); -} - -int CNetworkDatagram::SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn) -{ - return sendto(m_sock, (const char *)c_pvBuf, uBufLen, 0, (PSOCKADDR)&c_rkSockAddrIn, sizeof(SOCKADDR_IN)); -} - - -void CNetworkDatagram::__Initialize() -{ - m_sock=INVALID_SOCKET; -} \ No newline at end of file diff --git a/src/EterLib/NetDatagram.h b/src/EterLib/NetDatagram.h deleted file mode 100644 index 7a0b4ee..0000000 --- a/src/EterLib/NetDatagram.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -class CNetworkDatagram -{ - public: - CNetworkDatagram(); - virtual ~CNetworkDatagram(); - - void Destroy(); - bool Create(UINT uPort); - - void Update(); - - bool CanRecv(); - - int PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn); - int RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn); - int SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn); - - private: - void __Initialize(); - - private: - SOCKET m_sock; - - fd_set m_fdsRecv; - fd_set m_fdsSend; -}; \ No newline at end of file diff --git a/src/EterLib/NetDatagramReceiver.cpp b/src/EterLib/NetDatagramReceiver.cpp deleted file mode 100644 index 144faca..0000000 --- a/src/EterLib/NetDatagramReceiver.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "StdAfx.h" -#include "NetDatagramReceiver.h" - -BOOL CNetDatagramReceiver::Process() -{ - m_recvBufCurrentPos = 0; - m_recvBufCurrentSize = 0; - - int irecvAddrLength = sizeof(SOCKADDR_IN); - m_recvBufCurrentSize = recvfrom(m_Socket, (char *)m_recvBuf, m_recvBufSize, 0, (PSOCKADDR)&m_SockAddr, &irecvAddrLength); - - if (m_recvBufCurrentSize <= 0) - { - return FALSE; - } - - return TRUE; -} - -BOOL CNetDatagramReceiver::Recv(void * pBuffer, int iSize) -{ - if (!Peek(pBuffer, iSize)) - return FALSE; - - m_recvBufCurrentPos += iSize; - return TRUE; -} - -BOOL CNetDatagramReceiver::Peek(void * pBuffer, int iSize) -{ - if (m_recvBufCurrentSize < m_recvBufCurrentPos+iSize) - return FALSE; - - memcpy(pBuffer, m_recvBuf + m_recvBufCurrentPos, iSize); - return TRUE; -} - -BOOL CNetDatagramReceiver::isBind() -{ - return m_isBind; -} - -BOOL CNetDatagramReceiver::Bind(DWORD /*dwAddress*/, WORD wPortIndex) -{ - m_Socket = socket(AF_INET, SOCK_DGRAM, 0); - - DWORD arg = 1; - ioctlsocket(m_Socket, FIONBIO, &arg); // Non-blocking mode - - memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); - m_SockAddr.sin_family = AF_INET; -// m_SockAddr.sin_addr.s_addr = dwAddress; - m_SockAddr.sin_addr.s_addr = INADDR_ANY; - m_SockAddr.sin_port = htons(wPortIndex); - - if (bind(m_Socket, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN)) < 0) - { - Tracef("Failed binding socket\n"); - return FALSE; - } - - m_isBind = TRUE; - - return TRUE; -} - -void CNetDatagramReceiver::SetRecvBufferSize(int recvBufSize) -{ - if (m_recvBuf) - { - if (m_recvBufSize>recvBufSize) - return; - - delete [] m_recvBuf; - } - m_recvBufSize=recvBufSize; - m_recvBuf=new char[m_recvBufSize]; -} - -void CNetDatagramReceiver::Clear() -{ - - m_isBind = FALSE; - - m_dwPortIndex = 1000; - - m_Socket = 0; - memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); - - m_recvBufCurrentPos = 0; - m_recvBufCurrentSize = 0; -} - -CNetDatagramReceiver::CNetDatagramReceiver() -{ - m_recvBuf = NULL; - m_recvBufSize = 0; - - Clear(); -} -CNetDatagramReceiver::~CNetDatagramReceiver() -{ - if (m_recvBuf) - delete [] m_recvBuf; -} \ No newline at end of file diff --git a/src/EterLib/NetDatagramReceiver.h b/src/EterLib/NetDatagramReceiver.h deleted file mode 100644 index d8615e5..0000000 --- a/src/EterLib/NetDatagramReceiver.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#ifndef VC_EXTRALEAN - -class CNetDatagramReceiver -{ - public: - CNetDatagramReceiver(); - virtual ~CNetDatagramReceiver(); - - void Clear(); - BOOL Bind(DWORD dwAddress, WORD wPortIndex); - BOOL isBind(); - - BOOL Process(); - BOOL Recv(void * pBuffer, int iSize); - BOOL Peek(void * pBuffer, int iSize); - - void SetRecvBufferSize(int recvBufSize); - - protected: - BOOL m_isBind; - - DWORD m_dwPortIndex; - - SOCKET m_Socket; - SOCKADDR_IN m_SockAddr; - - int m_recvBufCurrentPos; - int m_recvBufCurrentSize; - - char* m_recvBuf; - int m_recvBufSize; -}; - -#endif \ No newline at end of file diff --git a/src/EterLib/NetDatagramSender.cpp b/src/EterLib/NetDatagramSender.cpp deleted file mode 100644 index 72497ee..0000000 --- a/src/EterLib/NetDatagramSender.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "StdAfx.h" -#include "NetDatagramSender.h" - -BOOL CNetDatagramSender::SetSocket(const char * c_szIP, WORD wPortIndex) -{ - return SetSocket(inet_addr(c_szIP), wPortIndex); -} - -BOOL CNetDatagramSender::SetSocket(DWORD dwAddress, WORD wPortIndex) -{ - m_isSocket = TRUE; - - m_dwAddress = dwAddress; - m_wPortIndex = wPortIndex; - - m_Socket = socket(AF_INET, SOCK_DGRAM, 0); - - memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); - m_SockAddr.sin_family = AF_INET; - m_SockAddr.sin_addr.s_addr = dwAddress; - m_SockAddr.sin_port = htons(wPortIndex); - - return TRUE; -} - -BOOL CNetDatagramSender::Send(const void * pBuffer, int iSize) -{ - assert(isSocket()); - - int iSendingLength = sendto(m_Socket, (const char *)pBuffer, iSize, 0, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN)); - if (iSendingLength < 0) - { - Tracef("Failed sending packet\n"); - return FALSE; - } - - return TRUE; -} - -BOOL CNetDatagramSender::isSocket() -{ - return m_isSocket; -} - -CNetDatagramSender::CNetDatagramSender() -{ - m_isSocket = FALSE; - - m_dwAddress = 0; - m_wPortIndex = 1000; - - m_Socket = 0; - memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); -} - -CNetDatagramSender::~CNetDatagramSender() -{ -} \ No newline at end of file diff --git a/src/EterLib/NetDatagramSender.h b/src/EterLib/NetDatagramSender.h deleted file mode 100644 index 8fb96f0..0000000 --- a/src/EterLib/NetDatagramSender.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#ifndef VC_EXTRALEAN - -class CNetDatagramSender -{ - public: - CNetDatagramSender(); - virtual ~CNetDatagramSender(); - - BOOL isSocket(); - - BOOL SetSocket(const char * c_szIP, WORD wPortIndex); - BOOL SetSocket(DWORD dwAddress, WORD wPortIndex); - BOOL Send(const void * pBuffer, int iSize); - - protected: - BOOL m_isSocket; - - WORD m_dwAddress; - WORD m_wPortIndex; - - SOCKET m_Socket; - SOCKADDR_IN m_SockAddr; -}; - -#endif diff --git a/src/EterLib/NetPacketHeaderMap.h b/src/EterLib/NetPacketHeaderMap.h index 6da0ec1..8d98217 100644 --- a/src/EterLib/NetPacketHeaderMap.h +++ b/src/EterLib/NetPacketHeaderMap.h @@ -7,14 +7,12 @@ class CNetworkPacketHeaderMap public: typedef struct SPacketType { - SPacketType(int iSize = 0, bool bFlag = false) + SPacketType(int iSize = 0) + : iPacketSize(iSize) { - iPacketSize = iSize; - isDynamicSizePacket = bFlag; } - int iPacketSize; - bool isDynamicSizePacket; + int iPacketSize; // Expected/minimum packet size (actual size from wire length field) } TPacketType; public: diff --git a/src/EterLib/NetStream.cpp b/src/EterLib/NetStream.cpp index 5303e47..61fe3ed 100644 --- a/src/EterLib/NetStream.cpp +++ b/src/EterLib/NetStream.cpp @@ -7,6 +7,11 @@ #define _PACKETDUMP #endif +#ifdef _PACKETDUMP +#include +#include "../UserInterface/Packet.h" +#endif + bool CNetworkStream::IsSecurityMode() { return m_secureCipher.IsActivated(); @@ -14,58 +19,29 @@ bool CNetworkStream::IsSecurityMode() void CNetworkStream::DecryptPendingRecvData() { - int remaining = m_recvBufInputPos - m_recvBufOutputPos; + size_t remaining = m_recvBuf.ReadableBytes(); if (remaining > 0 && m_secureCipher.IsActivated()) - { - m_secureCipher.DecryptInPlace(m_recvBuf + m_recvBufOutputPos, remaining); - } + m_secureCipher.DecryptInPlace(m_recvBuf.DataAt(m_recvBuf.ReadPos()), remaining); } void CNetworkStream::SetRecvBufferSize(int recvBufSize) { - if (m_recvBuf) - { - if (m_recvBufSize > recvBufSize) - return; - - delete [] m_recvBuf; - } - m_recvBufSize = recvBufSize; - m_recvBuf = new char[m_recvBufSize]; + m_recvBuf.Reserve(static_cast(recvBufSize)); } void CNetworkStream::SetSendBufferSize(int sendBufSize) { - if (m_sendBuf) - { - if (m_sendBufSize > sendBufSize) - return; - - delete [] m_sendBuf; - } - - m_sendBufSize = sendBufSize; - m_sendBuf = new char[m_sendBufSize]; + m_sendBuf.Reserve(static_cast(sendBufSize)); } bool CNetworkStream::__RecvInternalBuffer() { - if (m_recvBufOutputPos > 0) - { - int recvBufDataSize = m_recvBufInputPos - m_recvBufOutputPos; - if (recvBufDataSize > 0) - { - memmove(m_recvBuf, m_recvBuf + m_recvBufOutputPos, recvBufDataSize); - } + m_recvBuf.EnsureWritable(4096); - m_recvBufInputPos -= m_recvBufOutputPos; - m_recvBufOutputPos = 0; - } - - int restSize = m_recvBufSize - m_recvBufInputPos; + int restSize = static_cast(m_recvBuf.WritableBytes()); if (restSize > 0) { - int recvSize = recv(m_sock, m_recvBuf + m_recvBufInputPos, restSize, 0); + int recvSize = recv(m_sock, reinterpret_cast(m_recvBuf.WritePtr()), restSize, 0); if (recvSize < 0) { @@ -80,47 +56,33 @@ bool CNetworkStream::__RecvInternalBuffer() else { if (m_secureCipher.IsActivated()) - { - m_secureCipher.DecryptInPlace(m_recvBuf + m_recvBufInputPos, recvSize); - } - m_recvBufInputPos += recvSize; + m_secureCipher.DecryptInPlace(m_recvBuf.WritePtr(), recvSize); + + m_recvBuf.CommitWrite(recvSize); } } return true; } - bool CNetworkStream::__SendInternalBuffer() { int dataSize = __GetSendBufferSize(); if (dataSize <= 0) return true; - int sendSize = send(m_sock, m_sendBuf + m_sendBufOutputPos, dataSize, 0); + int sendSize = send(m_sock, reinterpret_cast(m_sendBuf.ReadPtr()), dataSize, 0); if (sendSize < 0) - return false; - - m_sendBufOutputPos += sendSize; - __PopSendBuffer(); - - return true; -} - -void CNetworkStream::__PopSendBuffer() -{ - if (m_sendBufOutputPos <= 0) - return; - - int sendBufDataSize = m_sendBufInputPos - m_sendBufOutputPos; - - if (sendBufDataSize > 0) { - memmove(m_sendBuf, m_sendBuf + m_sendBufOutputPos, sendBufDataSize); + int err = WSAGetLastError(); + TraceError("__SendInternalBuffer: send() failed, sock=%llu, dataSize=%d, error=%d", + (unsigned long long)m_sock, dataSize, err); + return false; } - m_sendBufInputPos = sendBufDataSize; - m_sendBufOutputPos = 0; + m_sendBuf.Discard(sendSize); + + return true; } #pragma warning(push) @@ -163,7 +125,7 @@ void CNetworkStream::Process() return; } - if (FD_ISSET(m_sock, &fdsSend) && (m_sendBufInputPos > m_sendBufOutputPos)) + if (FD_ISSET(m_sock, &fdsSend) && (m_sendBuf.ReadableBytes() > 0)) { if (!__SendInternalBuffer()) { @@ -206,24 +168,20 @@ void CNetworkStream::Disconnect() void CNetworkStream::Clear() { - if (m_sock == INVALID_SOCKET) - return; - + // Always clean cipher state (erase key material promptly) m_secureCipher.CleanUp(); - closesocket(m_sock); - m_sock = INVALID_SOCKET; + if (m_sock != INVALID_SOCKET) + { + closesocket(m_sock); + m_sock = INVALID_SOCKET; + } m_isOnline = false; m_connectLimitTime = 0; - m_recvBufInputPos = 0; - m_recvBufOutputPos = 0; - - m_sendBufInputPos = 0; - m_sendBufOutputPos = 0; - - m_SequenceGenerator.seed(SEQUENCE_SEED); + m_recvBuf.Clear(); + m_sendBuf.Clear(); } bool CNetworkStream::Connect(const CNetworkAddress& c_rkNetAddr, int limitSec) @@ -294,251 +252,229 @@ bool CNetworkStream::Connect(const char* c_szAddr, int port, int /*limitSec*/) void CNetworkStream::ClearRecvBuffer() { - m_recvBufOutputPos = m_recvBufInputPos = 0; + m_recvBuf.Clear(); } int CNetworkStream::GetRecvBufferSize() { - return m_recvBufInputPos - m_recvBufOutputPos; + return static_cast(m_recvBuf.ReadableBytes()); } bool CNetworkStream::Peek(int size) { - if (GetRecvBufferSize() < size) - return false; - - return true; + return m_recvBuf.HasBytes(static_cast(size)); } -bool CNetworkStream::Peek(int size, char * pDestBuf) +bool CNetworkStream::Peek(int size, char* pDestBuf) { - if (GetRecvBufferSize() < size) - return false; - - memcpy(pDestBuf, m_recvBuf + m_recvBufOutputPos, size); - return true; + return m_recvBuf.Peek(pDestBuf, static_cast(size)); } - #ifdef _PACKETDUMP -const char * GetSendHeaderName(BYTE header) + +static const char* GetHeaderName(uint16_t header) { - static bool b = false; - static std::string stringList[UCHAR_MAX+1]; - if (b==false) - { - for (DWORD i = 0; i < UCHAR_MAX+1; i++) - { - char buf[10]; - sprintf(buf,"%d",i); - stringList[i] = buf; - } - stringList[2] = "HEADER_CG_ATTACK"; - stringList[3] = "HEADER_CG_CHAT"; - stringList[4] = "HEADER_CG_PLAYER_CREATE"; - stringList[5] = "HEADER_CG_PLAYER_DESTROY"; - stringList[6] = "HEADER_CG_PLAYER_SELECT"; - stringList[7] = "HEADER_CG_CHARACTER_MOVE"; - stringList[8] = "HEADER_CG_SYNC_POSITION"; - stringList[9] = "HEADER_CG_DIRECT_ENTER"; - stringList[10] = "HEADER_CG_ENTERGAME"; - stringList[11] = "HEADER_CG_ITEM_USE"; - stringList[12] = "HEADER_CG_ITEM_DROP"; - stringList[13] = "HEADER_CG_ITEM_MOVE"; - stringList[15] = "HEADER_CG_ITEM_PICKUP"; - stringList[16] = "HEADER_CG_QUICKSLOT_ADD"; - stringList[17] = "HEADER_CG_QUICKSLOT_DEL"; - stringList[18] = "HEADER_CG_QUICKSLOT_SWAP"; - stringList[19] = "HEADER_CG_WHISPER"; - stringList[20] = "HEADER_CG_ITEM_DROP2"; - stringList[26] = "HEADER_CG_ON_CLICK"; - stringList[27] = "HEADER_CG_EXCHANGE"; - stringList[28] = "HEADER_CG_CHARACTER_POSITION"; - stringList[29] = "HEADER_CG_SCRIPT_ANSWER"; - stringList[30] = "HEADER_CG_QUEST_INPUT_STRING"; - stringList[31] = "HEADER_CG_QUEST_CONFIRM"; - stringList[41] = "HEADER_CG_PVP"; - stringList[50] = "HEADER_CG_SHOP"; - stringList[51] = "HEADER_CG_FLY_TARGETING"; - stringList[52] = "HEADER_CG_USE_SKILL"; - stringList[53] = "HEADER_CG_ADD_FLY_TARGETING"; - stringList[54] = "HEADER_CG_SHOOT"; - stringList[55] = "HEADER_CG_MYSHOP"; - stringList[60] = "HEADER_CG_ITEM_USE_TO_ITEM"; - stringList[61] = "HEADER_CG_TARGET"; - stringList[65] = "HEADER_CG_WARP"; - stringList[66] = "HEADER_CG_SCRIPT_BUTTON"; - stringList[67] = "HEADER_CG_MESSENGER"; - stringList[69] = "HEADER_CG_MALL_CHECKOUT"; - stringList[70] = "HEADER_CG_SAFEBOX_CHECKIN"; - stringList[71] = "HEADER_CG_SAFEBOX_CHECKOUT"; - stringList[72] = "HEADER_CG_PARTY_INVITE"; - stringList[73] = "HEADER_CG_PARTY_INVITE_ANSWER"; - stringList[74] = "HEADER_CG_PARTY_REMOVE"; - stringList[75] = "HEADER_CG_PARTY_SET_STATE"; - stringList[76] = "HEADER_CG_PARTY_USE_SKILL"; - stringList[77] = "HEADER_CG_SAFEBOX_ITEM_MOVE"; - stringList[78] = "HEADER_CG_PARTY_PARAMETER"; - stringList[80] = "HEADER_CG_GUILD"; - stringList[81] = "HEADER_CG_ANSWER_MAKE_GUILD"; - stringList[82] = "HEADER_CG_FISHING"; - stringList[83] = "HEADER_CG_GIVE_ITEM"; - stringList[90] = "HEADER_CG_EMPIRE"; - stringList[96] = "HEADER_CG_REFINE"; - stringList[100] = "HEADER_CG_MARK_LOGIN"; - stringList[101] = "HEADER_CG_MARK_CRCLIST"; - stringList[102] = "HEADER_CG_MARK_UPLOAD"; - stringList[103] = "HEADER_CG_CRC_REPORT"; - stringList[105] = "HEADER_CG_HACK"; - stringList[106] = "HEADER_CG_CHANGE_NAME"; - stringList[107] = "HEADER_CG_SMS"; - stringList[108] = "HEADER_CG_MATRIX_CARD"; - stringList[109] = "HEADER_CG_LOGIN2"; - stringList[110] = "HEADER_CG_DUNGEON"; - stringList[111] = "HEADER_CG_LOGIN3"; - stringList[112] = "HEADER_CG_GUILD_SYMBOL_UPLOAD"; - stringList[113] = "HEADER_CG_GUILD_SYMBOL_CRC"; - stringList[114] = "HEADER_CG_SCRIPT_SELECT_ITEM"; - stringList[0xf9] = "HEADER_CG_KEY_RESPONSE"; - stringList[0xfc] = "HEADER_CG_TIME_SYNC"; - stringList[0xfd] = "HEADER_CG_CLIENT_VERSION"; - stringList[0xfe] = "HEADER_CG_PONG"; - stringList[0xff] = "HEADER_CG_HANDSHAKE"; - } - return stringList[header].c_str(); -} + static const std::unordered_map s_headerNames = { + // Control + { CG::PONG, "CG_PONG" }, + { GC::PING, "GC_PING" }, + { GC::PHASE, "GC_PHASE" }, + { CG::KEY_RESPONSE, "CG_KEY_RESPONSE" }, + { GC::KEY_CHALLENGE, "GC_KEY_CHALLENGE" }, + { GC::KEY_COMPLETE, "GC_KEY_COMPLETE" }, + { CG::CLIENT_VERSION, "CG_CLIENT_VERSION" }, + { CG::STATE_CHECKER, "CG_STATE_CHECKER" }, + { GC::RESPOND_CHANNELSTATUS, "GC_RESPOND_CHANNELSTATUS" }, + { CG::TEXT, "CG_TEXT" }, + // Authentication + { CG::LOGIN2, "CG_LOGIN2" }, + { CG::LOGIN3, "CG_LOGIN3" }, + { CG::LOGIN_SECURE, "CG_LOGIN_SECURE" }, + { GC::LOGIN_SUCCESS3, "GC_LOGIN_SUCCESS3" }, + { GC::LOGIN_SUCCESS4, "GC_LOGIN_SUCCESS4" }, + { GC::LOGIN_FAILURE, "GC_LOGIN_FAILURE" }, + { GC::LOGIN_KEY, "GC_LOGIN_KEY" }, + { GC::AUTH_SUCCESS, "GC_AUTH_SUCCESS" }, + { GC::EMPIRE, "GC_EMPIRE" }, + { CG::EMPIRE, "CG_EMPIRE" }, + { CG::CHANGE_NAME, "CG_CHANGE_NAME" }, + { GC::CHANGE_NAME, "GC_CHANGE_NAME" }, + // Character + { CG::CHARACTER_CREATE, "CG_CHARACTER_CREATE" }, + { CG::CHARACTER_DELETE, "CG_CHARACTER_DELETE" }, + { CG::CHARACTER_SELECT, "CG_CHARACTER_SELECT" }, + { CG::ENTERGAME, "CG_ENTERGAME" }, + { GC::CHARACTER_ADD, "GC_CHARACTER_ADD" }, + { GC::CHARACTER_ADD2, "GC_CHARACTER_ADD2" }, + { GC::CHAR_ADDITIONAL_INFO, "GC_CHAR_ADDITIONAL_INFO" }, + { GC::CHARACTER_DEL, "GC_CHARACTER_DEL" }, + { GC::CHARACTER_UPDATE, "GC_CHARACTER_UPDATE" }, + { GC::CHARACTER_UPDATE2, "GC_CHARACTER_UPDATE2" }, + { GC::CHARACTER_POSITION, "GC_CHARACTER_POSITION" }, + { GC::PLAYER_CREATE_SUCCESS, "GC_PLAYER_CREATE_SUCCESS" }, + { GC::PLAYER_CREATE_FAILURE, "GC_PLAYER_CREATE_FAILURE" }, + { GC::PLAYER_DELETE_SUCCESS, "GC_PLAYER_DELETE_SUCCESS" }, + { GC::PLAYER_DELETE_WRONG_SOCIAL_ID, "GC_PLAYER_DELETE_WRONG_SOCIAL_ID" }, + { GC::MAIN_CHARACTER, "GC_MAIN_CHARACTER" }, + { GC::PLAYER_POINTS, "GC_PLAYER_POINTS" }, + { GC::PLAYER_POINT_CHANGE, "GC_PLAYER_POINT_CHANGE" }, + { GC::STUN, "GC_STUN" }, + { GC::DEAD, "GC_DEAD" }, + { GC::CHANGE_SPEED, "GC_CHANGE_SPEED" }, + { GC::WALK_MODE, "GC_WALK_MODE" }, + { GC::SKILL_LEVEL, "GC_SKILL_LEVEL" }, + { GC::SKILL_LEVEL_NEW, "GC_SKILL_LEVEL_NEW" }, + { GC::SKILL_COOLTIME_END, "GC_SKILL_COOLTIME_END" }, + { GC::CHANGE_SKILL_GROUP, "GC_CHANGE_SKILL_GROUP" }, + { GC::VIEW_EQUIP, "GC_VIEW_EQUIP" }, + // Movement + { CG::MOVE, "CG_MOVE" }, + { GC::MOVE, "GC_MOVE" }, + { CG::SYNC_POSITION, "CG_SYNC_POSITION" }, + { GC::SYNC_POSITION, "GC_SYNC_POSITION" }, + { CG::WARP, "CG_WARP" }, + { GC::WARP, "GC_WARP" }, + { GC::MOTION, "GC_MOTION" }, + { GC::DIG_MOTION, "GC_DIG_MOTION" }, + // Combat + { CG::ATTACK, "CG_ATTACK" }, + { CG::USE_SKILL, "CG_USE_SKILL" }, + { CG::SHOOT, "CG_SHOOT" }, + { CG::FLY_TARGETING, "CG_FLY_TARGETING" }, + { CG::ADD_FLY_TARGETING, "CG_ADD_FLY_TARGETING" }, + { GC::DAMAGE_INFO, "GC_DAMAGE_INFO" }, + { GC::FLY_TARGETING, "GC_FLY_TARGETING" }, + { GC::ADD_FLY_TARGETING, "GC_ADD_FLY_TARGETING" }, + { GC::CREATE_FLY, "GC_CREATE_FLY" }, + { GC::PVP, "GC_PVP" }, + { GC::DUEL_START, "GC_DUEL_START" }, + // Items + { CG::ITEM_USE, "CG_ITEM_USE" }, + { CG::ITEM_DROP, "CG_ITEM_DROP" }, + { CG::ITEM_DROP2, "CG_ITEM_DROP2" }, + { CG::ITEM_MOVE, "CG_ITEM_MOVE" }, + { CG::ITEM_PICKUP, "CG_ITEM_PICKUP" }, + { CG::ITEM_USE_TO_ITEM, "CG_ITEM_USE_TO_ITEM" }, + { CG::ITEM_GIVE, "CG_ITEM_GIVE" }, + { CG::EXCHANGE, "CG_EXCHANGE" }, + { CG::QUICKSLOT_ADD, "CG_QUICKSLOT_ADD" }, + { CG::QUICKSLOT_DEL, "CG_QUICKSLOT_DEL" }, + { CG::QUICKSLOT_SWAP, "CG_QUICKSLOT_SWAP" }, + { CG::REFINE, "CG_REFINE" }, + { CG::DRAGON_SOUL_REFINE, "CG_DRAGON_SOUL_REFINE" }, + { GC::ITEM_DEL, "GC_ITEM_DEL" }, + { GC::ITEM_SET, "GC_ITEM_SET" }, + { GC::ITEM_USE, "GC_ITEM_USE" }, + { GC::ITEM_DROP, "GC_ITEM_DROP" }, + { GC::ITEM_UPDATE, "GC_ITEM_UPDATE" }, + { GC::ITEM_GROUND_ADD, "GC_ITEM_GROUND_ADD" }, + { GC::ITEM_GROUND_DEL, "GC_ITEM_GROUND_DEL" }, + { GC::ITEM_OWNERSHIP, "GC_ITEM_OWNERSHIP" }, + { GC::ITEM_GET, "GC_ITEM_GET" }, + { GC::QUICKSLOT_ADD, "GC_QUICKSLOT_ADD" }, + { GC::QUICKSLOT_DEL, "GC_QUICKSLOT_DEL" }, + { GC::QUICKSLOT_SWAP, "GC_QUICKSLOT_SWAP" }, + { GC::EXCHANGE, "GC_EXCHANGE" }, + { GC::REFINE_INFORMATION, "GC_REFINE_INFORMATION" }, + { GC::DRAGON_SOUL_REFINE, "GC_DRAGON_SOUL_REFINE" }, + // Chat + { CG::CHAT, "CG_CHAT" }, + { CG::WHISPER, "CG_WHISPER" }, + { GC::CHAT, "GC_CHAT" }, + { GC::WHISPER, "GC_WHISPER" }, + // Social + { CG::PARTY_INVITE, "CG_PARTY_INVITE" }, + { CG::PARTY_INVITE_ANSWER, "CG_PARTY_INVITE_ANSWER" }, + { CG::PARTY_REMOVE, "CG_PARTY_REMOVE" }, + { CG::PARTY_SET_STATE, "CG_PARTY_SET_STATE" }, + { CG::PARTY_USE_SKILL, "CG_PARTY_USE_SKILL" }, + { CG::PARTY_PARAMETER, "CG_PARTY_PARAMETER" }, + { GC::PARTY_INVITE, "GC_PARTY_INVITE" }, + { GC::PARTY_ADD, "GC_PARTY_ADD" }, + { GC::PARTY_UPDATE, "GC_PARTY_UPDATE" }, + { GC::PARTY_REMOVE, "GC_PARTY_REMOVE" }, + { GC::PARTY_LINK, "GC_PARTY_LINK" }, + { GC::PARTY_UNLINK, "GC_PARTY_UNLINK" }, + { GC::PARTY_PARAMETER, "GC_PARTY_PARAMETER" }, + { CG::GUILD, "CG_GUILD" }, + { CG::ANSWER_MAKE_GUILD, "CG_ANSWER_MAKE_GUILD" }, + { CG::GUILD_SYMBOL_UPLOAD, "CG_GUILD_SYMBOL_UPLOAD" }, + { CG::SYMBOL_CRC, "CG_SYMBOL_CRC" }, + { GC::GUILD, "GC_GUILD" }, + { GC::REQUEST_MAKE_GUILD, "GC_REQUEST_MAKE_GUILD" }, + { GC::SYMBOL_DATA, "GC_SYMBOL_DATA" }, + { CG::MESSENGER, "CG_MESSENGER" }, + { GC::MESSENGER, "GC_MESSENGER" }, + { GC::LOVER_INFO, "GC_LOVER_INFO" }, + { GC::LOVE_POINT_UPDATE, "GC_LOVE_POINT_UPDATE" }, + // Shop / Trade + { CG::SHOP, "CG_SHOP" }, + { CG::MYSHOP, "CG_MYSHOP" }, + { GC::SHOP, "GC_SHOP" }, + { GC::SHOP_SIGN, "GC_SHOP_SIGN" }, + { CG::SAFEBOX_CHECKIN, "CG_SAFEBOX_CHECKIN" }, + { CG::SAFEBOX_CHECKOUT, "CG_SAFEBOX_CHECKOUT" }, + { CG::SAFEBOX_ITEM_MOVE, "CG_SAFEBOX_ITEM_MOVE" }, + { GC::SAFEBOX_SET, "GC_SAFEBOX_SET" }, + { GC::SAFEBOX_DEL, "GC_SAFEBOX_DEL" }, + { GC::SAFEBOX_WRONG_PASSWORD, "GC_SAFEBOX_WRONG_PASSWORD" }, + { GC::SAFEBOX_SIZE, "GC_SAFEBOX_SIZE" }, + { GC::SAFEBOX_MONEY_CHANGE, "GC_SAFEBOX_MONEY_CHANGE" }, + { CG::MALL_CHECKOUT, "CG_MALL_CHECKOUT" }, + { GC::MALL_OPEN, "GC_MALL_OPEN" }, + { GC::MALL_SET, "GC_MALL_SET" }, + { GC::MALL_DEL, "GC_MALL_DEL" }, + // Quest + { CG::SCRIPT_ANSWER, "CG_SCRIPT_ANSWER" }, + { CG::SCRIPT_BUTTON, "CG_SCRIPT_BUTTON" }, + { CG::SCRIPT_SELECT_ITEM, "CG_SCRIPT_SELECT_ITEM" }, + { CG::QUEST_INPUT_STRING, "CG_QUEST_INPUT_STRING" }, + { CG::QUEST_CONFIRM, "CG_QUEST_CONFIRM" }, + { CG::QUEST_CANCEL, "CG_QUEST_CANCEL" }, + { GC::SCRIPT, "GC_SCRIPT" }, + { GC::QUEST_CONFIRM, "GC_QUEST_CONFIRM" }, + { GC::QUEST_INFO, "GC_QUEST_INFO" }, + // UI / Effects + { CG::TARGET, "CG_TARGET" }, + { CG::ON_CLICK, "CG_ON_CLICK" }, + { GC::TARGET, "GC_TARGET" }, + { GC::TARGET_UPDATE, "GC_TARGET_UPDATE" }, + { GC::TARGET_DELETE, "GC_TARGET_DELETE" }, + { GC::TARGET_CREATE_NEW, "GC_TARGET_CREATE_NEW" }, + { GC::AFFECT_ADD, "GC_AFFECT_ADD" }, + { GC::AFFECT_REMOVE, "GC_AFFECT_REMOVE" }, + { GC::SEPCIAL_EFFECT, "GC_SPECIAL_EFFECT" }, + { GC::SPECIFIC_EFFECT, "GC_SPECIFIC_EFFECT" }, + { GC::MOUNT, "GC_MOUNT" }, + { GC::OWNERSHIP, "GC_OWNERSHIP" }, + { GC::NPC_POSITION, "GC_NPC_POSITION" }, + { CG::CHARACTER_POSITION, "CG_CHARACTER_POSITION" }, + // World + { CG::FISHING, "CG_FISHING" }, + { CG::DUNGEON, "CG_DUNGEON" }, + { CG::HACK, "CG_HACK" }, + { GC::FISHING, "GC_FISHING" }, + { GC::DUNGEON, "GC_DUNGEON" }, + { GC::LAND_LIST, "GC_LAND_LIST" }, + { GC::TIME, "GC_TIME" }, + { GC::CHANNEL, "GC_CHANNEL" }, + { GC::MARK_UPDATE, "GC_MARK_UPDATE" }, + // Guild Marks + { CG::MARK_LOGIN, "CG_MARK_LOGIN" }, + { CG::MARK_CRCLIST, "CG_MARK_CRCLIST" }, + { CG::MARK_UPLOAD, "CG_MARK_UPLOAD" }, + { CG::MARK_IDXLIST, "CG_MARK_IDXLIST" }, + { GC::MARK_BLOCK, "GC_MARK_BLOCK" }, + { GC::MARK_IDXLIST, "GC_MARK_IDXLIST" }, + }; -const char * GetRecvHeaderName(BYTE header) -{ - static bool b = false; - static std::string stringList[UCHAR_MAX+1]; - if (b==false) - { - for (DWORD i = 0; i < UCHAR_MAX+1; i++) - { - char buf[10]; - sprintf(buf,"%d",i); - stringList[i] = buf; - } - stringList[1] = "HEADER_GC_CHARACTER_ADD"; - stringList[2] = "HEADER_GC_CHARACTER_DEL"; - stringList[3] = "HEADER_GC_CHARACTER_MOVE"; - stringList[4] = "HEADER_GC_CHAT"; - stringList[5] = "HEADER_GC_SYNC_POSITION"; - stringList[6] = "HEADER_GC_LOGIN_SUCCESS"; - stringList[7] = "HEADER_GC_LOGIN_FAILURE"; - stringList[8] = "HEADER_GC_PLAYER_CREATE_SUCCESS"; - stringList[9] = "HEADER_GC_PLAYER_CREATE_FAILURE"; - stringList[10] = "HEADER_GC_PLAYER_DELETE_SUCCESS"; - stringList[11] = "HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID"; + auto it = s_headerNames.find(header); + if (it != s_headerNames.end()) + return it->second; - stringList[13] = "HEADER_GC_STUN"; - stringList[14] = "HEADER_GC_DEAD"; - stringList[15] = "HEADER_GC_MAIN_CHARACTER"; - stringList[16] = "HEADER_GC_PLAYER_POINTS"; - stringList[17] = "HEADER_GC_PLAYER_POINT_CHANGE"; - stringList[18] = "HEADER_GC_CHANGE_SPEED"; - stringList[19] = "HEADER_GC_CHARACTER_UPDATE"; - stringList[20] = "HEADER_GC_ITEM_DEL"; - stringList[21] = "HEADER_GC_ITEM_SET"; - stringList[22] = "HEADER_GC_ITEM_USE"; - stringList[23] = "HEADER_GC_ITEM_DROP"; - stringList[25] = "HEADER_GC_ITEM_UPDATE"; - stringList[26] = "HEADER_GC_ITEM_GROUND_ADD"; - stringList[27] = "HEADER_GC_ITEM_GROUND_DEL"; - stringList[28] = "HEADER_GC_QUICKSLOT_ADD"; - stringList[29] = "HEADER_GC_QUICKSLOT_DEL"; - stringList[30] = "HEADER_GC_QUICKSLOT_SWAP"; - stringList[31] = "HEADER_GC_ITEM_OWNERSHIP"; - stringList[33] = "HEADER_GC_ITEM_UNBIND_TIME"; - stringList[34] = "HEADER_GC_WHISPER"; - stringList[35] = "HEADER_GC_ALERT"; - stringList[36] = "HEADER_GC_MOTION"; - stringList[38] = "HEADER_GC_SHOP"; - stringList[39] = "HEADER_GC_SHOP_SIGN"; - stringList[41] = "HEADER_GC_PVP"; - stringList[42] = "HEADER_GC_EXCHANGE"; - stringList[43] = "HEADER_GC_CHARACTER_POSITION"; - stringList[44] = "HEADER_GC_PING"; - stringList[45] = "HEADER_GC_SCRIPT"; - stringList[46] = "HEADER_GC_QUEST_CONFIRM"; - - stringList[61] = "HEADER_GC_MOUNT"; - stringList[62] = "HEADER_GC_OWNERSHIP"; - stringList[63] = "HEADER_GC_TARGET"; - stringList[65] = "HEADER_GC_WARP"; - stringList[69] = "HEADER_GC_ADD_FLY_TARGETING"; - - stringList[70] = "HEADER_GC_CREATE_FLY"; - stringList[71] = "HEADER_GC_FLY_TARGETING"; - stringList[72] = "HEADER_GC_SKILL_LEVEL"; - stringList[73] = "HEADER_GC_SKILL_COOLTIME_END"; - stringList[74] = "HEADER_GC_MESSENGER"; - stringList[75] = "HEADER_GC_GUILD"; - stringList[76] = "HEADER_GC_SKILL_LEVEL_NEW"; - stringList[77] = "HEADER_GC_PARTY_INVITE"; - stringList[78] = "HEADER_GC_PARTY_ADD"; - stringList[79] = "HEADER_GC_PARTY_UPDATE"; - stringList[80] = "HEADER_GC_PARTY_REMOVE"; - stringList[81] = "HEADER_GC_QUEST_INFO"; - stringList[82] = "HEADER_GC_REQUEST_MAKE_GUILD"; - stringList[83] = "HEADER_GC_PARTY_PARAMETER"; - stringList[84] = "HEADER_GC_SAFEBOX_MONEY_CHANGE"; - stringList[85] = "HEADER_GC_SAFEBOX_SET"; - stringList[86] = "HEADER_GC_SAFEBOX_DEL"; - stringList[87] = "HEADER_GC_SAFEBOX_WRONG_PASSWORD"; - stringList[88] = "HEADER_GC_SAFEBOX_SIZE"; - stringList[89] = "HEADER_GC_FISHING"; - stringList[90] = "HEADER_GC_EMPIRE"; - stringList[91] = "HEADER_GC_PARTY_LINK"; - stringList[92] = "HEADER_GC_PARTY_UNLINK"; - - stringList[95] = "HEADER_GC_REFINE_INFORMATION"; - stringList[96] = "HEADER_GC_OBSERVER_ADD"; - stringList[97] = "HEADER_GC_OBSERVER_REMOVE"; - stringList[98] = "HEADER_GC_OBSERVER_MOVE"; - stringList[99] = "HEADER_GC_VIEW_EQUIP"; - stringList[100] = "HEADER_GC_MARK_BLOCK"; - stringList[101] = "HEADER_GC_MARK_DIFF_DATA"; - - stringList[106] = "HEADER_GC_TIME"; - stringList[107] = "HEADER_GC_CHANGE_NAME"; - stringList[110] = "HEADER_GC_DUNGEON"; - stringList[111] = "HEADER_GC_WALK_MODE"; - stringList[112] = "HEADER_GC_CHANGE_SKILL_GROUP"; - stringList[113] = "HEADER_GC_MAIN_CHARACTER_NEW"; - stringList[114] = "HEADER_GC_USE_POTION"; - stringList[115] = "HEADER_GC_NPC_POSITION"; - stringList[116] = "HEADER_GC_MATRIX_CARD"; - stringList[117] = "HEADER_GC_CHARACTER_UPDATE2"; - stringList[118] = "HEADER_GC_LOGIN_KEY"; - stringList[119] = "HEADER_GC_REFINE_INFORMATION_NEW"; - stringList[120] = "HEADER_GC_CHARACTER_ADD2"; - stringList[121] = "HEADER_GC_CHANNEL"; - stringList[122] = "HEADER_GC_MALL_OPEN"; - stringList[123] = "HEADER_GC_TARGET_UPDATE"; - stringList[124] = "HEADER_GC_TARGET_DELETE"; - stringList[125] = "HEADER_GC_TARGET_CREATE_NEW"; - stringList[126] = "HEADER_GC_AFFECT_ADD"; - stringList[127] = "HEADER_GC_AFFECT_REMOVE"; - stringList[128] = "HEADER_GC_MALL_SET"; - stringList[129] = "HEADER_GC_MALL_DEL"; - stringList[130] = "HEADER_GC_LAND_LIST"; - stringList[131] = "HEADER_GC_LOVER_INFO"; - stringList[132] = "HEADER_GC_LOVE_POINT_UPDATE"; - stringList[133] = "HEADER_GC_GUILD_SYMBOL_DATA"; - stringList[134] = "HEADER_GC_DIG_MOTION"; - stringList[135] = "HEADER_GC_DAMAGE_INFO"; - stringList[136] = "HEADER_GC_CHAR_ADDITIONAL_INFO"; - stringList[150] = "HEADER_GC_AUTH_SUCCESS"; - stringList[0xf7] = "HEADER_GC_KEY_COMPLETE"; - stringList[0xf8] = "HEADER_GC_KEY_CHALLENGE"; - stringList[0xfc] = "HEADER_GC_HANDSHAKE_OK"; - stringList[0xfd] = "HEADER_GC_PHASE"; - stringList[0xfe] = "HEADER_GC_BINDUDP"; - stringList[0xff] = "HEADER_GC_HANDSHAKE"; - } - return stringList[header].c_str(); + static thread_local char buf[16]; + snprintf(buf, sizeof(buf), "0x%04X", header); + return buf; } #endif @@ -548,7 +484,7 @@ bool CNetworkStream::Recv(int size) if (!Peek(size)) return false; - m_recvBufOutputPos += size; + m_recvBuf.Discard(static_cast(size)); return true; } @@ -575,46 +511,61 @@ bool CNetworkStream::Recv(int size, char * pDestBuf) return false; #ifdef _PACKETDUMP - if (*pDestBuf != 0) + if (size >= 2) { - const auto kHeader = *pDestBuf; - TraceError("RECV< %s %u(0x%X) (%d)", GetRecvHeaderName(kHeader), kHeader, kHeader, size); + const uint16_t kHeader = *reinterpret_cast(pDestBuf); + TraceError("RECV< %s 0x%04X (%d bytes)", GetHeaderName(kHeader), kHeader, size); const auto contents = dump_hex(reinterpret_cast(pDestBuf), size); TraceError("%s", contents.c_str()); } #endif - m_recvBufOutputPos += size; + m_recvBuf.Discard(static_cast(size)); return true; } int CNetworkStream::__GetSendBufferSize() { - return m_sendBufInputPos - m_sendBufOutputPos; + return static_cast(m_sendBuf.ReadableBytes()); } - bool CNetworkStream::Send(int size, const char * pSrcBuf) { - int sendBufRestSize = m_sendBufSize - m_sendBufInputPos; - if ((size + 1) > sendBufRestSize) - return false; - - memcpy(m_sendBuf + m_sendBufInputPos, pSrcBuf, size); - - if (m_secureCipher.IsActivated()) + // Track packet sends: detect new packet start by checking [header:2][length:2] framing + if (size >= 4) { - m_secureCipher.EncryptInPlace(m_sendBuf + m_sendBufInputPos, size); + const uint16_t wHeader = *reinterpret_cast(pSrcBuf); + const uint16_t wLength = *reinterpret_cast(pSrcBuf + 2); + + if (wHeader != 0 && wLength >= 4) + { + auto& e = m_aSentPacketLog[m_dwSentPacketSeq % SENT_PACKET_LOG_SIZE]; + e.seq = m_dwSentPacketSeq; + e.header = wHeader; + e.length = wLength; + m_dwSentPacketSeq++; + } } - m_sendBufInputPos += size; + m_sendBuf.EnsureWritable(static_cast(size)); + + // Copy data to send buffer + std::memcpy(m_sendBuf.WritePtr(), pSrcBuf, static_cast(size)); + + // Encrypt in-place before committing + if (m_secureCipher.IsActivated()) + { + m_secureCipher.EncryptInPlace(m_sendBuf.WritePtr(), size); + } + + m_sendBuf.CommitWrite(static_cast(size)); #ifdef _PACKETDUMP - if (*pSrcBuf != 0) + if (size >= 2) { - const auto kHeader = *pSrcBuf; - TraceError("SEND> %s %u(0x%X) (%d)", GetSendHeaderName(kHeader), kHeader, kHeader, size); + const uint16_t kHeader = *reinterpret_cast(pSrcBuf); + TraceError("SEND> %s 0x%04X (%d bytes)", GetHeaderName(kHeader), kHeader, size); const auto contents = dump_hex(reinterpret_cast(pSrcBuf), size); TraceError("%s", contents.c_str()); @@ -652,25 +603,6 @@ bool CNetworkStream::IsOnline() return m_isOnline; } -void CNetworkStream::SetPacketSequenceMode(bool isOn) -{ - m_bUseSequence = isOn; -} - -bool CNetworkStream::SendSequence() -{ - if (!m_bUseSequence) - return true; - - BYTE bSeq = m_SequenceGenerator(UINT8_MAX + 1); - return Send(sizeof(BYTE), &bSeq); -} - -uint8_t CNetworkStream::GetNextSequence() -{ - return m_SequenceGenerator(UINT8_MAX + 1); -} - bool CNetworkStream::OnProcess() { return true; @@ -694,6 +626,96 @@ void CNetworkStream::OnConnectFailure() Tracen("Failed to connect."); } +// --------------------------------------------------------------------------- +// Control-plane packet handlers (shared by all connection types) +// --------------------------------------------------------------------------- + +bool CNetworkStream::RecvKeyChallenge() +{ + TPacketGCKeyChallenge packet; + if (!Recv(sizeof(packet), &packet)) + return false; + + Tracen("KEY_CHALLENGE RECV"); + + SecureCipher& cipher = GetSecureCipher(); + if (!cipher.Initialize()) + { + TraceError("SecureCipher initialization failed"); + Disconnect(); + return false; + } + + if (!cipher.ComputeClientKeys(packet.server_pk)) + { + TraceError("Failed to compute client session keys"); + Disconnect(); + return false; + } + + TPacketCGKeyResponse response; + response.header = CG::KEY_RESPONSE; + response.length = sizeof(response); + cipher.GetPublicKey(response.client_pk); + cipher.ComputeChallengeResponse(packet.challenge, response.challenge_response); + + if (!Send(sizeof(response), &response)) + { + TraceError("Failed to send key response"); + return false; + } + + Tracen("KEY_RESPONSE SENT"); + return true; +} + +bool CNetworkStream::RecvKeyComplete() +{ + TPacketGCKeyComplete packet; + if (!Recv(sizeof(packet), &packet)) + return false; + + SecureCipher& cipher = GetSecureCipher(); + + uint8_t decrypted_token[SecureCipher::SESSION_TOKEN_SIZE]; + if (!cipher.DecryptToken(packet.encrypted_token, sizeof(packet.encrypted_token), + packet.nonce, decrypted_token)) + { + TraceError("Failed to decrypt session token"); + Disconnect(); + return false; + } + + cipher.SetSessionToken(decrypted_token); + cipher.SetActivated(true); + DecryptPendingRecvData(); + + return true; +} + +bool CNetworkStream::RecvPingPacket() +{ + TPacketGCPing kPacketPing; + if (!Recv(sizeof(kPacketPing), &kPacketPing)) + return false; + + return SendPongPacket(); +} + +bool CNetworkStream::SendPongPacket() +{ + TPacketCGPong kPacketPong; + kPacketPong.header = CG::PONG; + kPacketPong.length = sizeof(kPacketPong); + + if (!Send(sizeof(kPacketPong), &kPacketPong)) + return false; + + return true; +} + +// --------------------------------------------------------------------------- + CNetworkStream::CNetworkStream() { m_sock = INVALID_SOCKET; @@ -701,33 +723,9 @@ CNetworkStream::CNetworkStream() m_isOnline = false; m_connectLimitTime = 0; - m_recvBuf = NULL; - m_recvBufSize = 0; - m_recvBufOutputPos = 0; - m_recvBufInputPos = 0; - - m_sendBuf = NULL; - m_sendBufSize = 0; - m_sendBufOutputPos = 0; - m_sendBufInputPos = 0; - - m_SequenceGenerator.seed(SEQUENCE_SEED); - m_bUseSequence = false; } CNetworkStream::~CNetworkStream() { Clear(); - - if (m_recvBuf) - { - delete [] m_recvBuf; - m_recvBuf = NULL; - } - - if (m_sendBuf) - { - delete [] m_sendBuf; - m_sendBuf = NULL; - } } diff --git a/src/EterLib/NetStream.h b/src/EterLib/NetStream.h index e7d02bd..2869c8d 100644 --- a/src/EterLib/NetStream.h +++ b/src/EterLib/NetStream.h @@ -2,10 +2,9 @@ #include "EterBase/SecureCipher.h" #include "NetAddress.h" +#include "RingBuffer.h" +#include "ControlPackets.h" -#include - -#define SEQUENCE_SEED 0 class CNetworkStream { @@ -44,10 +43,6 @@ class CNetworkStream bool IsOnline(); - void SetPacketSequenceMode(bool isOn); - bool SendSequence(); - uint8_t GetNextSequence(); - protected: virtual void OnConnectSuccess(); virtual void OnConnectFailure(); @@ -58,8 +53,6 @@ class CNetworkStream bool __SendInternalBuffer(); bool __RecvInternalBuffer(); - void __PopSendBuffer(); - int __GetSendBufferSize(); // Secure cipher methods (libsodium) @@ -71,18 +64,31 @@ class CNetworkStream // Must be called after activating the cipher mid-stream void DecryptPendingRecvData(); + // Control-plane packet handlers (shared by all connection types) + virtual bool RecvKeyChallenge(); + virtual bool RecvKeyComplete(); + bool RecvPingPacket(); + bool SendPongPacket(); + + // Packet send tracking (for debug sequence correlation) + protected: + struct SentPacketLogEntry + { + uint32_t seq; + uint16_t header; + uint16_t length; + }; + + static constexpr size_t SENT_PACKET_LOG_SIZE = 32; + + SentPacketLogEntry m_aSentPacketLog[SENT_PACKET_LOG_SIZE] = {}; + uint32_t m_dwSentPacketSeq = 0; + private: time_t m_connectLimitTime; - char* m_recvBuf; - int m_recvBufSize; - int m_recvBufInputPos; - int m_recvBufOutputPos; - - char* m_sendBuf; - int m_sendBufSize; - int m_sendBufInputPos; - int m_sendBufOutputPos; + RingBuffer m_recvBuf; + RingBuffer m_sendBuf; bool m_isOnline; @@ -93,7 +99,4 @@ class CNetworkStream CNetworkAddress m_addr; - // Sequence - pcg32 m_SequenceGenerator; - bool m_bUseSequence; }; diff --git a/src/EterLib/PacketReader.h b/src/EterLib/PacketReader.h new file mode 100644 index 0000000..7d46379 --- /dev/null +++ b/src/EterLib/PacketReader.h @@ -0,0 +1,157 @@ +#pragma once + +#include +#include +#include + +// PacketReader: Safe, bounds-checked packet deserialization from a read-only buffer. +// Used to parse incoming packets after the dispatch loop validates the header and length. +// +// Usage: +// PacketReader r(packetData, packetLength); +// uint16_t header = r.ReadU16(); +// uint16_t length = r.ReadU16(); +// uint8_t chatType = r.ReadU8(); +// char message[128]; +// r.ReadString(message, sizeof(message)); + +class PacketReader +{ +public: + PacketReader(const void* data, size_t size) + : m_buf(static_cast(data)) + , m_size(size) + , m_pos(0) + { + assert(data != nullptr || size == 0); + } + + // --- Read primitives --- + + uint8_t ReadU8() + { + assert(m_pos + sizeof(uint8_t) <= m_size); + return m_buf[m_pos++]; + } + + uint16_t ReadU16() + { + assert(m_pos + sizeof(uint16_t) <= m_size); + uint16_t v; + std::memcpy(&v, m_buf + m_pos, sizeof(v)); + m_pos += sizeof(v); + return v; + } + + uint32_t ReadU32() + { + assert(m_pos + sizeof(uint32_t) <= m_size); + uint32_t v; + std::memcpy(&v, m_buf + m_pos, sizeof(v)); + m_pos += sizeof(v); + return v; + } + + int8_t ReadI8() { return static_cast(ReadU8()); } + int16_t ReadI16() { return static_cast(ReadU16()); } + int32_t ReadI32() { return static_cast(ReadU32()); } + + uint64_t ReadU64() + { + assert(m_pos + sizeof(uint64_t) <= m_size); + uint64_t v; + std::memcpy(&v, m_buf + m_pos, sizeof(v)); + m_pos += sizeof(v); + return v; + } + + float ReadFloat() + { + assert(m_pos + sizeof(float) <= m_size); + float v; + std::memcpy(&v, m_buf + m_pos, sizeof(v)); + m_pos += sizeof(v); + return v; + } + + // Read raw bytes + bool ReadBytes(void* dest, size_t len) + { + if (m_pos + len > m_size) + return false; + std::memcpy(dest, m_buf + m_pos, len); + m_pos += len; + return true; + } + + // Read a fixed-length string (null-terminated in dest) + bool ReadString(char* dest, size_t fixedLen) + { + if (m_pos + fixedLen > m_size) + return false; + std::memcpy(dest, m_buf + m_pos, fixedLen); + dest[fixedLen - 1] = '\0'; // ensure null termination + m_pos += fixedLen; + return true; + } + + // Skip bytes without reading + bool Skip(size_t len) + { + if (m_pos + len > m_size) + return false; + m_pos += len; + return true; + } + + // --- Peek (non-consuming) --- + + uint8_t PeekU8() const + { + assert(m_pos + sizeof(uint8_t) <= m_size); + return m_buf[m_pos]; + } + + uint16_t PeekU16() const + { + assert(m_pos + sizeof(uint16_t) <= m_size); + uint16_t v; + std::memcpy(&v, m_buf + m_pos, sizeof(v)); + return v; + } + + uint16_t PeekU16At(size_t offset) const + { + assert(offset + sizeof(uint16_t) <= m_size); + uint16_t v; + std::memcpy(&v, m_buf + offset, sizeof(v)); + return v; + } + + // --- Read struct (for backward compatibility during migration) --- + // Reads a struct directly via memcpy. Use sparingly — prefer typed reads. + template + bool ReadStruct(T& out) + { + if (m_pos + sizeof(T) > m_size) + return false; + std::memcpy(&out, m_buf + m_pos, sizeof(T)); + m_pos += sizeof(T); + return true; + } + + // --- State --- + + bool HasBytes(size_t n) const { return (m_pos + n) <= m_size; } + size_t Remaining() const { return m_size - m_pos; } + size_t Position() const { return m_pos; } + size_t Size() const { return m_size; } + const uint8_t* Current() const { return m_buf + m_pos; } + + void Reset() { m_pos = 0; } + +private: + const uint8_t* m_buf; + size_t m_size; + size_t m_pos; +}; diff --git a/src/EterLib/PacketWriter.h b/src/EterLib/PacketWriter.h new file mode 100644 index 0000000..c2823e7 --- /dev/null +++ b/src/EterLib/PacketWriter.h @@ -0,0 +1,139 @@ +#pragma once + +#include +#include +#include + +// PacketWriter: Safe, bounds-checked packet serialization into a fixed buffer. +// Used to build outgoing packets before writing to the send buffer. +// +// Usage: +// uint8_t buf[128]; +// PacketWriter w(buf, sizeof(buf)); +// w.WriteU16(CG::CHAT); +// w.WriteU16(0); // placeholder for length +// w.WriteU8(chatType); +// w.WriteString(message, 128); +// w.PatchU16(2, w.Written()); // patch length at offset 2 +// stream.Send(w.Written(), buf); + +class PacketWriter +{ +public: + PacketWriter(void* buf, size_t capacity) + : m_buf(static_cast(buf)) + , m_capacity(capacity) + , m_pos(0) + { + assert(buf != nullptr); + assert(capacity > 0); + } + + // --- Write primitives --- + + bool WriteU8(uint8_t v) + { + if (m_pos + sizeof(v) > m_capacity) + return false; + m_buf[m_pos++] = v; + return true; + } + + bool WriteU16(uint16_t v) + { + if (m_pos + sizeof(v) > m_capacity) + return false; + std::memcpy(m_buf + m_pos, &v, sizeof(v)); + m_pos += sizeof(v); + return true; + } + + bool WriteU32(uint32_t v) + { + if (m_pos + sizeof(v) > m_capacity) + return false; + std::memcpy(m_buf + m_pos, &v, sizeof(v)); + m_pos += sizeof(v); + return true; + } + + bool WriteI8(int8_t v) { return WriteU8(static_cast(v)); } + bool WriteI16(int16_t v) { return WriteU16(static_cast(v)); } + bool WriteI32(int32_t v) { return WriteU32(static_cast(v)); } + + bool WriteU64(uint64_t v) + { + if (m_pos + sizeof(v) > m_capacity) + return false; + std::memcpy(m_buf + m_pos, &v, sizeof(v)); + m_pos += sizeof(v); + return true; + } + + bool WriteFloat(float v) + { + if (m_pos + sizeof(v) > m_capacity) + return false; + std::memcpy(m_buf + m_pos, &v, sizeof(v)); + m_pos += sizeof(v); + return true; + } + + // Write raw bytes + bool WriteBytes(const void* data, size_t len) + { + if (len == 0) + return true; + if (m_pos + len > m_capacity) + return false; + std::memcpy(m_buf + m_pos, data, len); + m_pos += len; + return true; + } + + // Write a fixed-length null-padded string + bool WriteString(const char* str, size_t fixedLen) + { + if (m_pos + fixedLen > m_capacity) + return false; + + size_t srcLen = str ? std::strlen(str) : 0; + size_t copyLen = (srcLen < fixedLen) ? srcLen : (fixedLen - 1); + + std::memcpy(m_buf + m_pos, str, copyLen); + std::memset(m_buf + m_pos + copyLen, 0, fixedLen - copyLen); + m_pos += fixedLen; + return true; + } + + // --- Patch: overwrite data at a previous offset --- + + bool PatchU16(size_t offset, uint16_t v) + { + if (offset + sizeof(v) > m_pos) + return false; + std::memcpy(m_buf + offset, &v, sizeof(v)); + return true; + } + + bool PatchU32(size_t offset, uint32_t v) + { + if (offset + sizeof(v) > m_pos) + return false; + std::memcpy(m_buf + offset, &v, sizeof(v)); + return true; + } + + // --- State --- + + size_t Written() const { return m_pos; } + size_t Remaining() const { return m_capacity - m_pos; } + const uint8_t* Data() const { return m_buf; } + + void Reset() { m_pos = 0; } + +private: + uint8_t* m_buf; + size_t m_capacity; + size_t m_pos; +}; diff --git a/src/EterLib/Profiler.h b/src/EterLib/Profiler.h index d021217..6f70f09 100644 --- a/src/EterLib/Profiler.h +++ b/src/EterLib/Profiler.h @@ -1,264 +1 @@ #pragma once - -#include "EterBase/Timer.h" -#include "EterBase/Debug.h" - -/* -class CProfiler : public CSingleton -{ - public: - enum - { - STACK_DATA_MAX_NUM = 64, - }; - - public: - typedef struct SProfileStackData - { - int iCallStep; - long iStartTime; - long iEndTime; - - std::string strName; - } TProfileStackData; - typedef struct SProfileAccumulationData - { - int iStartTime; - int iCallingCount; - int iCollapsedTime; - - std::string strName; - } TProfileAccumulationData; - - typedef std::map TGraphicTextInstanceMap; - typedef std::map TProfileAccumulationDataMap; - - public: - CProfiler() - { - Clear(); - m_ProfileAccumulationDataMap.clear(); - } - virtual ~CProfiler() - { - } - - void Clear() - { - m_ProfileStackDataCount = 0; - m_iCallStep = 0; - - TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin(); - for (; itor != m_ProfileAccumulationDataMap.end(); ++itor) - { - TProfileAccumulationData & rData = itor->second; - rData.iCallingCount = 0; - rData.iCollapsedTime = 0; - } - } - - void Push(const char * c_szName) - { - assert(m_ProfileStackDataCount < STACK_DATA_MAX_NUM); - TProfileStackData & rProfileStackData = m_ProfileStackDatas[m_ProfileStackDataCount++]; - - rProfileStackData.iCallStep = m_iCallStep; - rProfileStackData.iStartTime = ELTimer_GetMSec(); - rProfileStackData.strName = c_szName; - - ++m_iCallStep; - - TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(c_szName); - - if (m_GraphicTextInstanceMap.end() == itor) - { - CGraphicTextInstance * pGraphicTextInstance = CGraphicTextInstance::New(); - - CResource * pResource = CResourceManager::Instance().GetResourcePointer("굴림체.fnt"); - pGraphicTextInstance->Clear(); - pGraphicTextInstance->SetTextPointer(static_cast(pResource)); - - m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance)); - } - } - void Pop(const char * c_szName) - { - TProfileStackData * pProfileStackData; - - if (!GetProfileStackDataPointer(c_szName, &pProfileStackData)) - { - assert(!"The name doesn't exist"); - return; - } - - pProfileStackData->iEndTime = ELTimer_GetMSec(); - - --m_iCallStep; - } - - void PushAccumulation(const char * c_szName) - { - TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName); - - if (itor == m_ProfileAccumulationDataMap.end()) - { - TProfileAccumulationData ProfileAccumulationData; - ProfileAccumulationData.iCollapsedTime = 0; - ProfileAccumulationData.iCallingCount = 0; - ProfileAccumulationData.strName = c_szName; - m_ProfileAccumulationDataMap.insert(TProfileAccumulationDataMap::value_type(c_szName, ProfileAccumulationData)); - - itor = m_ProfileAccumulationDataMap.find(c_szName); - - ///// - - CGraphicTextInstance * pGraphicTextInstance = m_GraphicTextInstancePool.Alloc(); - - CResource * pResource = CResourceManager::Instance().GetResourcePointer("굴림체.fnt"); - pGraphicTextInstance->Clear(); - pGraphicTextInstance->SetTextPointer(static_cast(pResource)); - - m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance)); - } - - TProfileAccumulationData & rData = itor->second; - rData.iStartTime = ELTimer_GetMSec(); - } - - void PopAccumulation(const char * c_szName) - { - TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName); - - if (itor == m_ProfileAccumulationDataMap.end()) - return; - - TProfileAccumulationData & rData = itor->second; - rData.iCollapsedTime += ELTimer_GetMSec() - rData.iStartTime; - ++rData.iCallingCount; - } - - void ProfileByConsole() - { - for (int i = 0; i < m_ProfileStackDataCount; ++i) - { - TProfileStackData & rProfileStackData = m_ProfileStackDatas[i]; - -// for (int i = 0; i < rProfileStackData.iCallStep; ++i) -// Tracef("\t"); - - Tracef("%-10s: %2d\t", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime); - } - Tracef("\n"); - } - - void ProfileOneStackDataByConsole(const char * c_szName) - { - TProfileStackData * pProfileStackData; - - if (!GetProfileStackDataPointer(c_szName, &pProfileStackData)) - { - return; - } - - Tracef("%-10s: %3d\n", pProfileStackData->strName.c_str(), pProfileStackData->iEndTime - pProfileStackData->iStartTime); - } - - void ProfileOneAccumulationDataByConsole(const char * c_szName) - { - TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName); - if (itor == m_ProfileAccumulationDataMap.end()) - return; - - TProfileAccumulationData & rData = itor->second; - Tracef("%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]\n", rData.strName.c_str(), - rData.iCollapsedTime, - rData.iCallingCount); - } - - void ProfileByScreen() - { - float fxPosition = 0; - float fyPosition = 10; - - char szText[128]; - - for (int i = 0; i < m_ProfileStackDataCount; ++i) - { - TProfileStackData & rProfileStackData = m_ProfileStackDatas[i]; - - TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rProfileStackData.strName); - - if (m_GraphicTextInstanceMap.end() != itor) - { - CGraphicTextInstance * pGraphicTextInstance = itor->second; - - fxPosition = 10 + (float) rProfileStackData.iCallStep * 10 * 4; - - sprintf(szText, "%-10s : %3d", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime); - - pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f); - pGraphicTextInstance->SetValue(szText, strlen(szText)); - pGraphicTextInstance->SetPosition(fxPosition, fyPosition); - pGraphicTextInstance->Update(); - pGraphicTextInstance->Render(); - - fyPosition += 17; - } - } - - fxPosition = 10; - fyPosition += 10; - TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin(); - for (; itor != m_ProfileAccumulationDataMap.end(); ++itor) - { - TProfileAccumulationData & rData = itor->second; - TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rData.strName); - - if (m_GraphicTextInstanceMap.end() != itor) - { - CGraphicTextInstance * pGraphicTextInstance = itor->second; - - sprintf(szText, "%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]", rData.strName.c_str(), - rData.iCollapsedTime, - rData.iCallingCount); - - pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f); - pGraphicTextInstance->SetValue(szText, strlen(szText)); - pGraphicTextInstance->SetPosition(fxPosition, fyPosition); - pGraphicTextInstance->Update(); - pGraphicTextInstance->Render(); - - fyPosition += 17; - } - } - } - - protected: - bool GetProfileStackDataPointer(const char * c_szName, TProfileStackData ** ppProfileStackData) - { - for (int i = 0; i < m_ProfileStackDataCount; ++i) - { - if (0 == m_ProfileStackDatas[i].strName.compare(c_szName)) - { - *ppProfileStackData = &m_ProfileStackDatas[i]; - - return true; - } - } - - return false; - } - - protected: - // Profile Stack Data - int m_ProfileStackDataCount; - TProfileStackData m_ProfileStackDatas[STACK_DATA_MAX_NUM]; - - // Profile Increase Data - TProfileAccumulationDataMap m_ProfileAccumulationDataMap; - - int m_iCallStep; - - TGraphicTextInstanceMap m_GraphicTextInstanceMap; -}; -*/ \ No newline at end of file diff --git a/src/EterLib/RingBuffer.h b/src/EterLib/RingBuffer.h new file mode 100644 index 0000000..090346e --- /dev/null +++ b/src/EterLib/RingBuffer.h @@ -0,0 +1,191 @@ +#pragma once + +#include +#include +#include +#include +#include + +class RingBuffer +{ +public: + explicit RingBuffer(size_t initialCapacity = 0) + { + if (initialCapacity > 0) + m_data.resize(initialCapacity); + } + + ~RingBuffer() = default; + + // Non-copyable, movable + RingBuffer(const RingBuffer&) = delete; + RingBuffer& operator=(const RingBuffer&) = delete; + RingBuffer(RingBuffer&&) noexcept = default; + RingBuffer& operator=(RingBuffer&&) noexcept = default; + + // --- Capacity --- + + size_t ReadableBytes() const { return m_writePos - m_readPos; } + size_t WritableBytes() const { return m_data.size() - m_writePos; } + size_t Capacity() const { return m_data.size(); } + + void Reserve(size_t capacity) + { + if (capacity > m_data.size()) + { + Compact(); + m_data.resize(capacity); + } + } + + void EnsureWritable(size_t len) + { + if (WritableBytes() >= len) + return; + + // Try compaction first + Compact(); + if (WritableBytes() >= len) + return; + + // Must grow + size_t needed = m_writePos + len; + size_t newSize = m_data.size(); + if (newSize == 0) + newSize = 1024; + while (newSize < needed) + newSize *= 2; + + m_data.resize(newSize); + } + + // --- Write operations --- + + void Write(const void* data, size_t len) + { + if (len == 0) + return; + + assert(data != nullptr); + EnsureWritable(len); + std::memcpy(m_data.data() + m_writePos, data, len); + m_writePos += len; + } + + // Direct write access for socket recv() + uint8_t* WritePtr() + { + return m_data.data() + m_writePos; + } + + void CommitWrite(size_t len) + { + assert(m_writePos + len <= m_data.size()); + m_writePos += len; + } + + // --- Read operations --- + + bool HasBytes(size_t n) const { return ReadableBytes() >= n; } + + bool Peek(void* dest, size_t len) const + { + if (ReadableBytes() < len) + return false; + + std::memcpy(dest, m_data.data() + m_readPos, len); + return true; + } + + // Peek at a specific offset from read position (non-consuming) + bool PeekAt(size_t offset, void* dest, size_t len) const + { + if (ReadableBytes() < offset + len) + return false; + + std::memcpy(dest, m_data.data() + m_readPos + offset, len); + return true; + } + + bool Read(void* dest, size_t len) + { + if (!Peek(dest, len)) + return false; + + m_readPos += len; + MaybeCompact(); + return true; + } + + // Discard bytes without reading them + bool Discard(size_t len) + { + if (ReadableBytes() < len) + return false; + + m_readPos += len; + MaybeCompact(); + return true; + } + + // Direct read access for socket send() and packet processing + const uint8_t* ReadPtr() const + { + return m_data.data() + m_readPos; + } + + size_t ReadPos() const { return m_readPos; } + size_t WritePos() const { return m_writePos; } + + // --- Encryption support --- + // Get writable pointer to already-written data at a specific position + // Used for in-place encryption of data that was just written + uint8_t* DataAt(size_t pos) + { + assert(pos < m_data.size()); + return m_data.data() + pos; + } + + // --- Reset --- + + void Clear() + { + m_readPos = 0; + m_writePos = 0; + } + + // --- Compaction --- + + void Compact() + { + if (m_readPos == 0) + return; + + size_t readable = ReadableBytes(); + if (readable > 0) + std::memmove(m_data.data(), m_data.data() + m_readPos, readable); + + m_readPos = 0; + m_writePos = readable; + } + +private: + void MaybeCompact() + { + // Compact when read position passes halfway and there's no readable data + // or when read position is more than half the buffer + if (m_readPos == m_writePos) + { + m_readPos = 0; + m_writePos = 0; + } + else if (m_readPos > m_data.size() / 2) + { + Compact(); + } + } + + std::vector m_data; + size_t m_readPos = 0; + size_t m_writePos = 0; +}; diff --git a/src/GameLib/ActorInstance.cpp b/src/GameLib/ActorInstance.cpp index 9b12497..2fff89f 100644 --- a/src/GameLib/ActorInstance.cpp +++ b/src/GameLib/ActorInstance.cpp @@ -44,33 +44,6 @@ void CActorInstance::INSTANCEBASE_Transform() UpdateAttribute(); } -/* -void CActorInstance::TEMP_Update() -{ - //DWORD t1=ELTimer_GetMSec(); - OnUpdate(); - //DWORD t2=ELTimer_GetMSec(); - UpdateBoundingSphere(); - //DWORD t3=ELTimer_GetMSec(); - -#ifdef __PERFORMANCE_CHECKER__ - { - static FILE* fp=fopen("perf_actor_update.txt", "w"); - - if (t3-t1>3) - { - fprintf(fp, "AIU.Total %d (Time %f)\n", - t3-t1, ELTimer_GetMSec()/1000.0f); - fprintf(fp, "AIU.UP %d\n", t2-t1); - fprintf(fp, "AIU.UBS %d\n", t3-t2); - fprintf(fp, "-------------------------------- \n"); - fflush(fp); - } - fflush(fp); - } -#endif -} -*/ void CActorInstance::OnUpdate() { diff --git a/src/GameLib/ActorInstanceData.cpp b/src/GameLib/ActorInstanceData.cpp index 3f12c83..19f318e 100644 --- a/src/GameLib/ActorInstanceData.cpp +++ b/src/GameLib/ActorInstanceData.cpp @@ -294,36 +294,6 @@ void CActorInstance::ChangeMaterial(const char * c_szFileName) SetMaterialImagePointer(c_rkSkinItem.m_ePart, c_rkSkinItem.m_stSrcFileName.c_str(), static_cast(pkRes)); } -/* -void CActorInstance::SetPart(DWORD dwPartIndex, DWORD dwItemID) -{ - if (dwPartIndex>=CRaceData::PART_MAX_NUM) - return; - - if (!m_pkCurRaceData) - { - assert(m_pkCurRaceData); - return; - } - - CItemData * pItemData; - if (!CItemManager::Instance().GetItemDataPointer(dwItemID, &pItemData)) - return; - - RegisterModelThing(dwPartIndex, pItemData->GetModelThing()); - for (DWORD i = 0; i < pItemData->GetLODModelThingCount(); ++i) - { - CGraphicThing * pThing; - if (!pItemData->GetLODModelThingPointer(i, &pThing)) - continue; - - RegisterLODThing(dwPartIndex, pThing); - } - SetModelInstance(dwPartIndex, dwPartIndex, 0); - - m_adwPartItemID[dwPartIndex] = dwItemID; -} -*/ DWORD CActorInstance::GetPartItemID(DWORD dwPartIndex) { diff --git a/src/GameLib/Area.cpp b/src/GameLib/Area.cpp index 7a24814..ec67d82 100644 --- a/src/GameLib/Area.cpp +++ b/src/GameLib/Area.cpp @@ -737,107 +737,6 @@ void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_sz } -/* -void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName) -{ - // AABB를 사용한 충돌 정보 자동 생성. - const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName); - - CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName); - - CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc(); - pAttrInstance->Clear(); - pAttrInstance->SetObjectPointer(pAttributeData); - - if (false == bFileExist) - { - if (pAttributeData->IsEmpty()) - { - if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance) - { - CGraphicThingInstance* object = pObjectInstance->pThingInstance; - - D3DXVECTOR3 v3Min, v3Max; - - object->GetBoundingAABB(v3Min, v3Max); - - CStaticCollisionData collision; - collision.dwType = COLLISION_TYPE_AABB; - collision.quatRotation = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f); - strcpy(collision.szName, "DummyCollisionAABB"); - collision.v3Position = (v3Min + v3Max) * 0.5f; - - D3DXVECTOR3 vDelta = (v3Max - v3Min); - collision.fDimensions[0] = vDelta.x * 0.5f; // v3Min, v3Max를 구하기 위한 가로, 세로, 높이의 절반값 저장 - collision.fDimensions[1] = vDelta.y * 0.5f; - collision.fDimensions[2] = vDelta.z * 0.5f; - - - pAttributeData->AddCollisionData(collision); - } - } - } - - if (!pAttributeData->IsEmpty()) - { - pObjectInstance->pAttributeInstance = pAttrInstance; - } - else - { - pAttrInstance->Clear(); - ms_AttributeInstancePool.Free(pAttrInstance); - } -} -*/ -/* -void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName) -{ - // Sphere를 사용한 충돌 정보 자동 생성. - const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName); - - CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName); - - CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc(); - pAttrInstance->Clear(); - pAttrInstance->SetObjectPointer(pAttributeData); - - if (false == bFileExist) - { - if (pAttributeData->IsEmpty()) - { - if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance) - { - CGraphicThingInstance* object = pObjectInstance->pThingInstance; - - D3DXVECTOR3 v3Center; - float fRadius = 0.0f; - - object->GetBoundingSphere(v3Center, fRadius); - - CStaticCollisionData collision; - collision.dwType = COLLISION_TYPE_SPHERE; - collision.quatRotation = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f); - strcpy(collision.szName, "DummyCollisionSphere"); - collision.fDimensions[0] = fRadius * 0.25; - collision.v3Position = v3Center; - - pAttributeData->AddCollisionData(collision); - } - } - } - - if (!pAttributeData->IsEmpty()) - { - pObjectInstance->pAttributeInstance = pAttrInstance; - } - else - { - pAttrInstance->Clear(); - ms_AttributeInstancePool.Free(pAttrInstance); - } -} - -*/ bool CArea::Load(const char * c_szPathName) { diff --git a/src/GameLib/GameUtil.cpp b/src/GameLib/GameUtil.cpp index a1c1928..0eacde7 100644 --- a/src/GameLib/GameUtil.cpp +++ b/src/GameLib/GameUtil.cpp @@ -47,72 +47,6 @@ bool DetectCollisionDynamicSphereVSDynamicSphere(const CDynamicSphereInstance & float r = c_rSphere1.fRadius+c_rSphere2.fRadius; float rsq = r*r; - /*if (D3DXVec3LengthSq(&(c_rSphere1.v3Position -c_rSphere2.v3Position ))<=rsq) return true; - if (D3DXVec3LengthSq(&(c_rSphere1.v3Position -c_rSphere2.v3LastPosition ))<=rsq) return true; - if (D3DXVec3LengthSq(&(c_rSphere1.v3LastPosition -c_rSphere2.v3Position ))<=rsq) return true; - if (D3DXVec3LengthSq(&(c_rSphere1.v3LastPosition -c_rSphere2.v3LastPosition ))<=rsq) return true;*/ - - /* - if (square_distance_between_linesegment_and_point( - c_rSphere1.v3Position, - c_rSphere1.v3LastPosition, - c_rSphere2.v3Position - )<=rsq) return true; - if (square_distance_between_linesegment_and_point( - c_rSphere1.v3Position, - c_rSphere1.v3LastPosition, - c_rSphere2.v3LastPosition - )<=rsq) return true; - if (square_distance_between_linesegment_and_point( - c_rSphere2.v3Position, - c_rSphere2.v3LastPosition, - c_rSphere1.v3Position - )<=rsq) return true; - if (square_distance_between_linesegment_and_point( - c_rSphere2.v3Position, - c_rSphere2.v3LastPosition, - c_rSphere1.v3LastPosition - )<=rsq) return true; - - D3DXVECTOR3 da=c_rSphere1.v3Position-c_rSphere1.v3LastPosition; - D3DXVECTOR3 db=c_rSphere2.v3Position-c_rSphere2.v3LastPosition; - D3DXVECTOR3 n; - float la = D3DXVec3Length(&da); - float lb = D3DXVec3Length(&db); - if (la==0||lb==0) - { - D3DXVECTOR3 vA, vB; - IntersectLineSegments( - c_rSphere1.v3LastPosition.x,c_rSphere1.v3LastPosition.y,c_rSphere1.v3LastPosition.z, - c_rSphere1.v3Position.x, c_rSphere1.v3Position.y, c_rSphere1.v3Position.z, - c_rSphere2.v3LastPosition.x,c_rSphere2.v3LastPosition.y,c_rSphere2.v3LastPosition.z, - c_rSphere2.v3Position.x, c_rSphere2.v3Position.y, c_rSphere2.v3Position.z, - false, 1.e-5f, vA.x, vA.y, vA.z, vB.x, vB.y, vB.z); - return (D3DXVec3LengthSq(&(vA-vB))<=r*r); - } - D3DXVECTOR3 p=c_rSphere2.v3Position - c_rSphere1.v3LastPosition; - D3DXVec3Cross(&n, &da, &db); - float from_plane = D3DXVec3Dot(&n,&p)/la/lb; - if (from_plane>r || from_plane<-r) - return false; - p-=(from_plane/la/lb)*n; - float ta = D3DXVec3Dot(&p,&da)/la/la; - float tb = D3DXVec3Dot(&p,&db)/lb/lb; - - // FIXME 구 체크가 아니다 - - if (ta<0) - return false; - if (tb<0) - return false; - if (ta>1) - return false; - if (tb>1) - return false; - return true; - - */ - //*/ // using gpg line-collision // AABB check @@ -133,144 +67,14 @@ bool DetectCollisionDynamicSphereVSDynamicSphere(const CDynamicSphereInstance & if (mi4.y= 1.0f) - return false; - - return true;*/ } -/* -// Dynamic VS Static -bool DetectCollisionDynamicSphereVSStaticPlane(const CDynamicSphereInstance & c_rSphere, const TPlaneData & c_rPlane) -{ - D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position; - D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position; - - float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition); - float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition); - - if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f || (fPosition1) <= c_rSphere.fRadius && fPosition1 >= -c_rSphere.fRadius) - { - D3DXVECTOR3 v3QuadPosition1 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[0]; - D3DXVECTOR3 v3QuadPosition2 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[3]; - if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < c_rSphere.fRadius) - if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < c_rSphere.fRadius) - if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < c_rSphere.fRadius) - if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < c_rSphere.fRadius) - return true; - - } - - return false; -} - -bool DetectCollisionDynamicSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere, const TSphereData & c_rSphereData) -{ - D3DXVECTOR3 v3Distance = c_rSphere.v3Position - c_rSphereData.v3Position; - float fDistanceSq = D3DXVec3LengthSq(&v3Distance); - float fRadiusSummary = c_rSphere.fRadius + c_rSphereData.fRadius; - if (fDistanceSq < fRadiusSummary*fRadiusSummary) - return true; - - //D3DXVECTOR3 v3LastDistance = c_rSphere.v3LastPosition - c_rSphereData.v3Position; - //if (D3DXVec3Dot(&v3LastDistance, &v3Distance) < 0.0f) - // return true; - - return false; -} - -bool DetectCollisionDynamicSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinderData) -{ - if (c_rSphere.v3Position.z + c_rSphere.fRadius < c_rCylinderData.v3Position.z) - return false; - - if (c_rSphere.v3Position.z - c_rSphere.fRadius > c_rCylinderData.v3Position.z + c_rCylinderData.fHeight) - return false; - - D3DXVECTOR3 v3curDistance = c_rSphere.v3Position - c_rCylinderData.v3Position; - float fDistance = D3DXVec3Length(&v3curDistance); - - if (fDistance <= c_rSphere.fRadius + c_rCylinderData.fRadius) - return true; - - //D3DXVECTOR3 v3lastDistance = c_rSphere.v3LastPosition - c_rCylinderData.v3Position; - - //if (D3DXVec3Dot(&v3curDistance, &v3lastDistance) < 0.0f) - // return true; - - return false; -} -*/ -/* -bool DetectCollisionDynamicSphereVSStaticBox(const TSphereInstance & c_rSphere, const TBoxData & c_rBoxData) -{ - return false; -} -*/ -// Static VS Static -/* -bool DetectCollisionStaticSphereVSStaticSphere(const TSphereData & c_rSphere1, const TSphereData & c_rSphere2) -{ - D3DXVECTOR3 v3Distance = c_rSphere1.v3Position - c_rSphere2.v3Position; - float fDistance = D3DXVec3Length(&v3Distance); - - if (fDistance < c_rSphere1.fRadius + c_rSphere2.fRadius) - return true; - - return false; -} - -bool DetectCollisionStaticSphereVSStaticCylinder(const TSphereData & c_rSphere, const TCylinderData & c_rCylinder) -{ - return false; -} -*/ -/*bool DetectCollisionStaticSphereVSStaticBox(const TSphereData & c_rSphere, const TBoxData & c_rBox) -{ - return false; -} -*/ /////////////////////////////////////////////////////////////////////////////////////////////////// bool IsCWAcuteAngle(float begin, float end) @@ -402,33 +206,3 @@ float CharacterRotationToCameraRotation(float fCharacterRotation) return fmod((540.0f - fCharacterRotation), 360.0f); } -/* -bool DetectCollisionDynamicSphereVSStaticPlane(const TSphereInstance & c_rSphere, const TPlaneData & c_rPlane) -{ - D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position; - D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position; - - float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition); - float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition); - - if (fPosition1 * fPosition2 < 0.0f || fabs(fPosition1) <= c_rSphere.fRadius) - { - float fT = -fPosition1 / D3DXVec3Dot(&c_rPlane.v3Normal, &c_rSphere.v3Advance); - D3DXVECTOR3 v3CollisionPosition = c_rSphere.v3LastPosition + c_rSphere.v3Advance * fT; - D3DXVECTOR3 v3QuadPosition1 = v3CollisionPosition - c_rPlane.v3BeginPosition; - D3DXVECTOR3 v3QuadPosition2 = v3CollisionPosition - c_rPlane.v3EndPosition; - D3DXVec3Normalize(&v3QuadPosition1, &v3QuadPosition1); - D3DXVec3Normalize(&v3QuadPosition2, &v3QuadPosition2); - - if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < 0.0f) - if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < 0.0f) - if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < 0.0f) - if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < 0.0f) - { - return true; - } - } - - return false; -} -*/ diff --git a/src/GameLib/MapOutdoor.cpp b/src/GameLib/MapOutdoor.cpp index 749b484..d37c3bf 100644 --- a/src/GameLib/MapOutdoor.cpp +++ b/src/GameLib/MapOutdoor.cpp @@ -565,61 +565,6 @@ bool CMapOutdoor::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTO return false; } -/* -{ - bool bTerrainPick = false; - D3DXVECTOR3 v3TerrainPick; - - CTerrain * pTerrain; - - D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos; - float fRayRange; - rRay.GetStartPoint(&v3Start); - rRay.GetDirection(&v3Dir, &fRayRange); - rRay.GetEndPoint(&v3End); - - Vector3d v3dStart, v3dEnd; - v3dStart.Set(v3Start.x, v3Start.y, v3Start.z); - v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z); - - float fAdd = 1.0f / fRayRange; - - float ft = 0.0f; - while (ft < 1.0f) - { - D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, ft); - BYTE byTerrainNum; - float fMultiplier = 1.0f; - if (GetTerrainNum(v3CurPos.x, v3CurPos.y, &byTerrainNum)) - { - if (GetTerrainPointer(byTerrainNum, &pTerrain)) - { - int ix, iy; - PR_FLOAT_TO_INT(v3CurPos.x, ix); - PR_FLOAT_TO_INT(fabs(v3CurPos.y), iy); - float fMapHeight = pTerrain->GetHeight(ix, iy); - if ( fMapHeight >= v3CurPos.z) - { - bTerrainPick = true; - v3TerrainPick = v3CurPos; - break; - } - else - fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) ); - } - } - ft += fAdd * fMultiplier; - } - - if (bTerrainPick) - { - *v3IntersectPt = v3TerrainPick; - return true; - } - - return false; -} -*/ void CMapOutdoor::GetHeightMap(const BYTE & c_rucTerrainNum, WORD ** pwHeightMap) { diff --git a/src/GameLib/MapOutdoorQuadtree.cpp b/src/GameLib/MapOutdoorQuadtree.cpp index d7a7226..41b3e43 100644 --- a/src/GameLib/MapOutdoorQuadtree.cpp +++ b/src/GameLib/MapOutdoorQuadtree.cpp @@ -47,27 +47,6 @@ CTerrainQuadtreeNode * CMapOutdoor::AllocQuadTreeNode(long x0, long y0, long x1, Node->PatchNum = y0 * m_wPatchCount + x0; -/* - const float fTerrainMin = -(float) (m_lViewRadius * m_lCellScale); - - minx = fTerrainMin + x0 * c_byPatchSize * m_lCellScale; - maxx = fTerrainMin + (x1 + 1) * c_byPatchSize * m_lCellScale; - miny = fTerrainMin + y0 * c_byPatchSize * m_lCellScale; - maxy = fTerrainMin + (y1 + 1) * c_byPatchSize * m_lCellScale; - minz = 0.0f; - maxz = 0.0f; - - / * Set up 8 vertices that belong to the bounding box * / - Node->center.x = minx + (maxx - minx) * 0.5f; - Node->center.y = miny + (maxy - miny) * 0.5f; - Node->center.z = minz + (maxz - minz) * 0.5f; - - Node->radius = sqrtf( - (maxx-minx)*(maxx-minx)+ - (maxy-miny)*(maxy-miny)+ - (maxz-minz)*(maxz-minz) - )/2.0f; -*/ Node->center.x = 0.0f; Node->center.y = 0.0f; @@ -105,36 +84,6 @@ void CMapOutdoor::SubDivideNode(CTerrainQuadtreeNode * Node) SubDivideNode (tempnode); } -/* -void CMapOutdoor::RecurseDeleteQuadTree(CTerrainQuadtreeNode *Node) -{ - if (Node == NULL) - return; - - if (Node->NW_Node != NULL) - { - RecurseDeleteQuadTree(Node->NW_Node); - Node->NW_Node = NULL; - } - if (Node->NE_Node != NULL) - { - RecurseDeleteQuadTree(Node->NE_Node); - Node->NE_Node = NULL; - } - if (Node->SW_Node != NULL) - { - RecurseDeleteQuadTree(Node->SW_Node); - Node->SW_Node = NULL; - } - if (Node->SE_Node != NULL) - { - RecurseDeleteQuadTree(Node->SE_Node); - Node->SE_Node = NULL; - } - - free(Node); -} -*/ void CMapOutdoor::FreeQuadTree() { diff --git a/src/UserInterface/AbstractPlayer.h b/src/UserInterface/AbstractPlayer.h index fad023e..1184ee8 100644 --- a/src/UserInterface/AbstractPlayer.h +++ b/src/UserInterface/AbstractPlayer.h @@ -52,7 +52,6 @@ class IAbstractPlayer : public TAbstractSingleton virtual void NotifyChangePKMode() = 0; virtual void SetObserverMode(bool isEnable) = 0; - virtual void SetMobileFlag(BOOL bFlag) = 0; virtual void SetComboSkillFlag(BOOL bFlag) = 0; virtual void StartEmotionProcess() = 0; diff --git a/src/UserInterface/AccountConnector.cpp b/src/UserInterface/AccountConnector.cpp index e2e395f..2166f6b 100644 --- a/src/UserInterface/AccountConnector.cpp +++ b/src/UserInterface/AccountConnector.cpp @@ -63,19 +63,16 @@ bool CAccountConnector::__StateProcess() bool CAccountConnector::__HandshakeState_Process() { - if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) + if (!__AnalyzePacket(GC::PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) return false; - if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake)) + if (!__AnalyzePacket(GC::PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPingBase)) return false; - if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing)) + if (!__AnalyzePacket(GC::KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CAccountConnector::__AuthState_RecvKeyChallengeBase)) return false; - if (!__AnalyzePacket(HEADER_GC_KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CAccountConnector::__AuthState_RecvKeyChallenge)) - return false; - - if (!__AnalyzePacket(HEADER_GC_KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CAccountConnector::__AuthState_RecvKeyComplete)) + if (!__AnalyzePacket(GC::KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CAccountConnector::__AuthState_RecvKeyCompleteBase)) return false; return true; @@ -86,25 +83,22 @@ bool CAccountConnector::__AuthState_Process() if (!__AnalyzePacket(0, sizeof(BYTE), &CAccountConnector::__AuthState_RecvEmpty)) return true; - if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) + if (!__AnalyzePacket(GC::PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) return false; - if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing)) + if (!__AnalyzePacket(GC::PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPingBase)) return false; - if (!__AnalyzePacket(HEADER_GC_AUTH_SUCCESS, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthSuccess)) + if (!__AnalyzePacket(GC::AUTH_SUCCESS, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthSuccess)) return true; - if (!__AnalyzePacket(HEADER_GC_LOGIN_FAILURE, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthFailure)) + if (!__AnalyzePacket(GC::LOGIN_FAILURE, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthFailure)) return true; - if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake)) + if (!__AnalyzePacket(GC::KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CAccountConnector::__AuthState_RecvKeyChallengeBase)) return false; - if (!__AnalyzePacket(HEADER_GC_KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CAccountConnector::__AuthState_RecvKeyChallenge)) - return false; - - if (!__AnalyzePacket(HEADER_GC_KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CAccountConnector::__AuthState_RecvKeyComplete)) + if (!__AnalyzePacket(GC::KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CAccountConnector::__AuthState_RecvKeyCompleteBase)) return false; return true; @@ -130,7 +124,8 @@ bool CAccountConnector::__AuthState_RecvPhase() else if (kPacketPhase.phase == PHASE_AUTH) { TPacketCGLogin3 LoginPacket; - LoginPacket.header = HEADER_CG_LOGIN3; + LoginPacket.header = CG::LOGIN3; + LoginPacket.length = sizeof(LoginPacket); strncpy(LoginPacket.name, m_strID.c_str(), ID_MAX_NUM); strncpy(LoginPacket.pwd, m_strPassword.c_str(), PASS_MAX_NUM); @@ -149,133 +144,15 @@ bool CAccountConnector::__AuthState_RecvPhase() return false; } - if (!SendSequence()) - { - return false; - } - __AuthState_Set(); } return true; } -bool CAccountConnector::__AuthState_RecvHandshake() -{ - TPacketGCHandshake kPacketHandshake; - if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake)) - return false; - - Tracenf("HANDSHAKE RECV %u %d", kPacketHandshake.dwTime, kPacketHandshake.lDelta); - - ELTimer_SetServerMSec(kPacketHandshake.dwTime+ kPacketHandshake.lDelta); - - kPacketHandshake.dwTime = kPacketHandshake.dwTime + kPacketHandshake.lDelta + kPacketHandshake.lDelta; - kPacketHandshake.lDelta = 0; - - Tracenf("HANDSHAKE SEND %u", kPacketHandshake.dwTime); - - if (!Send(sizeof(kPacketHandshake), &kPacketHandshake)) - { - Tracen(" CAccountConnector::__AuthState_RecvHandshake - SendHandshake Error"); - return false; - } - - return true; -} - -bool CAccountConnector::__AuthState_RecvKeyChallenge() -{ - TPacketGCKeyChallenge packet; - if (!Recv(sizeof(packet), &packet)) - return false; - - Tracen("KEY_CHALLENGE RECV - Starting secure key exchange"); - - SecureCipher& cipher = GetSecureCipher(); - if (!cipher.Initialize()) - { - Tracen("SecureCipher initialization failed"); - Disconnect(); - return false; - } - - if (!cipher.ComputeClientKeys(packet.server_pk)) - { - Tracen("Failed to compute client session keys"); - Disconnect(); - return false; - } - - TPacketCGKeyResponse response; - response.bHeader = HEADER_CG_KEY_RESPONSE; - cipher.GetPublicKey(response.client_pk); - cipher.ComputeResponse(packet.challenge, response.challenge_response); - - if (!Send(sizeof(response), &response)) - { - Tracen("Failed to send key response"); - return false; - } - - Tracen("KEY_RESPONSE SEND - Awaiting key completion"); - return true; -} - -bool CAccountConnector::__AuthState_RecvKeyComplete() -{ - TPacketGCKeyComplete packet; - if (!Recv(sizeof(packet), &packet)) - return false; - - Tracen("KEY_COMPLETE RECV - Decrypting session token"); - - SecureCipher& cipher = GetSecureCipher(); - - uint8_t session_token[SecureCipher::SESSION_TOKEN_SIZE]; - if (crypto_aead_xchacha20poly1305_ietf_decrypt( - session_token, nullptr, - nullptr, - packet.encrypted_token, sizeof(packet.encrypted_token), - nullptr, 0, - packet.nonce, - cipher.GetRxKey()) != 0) - { - Tracen("Failed to decrypt session token - authentication failed"); - Disconnect(); - return false; - } - - cipher.SetSessionToken(session_token); - cipher.SetActivated(true); - DecryptPendingRecvData(); - - Tracen("Secure channel established - encryption activated"); - return true; -} - -bool CAccountConnector::__AuthState_RecvPing() -{ - TPacketGCPing kPacketPing; - if (!Recv(sizeof(kPacketPing), &kPacketPing)) - return false; - - __AuthState_SendPong(); - - return true; -} - -bool CAccountConnector::__AuthState_SendPong() -{ - TPacketCGPong kPacketPong; - kPacketPong.bHeader = HEADER_CG_PONG; - kPacketPong.bSequence = GetNextSequence(); - - if (!Send(sizeof(kPacketPong), &kPacketPong)) - return false; - - return true; -} +// Key exchange (RecvKeyChallenge, RecvKeyComplete) and ping/pong (RecvPingPacket) +// are now handled by CNetworkStream base class. Thin wrappers in the header +// delegate __AnalyzePacket dispatch to those base methods. bool CAccountConnector::__AuthState_RecvAuthSuccess() { @@ -315,11 +192,11 @@ bool CAccountConnector::__AuthState_RecvAuthFailure() bool CAccountConnector::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)()) { - BYTE bHeader; - if (!Peek(sizeof(bHeader), &bHeader)) + uint16_t wHeader; + if (!Peek(sizeof(wHeader), &wHeader)) return true; - if (bHeader!=uHeader) + if (wHeader != uHeader) return true; if (!Peek(uPacketSize)) diff --git a/src/UserInterface/AccountConnector.h b/src/UserInterface/AccountConnector.h index 54fd1b2..e116836 100644 --- a/src/UserInterface/AccountConnector.h +++ b/src/UserInterface/AccountConnector.h @@ -44,13 +44,13 @@ class CAccountConnector : public CNetworkStream, public CSingleton old %f", v3NewEye.z, m_v3Eye.z); - SetEye(v3NewEye); - } - } - - if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraBackToTerrainRay, &v3CollisionPoint)) - { - if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < m_fTerrainCollisionRadius) - { - D3DXVECTOR3 v3NewEye = v3CollisionPoint + m_fTerrainCollisionRadius * m_v3View; - //printf("CameraBackToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); - SetEye(v3NewEye); - } - } - - // Left - if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraLeftToTerrainRay, &v3CollisionPoint)) - { - SetCameraState(CAMERA_STATE_CANTGOLEFT); - if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 3.0f * m_fTerrainCollisionRadius) - { - D3DXVECTOR3 v3NewEye = v3CollisionPoint + 3.0f * m_fTerrainCollisionRadius * m_v3Cross; - //printf("CameraLeftToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); - SetEye(v3NewEye); - } - } - else - SetCameraState(CAMERA_STATE_NORMAL); - - // Right - if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraRightToTerrainRay, &v3CollisionPoint)) - { - SetCameraState(CAMERA_STATE_CANTGORIGHT); - if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 3.0f * m_fTerrainCollisionRadius) - { - D3DXVECTOR3 v3NewEye = v3CollisionPoint - 3.0f * m_fTerrainCollisionRadius * m_v3Cross; - //printf("CameraRightToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); - SetEye(v3NewEye); - } - } - else - SetCameraState(CAMERA_STATE_NORMAL); - */ } struct CameraCollisionChecker diff --git a/src/UserInterface/GuildMarkDownloader.cpp b/src/UserInterface/GuildMarkDownloader.cpp index 05e3614..8a34ad2 100644 --- a/src/UserInterface/GuildMarkDownloader.cpp +++ b/src/UserInterface/GuildMarkDownloader.cpp @@ -147,9 +147,9 @@ void CGuildMarkDownloader::__LoginState_Set() bool CGuildMarkDownloader::__LoginState_Process() { - BYTE header; + uint16_t header; - if (!Peek(sizeof(BYTE), &header)) + if (!Peek(sizeof(uint16_t), &header)) return true; if (IsSecurityMode()) @@ -158,11 +158,11 @@ bool CGuildMarkDownloader::__LoginState_Process() { if (!Recv(sizeof(header), &header)) return false; - + return true; } } - + UINT needPacketSize = __GetPacketSize(header); if (!needPacketSize) @@ -180,23 +180,21 @@ UINT CGuildMarkDownloader::__GetPacketSize(UINT header) { switch (header) { - case HEADER_GC_PHASE: + case GC::PHASE: return sizeof(TPacketGCPhase); - case HEADER_GC_HANDSHAKE: - return sizeof(TPacketGCHandshake); - case HEADER_GC_PING: + case GC::PING: return sizeof(TPacketGCPing); - case HEADER_GC_MARK_IDXLIST: + case GC::MARK_IDXLIST: return sizeof(TPacketGCMarkIDXList); - case HEADER_GC_MARK_BLOCK: + case GC::MARK_BLOCK: return sizeof(TPacketGCMarkBlock); - case HEADER_GC_GUILD_SYMBOL_DATA: + case GC::SYMBOL_DATA: return sizeof(TPacketGCGuildSymbolData); - case HEADER_GC_MARK_DIFF_DATA: + case GC::MARK_DIFF_DATA: return sizeof(BYTE); - case HEADER_GC_KEY_CHALLENGE: + case GC::KEY_CHALLENGE: return sizeof(TPacketGCKeyChallenge); - case HEADER_GC_KEY_COMPLETE: + case GC::KEY_COMPLETE: return sizeof(TPacketGCKeyComplete); } return 0; @@ -206,63 +204,28 @@ bool CGuildMarkDownloader::__DispatchPacket(UINT header) { switch (header) { - case HEADER_GC_PHASE: + case GC::PHASE: return __LoginState_RecvPhase(); - case HEADER_GC_HANDSHAKE: - return __LoginState_RecvHandshake(); - case HEADER_GC_PING: - return __LoginState_RecvPing(); - case HEADER_GC_MARK_IDXLIST: + case GC::PING: + return RecvPingPacket(); + case GC::MARK_IDXLIST: return __LoginState_RecvMarkIndex(); - case HEADER_GC_MARK_BLOCK: + case GC::MARK_BLOCK: return __LoginState_RecvMarkBlock(); - case HEADER_GC_GUILD_SYMBOL_DATA: + case GC::SYMBOL_DATA: return __LoginState_RecvSymbolData(); - case HEADER_GC_MARK_DIFF_DATA: + case GC::MARK_DIFF_DATA: return true; - case HEADER_GC_KEY_CHALLENGE: - return __LoginState_RecvKeyChallenge(); - case HEADER_GC_KEY_COMPLETE: - return __LoginState_RecvKeyComplete(); + case GC::KEY_CHALLENGE: + return RecvKeyChallenge(); + case GC::KEY_COMPLETE: + return __LoginState_RecvKeyCompleteAndLogin(); } return false; } // END_OF_MARK_BUG_FIX -bool CGuildMarkDownloader::__LoginState_RecvHandshake() -{ - TPacketGCHandshake kPacketHandshake; - if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake)) - return false; - - TPacketCGMarkLogin kPacketMarkLogin; - - kPacketMarkLogin.header = HEADER_CG_MARK_LOGIN; - kPacketMarkLogin.handle = m_dwHandle; - kPacketMarkLogin.random_key = m_dwRandomKey; - - if (!Send(sizeof(kPacketMarkLogin), &kPacketMarkLogin)) - return false; - - return true; -} - -bool CGuildMarkDownloader::__LoginState_RecvPing() -{ - TPacketGCPing kPacketPing; - - if (!Recv(sizeof(kPacketPing), &kPacketPing)) - return false; - - TPacketCGPong kPacketPong; - kPacketPong.bHeader = HEADER_CG_PONG; - kPacketPong.bSequence = GetNextSequence(); - - if (!Send(sizeof(TPacketCGPong), &kPacketPong)) - return false; - - return true; -} +// Ping/pong now handled by CNetworkStream::RecvPingPacket() bool CGuildMarkDownloader::__LoginState_RecvPhase() { @@ -304,7 +267,8 @@ bool CGuildMarkDownloader::__LoginState_RecvPhase() bool CGuildMarkDownloader::__SendMarkIDXList() { TPacketCGMarkIDXList kPacketMarkIDXList; - kPacketMarkIDXList.header = HEADER_CG_MARK_IDXLIST; + kPacketMarkIDXList.header = CG::MARK_IDXLIST; + kPacketMarkIDXList.length = sizeof(kPacketMarkIDXList); if (!Send(sizeof(kPacketMarkIDXList), &kPacketMarkIDXList)) return false; @@ -354,7 +318,8 @@ bool CGuildMarkDownloader::__SendMarkCRCList() } else { - kPacketMarkCRCList.header = HEADER_CG_MARK_CRCLIST; + kPacketMarkCRCList.header = CG::MARK_CRCLIST; + kPacketMarkCRCList.length = sizeof(kPacketMarkCRCList); kPacketMarkCRCList.imgIdx = m_currentRequestingImageIndex; ++m_currentRequestingImageIndex; @@ -417,62 +382,24 @@ bool CGuildMarkDownloader::__LoginState_RecvMarkBlock() } // END_OF_MARK_BUG_FIX -bool CGuildMarkDownloader::__LoginState_RecvKeyChallenge() +// RecvKeyChallenge now handled by CNetworkStream::RecvKeyChallenge() + +// RecvKeyComplete + mark-specific login authentication +bool CGuildMarkDownloader::__LoginState_RecvKeyCompleteAndLogin() { - TPacketGCKeyChallenge packet; - if (!Recv(sizeof(packet), &packet)) + if (!CNetworkStream::RecvKeyComplete()) return false; - Tracen("KEY_CHALLENGE RECV"); + // Send mark login (authentication) now that secure channel is established + TPacketCGMarkLogin kPacketMarkLogin; + kPacketMarkLogin.header = CG::MARK_LOGIN; + kPacketMarkLogin.length = sizeof(kPacketMarkLogin); + kPacketMarkLogin.handle = m_dwHandle; + kPacketMarkLogin.random_key = m_dwRandomKey; - SecureCipher& cipher = GetSecureCipher(); - if (!cipher.Initialize()) - { - Disconnect(); - return false; - } - - if (!cipher.ComputeClientKeys(packet.server_pk)) - { - Disconnect(); - return false; - } - - TPacketCGKeyResponse response; - response.bHeader = HEADER_CG_KEY_RESPONSE; - cipher.GetPublicKey(response.client_pk); - cipher.ComputeResponse(packet.challenge, response.challenge_response); - - if (!Send(sizeof(response), &response)) + if (!Send(sizeof(kPacketMarkLogin), &kPacketMarkLogin)) return false; - Tracen("KEY_RESPONSE SENT"); - return true; -} - -bool CGuildMarkDownloader::__LoginState_RecvKeyComplete() -{ - TPacketGCKeyComplete packet; - if (!Recv(sizeof(packet), &packet)) - return false; - - Tracen("KEY_COMPLETE RECV"); - - SecureCipher& cipher = GetSecureCipher(); - - uint8_t session_token[SecureCipher::SESSION_TOKEN_SIZE]; - if (!cipher.DecryptToken(packet.encrypted_token, sizeof(packet.encrypted_token), - packet.nonce, session_token)) - { - Disconnect(); - return false; - } - - cipher.SetSessionToken(session_token); - cipher.SetActivated(true); - DecryptPendingRecvData(); - - Tracen("SECURE CIPHER ACTIVATED"); return true; } @@ -481,7 +408,8 @@ bool CGuildMarkDownloader::__SendSymbolCRCList() for (DWORD i=0; i GetRecvBufferSize()) + if (packet.length > GetRecvBufferSize()) return true; ////////////////////////////////////////////////////////////// @@ -515,7 +443,7 @@ bool CGuildMarkDownloader::__LoginState_RecvSymbolData() if (!Recv(sizeof(kPacketSymbolData), &kPacketSymbolData)) return false; - WORD wDataSize = kPacketSymbolData.size - sizeof(kPacketSymbolData); + WORD wDataSize = kPacketSymbolData.length - sizeof(kPacketSymbolData); DWORD dwGuildID = kPacketSymbolData.guild_id; BYTE * pbyBuf = new BYTE [wDataSize]; diff --git a/src/UserInterface/GuildMarkDownloader.h b/src/UserInterface/GuildMarkDownloader.h index ab43bcc..52de306 100644 --- a/src/UserInterface/GuildMarkDownloader.h +++ b/src/UserInterface/GuildMarkDownloader.h @@ -49,13 +49,10 @@ class CGuildMarkDownloader : public CNetworkStream, public CSingleton(fileSize)); + fread(m_symbolBuf.data(), m_symbolBuf.size(), 1, file); fclose(file); m_dwSymbolCRC32 = GetFileCRC32(c_szFileName); @@ -222,13 +221,7 @@ void CGuildMarkUploader::__Inialize() m_dwHandle = 0; m_dwRandomKey = 0; - if (m_pbySymbolBuf) - { - delete[] m_pbySymbolBuf; - } - - m_dwSymbolBufSize = 0; - m_pbySymbolBuf = NULL; + m_symbolBuf.clear(); } bool CGuildMarkUploader::__StateProcess() @@ -263,19 +256,16 @@ void CGuildMarkUploader::__LoginState_Set() bool CGuildMarkUploader::__LoginState_Process() { - if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CGuildMarkUploader::__LoginState_RecvPhase)) + if (!__AnalyzePacket(GC::PHASE, sizeof(TPacketGCPhase), &CGuildMarkUploader::__LoginState_RecvPhase)) return false; - if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CGuildMarkUploader::__LoginState_RecvHandshake)) + if (!__AnalyzePacket(GC::PING, sizeof(TPacketGCPing), &CGuildMarkUploader::__LoginState_RecvPingBase)) return false; - if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CGuildMarkUploader::__LoginState_RecvPing)) + if (!__AnalyzePacket(GC::KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CGuildMarkUploader::__LoginState_RecvKeyChallengeBase)) return false; - if (!__AnalyzePacket(HEADER_GC_KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CGuildMarkUploader::__LoginState_RecvKeyChallenge)) - return false; - - if (!__AnalyzePacket(HEADER_GC_KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CGuildMarkUploader::__LoginState_RecvKeyComplete)) + if (!__AnalyzePacket(GC::KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CGuildMarkUploader::__LoginState_RecvKeyCompleteAndLogin)) return false; return true; @@ -284,7 +274,8 @@ bool CGuildMarkUploader::__LoginState_Process() bool CGuildMarkUploader::__SendMarkPacket() { TPacketCGMarkUpload kPacketMarkUpload; - kPacketMarkUpload.header=HEADER_CG_MARK_UPLOAD; + kPacketMarkUpload.header=CG::MARK_UPLOAD; + kPacketMarkUpload.length = sizeof(kPacketMarkUpload); kPacketMarkUpload.gid=m_dwGuildID; assert(sizeof(kPacketMarkUpload.image) == sizeof(m_kMark.m_apxBuf)); @@ -297,21 +288,21 @@ bool CGuildMarkUploader::__SendMarkPacket() } bool CGuildMarkUploader::__SendSymbolPacket() { - if (!m_pbySymbolBuf) + if (m_symbolBuf.empty()) return false; TPacketCGSymbolUpload kPacketSymbolUpload; - kPacketSymbolUpload.header=HEADER_CG_GUILD_SYMBOL_UPLOAD; + kPacketSymbolUpload.header=CG::GUILD_SYMBOL_UPLOAD; kPacketSymbolUpload.handle=m_dwGuildID; - kPacketSymbolUpload.size=sizeof(TPacketCGSymbolUpload) + m_dwSymbolBufSize; + kPacketSymbolUpload.length=sizeof(TPacketCGSymbolUpload) + static_cast(m_symbolBuf.size()); if (!Send(sizeof(TPacketCGSymbolUpload), &kPacketSymbolUpload)) return false; - if (!Send(m_dwSymbolBufSize, m_pbySymbolBuf)) + if (!Send(static_cast(m_symbolBuf.size()), m_symbolBuf.data())) return false; #ifdef _DEBUG - printf("__SendSymbolPacket : [GuildID:%d/PacketSize:%d/BufSize:%d/CRC:%d]\n", m_dwGuildID, kPacketSymbolUpload.size, m_dwSymbolBufSize, m_dwSymbolCRC32); + printf("__SendSymbolPacket : [GuildID:%d/PacketSize:%d/BufSize:%d/CRC:%d]\n", m_dwGuildID, kPacketSymbolUpload.length, (int)m_symbolBuf.size(), m_dwSymbolCRC32); #endif CNetworkStream::__SendInternalBuffer(); @@ -343,106 +334,35 @@ bool CGuildMarkUploader::__LoginState_RecvPhase() return true; } -bool CGuildMarkUploader::__LoginState_RecvHandshake() +// Ping/pong and key challenge now handled by CNetworkStream base class. +// Thin wrappers in the header delegate __AnalyzePacket dispatch to those base methods. + +// RecvKeyComplete + mark-specific login authentication +bool CGuildMarkUploader::__LoginState_RecvKeyCompleteAndLogin() { - TPacketGCHandshake kPacketHandshake; - if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake)) + if (!CNetworkStream::RecvKeyComplete()) return false; - { - TPacketCGMarkLogin kPacketMarkLogin; - kPacketMarkLogin.header=HEADER_CG_MARK_LOGIN; - kPacketMarkLogin.handle=m_dwHandle; - kPacketMarkLogin.random_key=m_dwRandomKey; - if (!Send(sizeof(kPacketMarkLogin), &kPacketMarkLogin)) - return false; - } + // Send mark login (authentication) now that secure channel is established + TPacketCGMarkLogin kPacketMarkLogin; + kPacketMarkLogin.header = CG::MARK_LOGIN; + kPacketMarkLogin.length = sizeof(kPacketMarkLogin); + kPacketMarkLogin.handle = m_dwHandle; + kPacketMarkLogin.random_key = m_dwRandomKey; - return true; -} - -bool CGuildMarkUploader::__LoginState_RecvPing() -{ - TPacketGCPing kPacketPing; - if (!Recv(sizeof(kPacketPing), &kPacketPing)) + if (!Send(sizeof(kPacketMarkLogin), &kPacketMarkLogin)) return false; - TPacketCGPong kPacketPong; - kPacketPong.bHeader = HEADER_CG_PONG; - kPacketPong.bSequence = GetNextSequence(); - - if (!Send(sizeof(TPacketCGPong), &kPacketPong)) - return false; - - return true; -} - -bool CGuildMarkUploader::__LoginState_RecvKeyChallenge() -{ - TPacketGCKeyChallenge packet; - if (!Recv(sizeof(packet), &packet)) - return false; - - Tracen("KEY_CHALLENGE RECV"); - - SecureCipher& cipher = GetSecureCipher(); - if (!cipher.Initialize()) - { - Disconnect(); - return false; - } - - if (!cipher.ComputeClientKeys(packet.server_pk)) - { - Disconnect(); - return false; - } - - TPacketCGKeyResponse response; - response.bHeader = HEADER_CG_KEY_RESPONSE; - cipher.GetPublicKey(response.client_pk); - cipher.ComputeResponse(packet.challenge, response.challenge_response); - - if (!Send(sizeof(response), &response)) - return false; - - Tracen("KEY_RESPONSE SENT"); - return true; -} - -bool CGuildMarkUploader::__LoginState_RecvKeyComplete() -{ - TPacketGCKeyComplete packet; - if (!Recv(sizeof(packet), &packet)) - return false; - - Tracen("KEY_COMPLETE RECV"); - - SecureCipher& cipher = GetSecureCipher(); - - uint8_t session_token[SecureCipher::SESSION_TOKEN_SIZE]; - if (!cipher.DecryptToken(packet.encrypted_token, sizeof(packet.encrypted_token), - packet.nonce, session_token)) - { - Disconnect(); - return false; - } - - cipher.SetSessionToken(session_token); - cipher.SetActivated(true); - DecryptPendingRecvData(); - - Tracen("SECURE CIPHER ACTIVATED"); return true; } bool CGuildMarkUploader::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CGuildMarkUploader::*pfnDispatchPacket)()) { - BYTE bHeader; - if (!Peek(sizeof(bHeader), &bHeader)) + uint16_t wHeader; + if (!Peek(sizeof(wHeader), &wHeader)) return true; - if (bHeader!=uHeader) + if (wHeader != uHeader) return true; if (!Peek(uPacketSize)) diff --git a/src/UserInterface/GuildMarkUploader.h b/src/UserInterface/GuildMarkUploader.h index a01ffad..a24e60a 100644 --- a/src/UserInterface/GuildMarkUploader.h +++ b/src/UserInterface/GuildMarkUploader.h @@ -86,13 +86,14 @@ class CGuildMarkUploader : public CNetworkStream, public CSingleton m_symbolBuf; }; #endif \ No newline at end of file diff --git a/src/UserInterface/InstanceBase.cpp b/src/UserInterface/InstanceBase.cpp index ca709ea..aa68eef 100644 --- a/src/UserInterface/InstanceBase.cpp +++ b/src/UserInterface/InstanceBase.cpp @@ -1164,11 +1164,6 @@ float CInstanceBase::GetLocalTime() return m_GraphicThingInstance.GetLocalTime(); } - -void CInstanceBase::PushUDPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) -{ -} - DWORD ELTimer_GetServerFrameMSec(); void CInstanceBase::PushTCPStateExpanded(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg, UINT uTargetVID) @@ -2688,29 +2683,6 @@ DWORD CInstanceBase::GetWeaponType() return pItemData->GetWeaponType(); } -/* -void CInstanceBase::SetParts(const WORD * c_pParts) -{ - if (IsPoly()) - return; - - if (__IsShapeAnimalWear()) - return; - - UINT eWeapon=c_pParts[CRaceData::PART_WEAPON]; - - if (__IsChangableWeapon(eWeapon) == false) - eWeapon = 0; - - if (eWeapon != m_GraphicThingInstance.GetPartItemID(CRaceData::PART_WEAPON)) - { - m_GraphicThingInstance.AttachPart(CRaceData::PART_MAIN, CRaceData::PART_WEAPON, eWeapon); - m_awPart[CRaceData::PART_WEAPON] = eWeapon; - } - - __AttachHorseSaddle(); -} -*/ void CInstanceBase::__ClearWeaponRefineEffect() { diff --git a/src/UserInterface/InstanceBase.h b/src/UserInterface/InstanceBase.h index 9b819a1..a64fbd5 100644 --- a/src/UserInterface/InstanceBase.h +++ b/src/UserInterface/InstanceBase.h @@ -621,7 +621,6 @@ class CInstanceBase // Battle void SetEventHandler(CActorInstance::IEventHandler* pkEventHandler); - void PushUDPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg); void PushTCPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg); void PushTCPStateExpanded(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg, UINT uTargetVID); diff --git a/src/UserInterface/InstanceBaseEffect.cpp b/src/UserInterface/InstanceBaseEffect.cpp index 0c97120..f940849 100644 --- a/src/UserInterface/InstanceBaseEffect.cpp +++ b/src/UserInterface/InstanceBaseEffect.cpp @@ -17,26 +17,6 @@ std::string CInstanceBase::ms_astAffectEffectAttachBone[EFFECT_NUM]; #define BYTE_COLOR_TO_D3DX_COLOR(r, g, b) D3DXCOLOR(float(r)/255.0f, float(g)/255.0f, float(b)/255.0f, 1.0f) -/* -D3DXCOLOR CInstanceBase::ms_kD3DXClrPC(0xFFFFD84D);//1.0f, 0.8470f, 0.3f, 1.0f -D3DXCOLOR CInstanceBase::ms_kD3DXClrNPC(0xFF7BE85E);//0.4823f, 0.9098f, 0.3686f, 1.0f -D3DXCOLOR CInstanceBase::ms_kD3DXClrMOB(0xFFEC170a);//0.9254f, 0.0901f, 0.0392f, 1.0f -D3DXCOLOR CInstanceBase::ms_kD3DXClrPVP(0xFF8532D9); -D3DXCOLOR CInstanceBase::ms_kD3DXClrPVPSelf(0xFFEE36DF); -D3DXCOLOR CInstanceBase::ms_kD3DXClrKiller = BYTE_COLOR_TO_D3DX_COLOR(180, 100, 0); -D3DXCOLOR CInstanceBase::ms_kD3DXClrTitle[CInstanceBase::TITLE_MAX_NUM] = -{ - BYTE_COLOR_TO_D3DX_COLOR( 0, 204, 255), - BYTE_COLOR_TO_D3DX_COLOR( 0, 144, 255), - BYTE_COLOR_TO_D3DX_COLOR( 92, 110, 255), - BYTE_COLOR_TO_D3DX_COLOR(155, 155, 255), - 0xFFFFFFFF, // None - BYTE_COLOR_TO_D3DX_COLOR(207, 117, 0), - BYTE_COLOR_TO_D3DX_COLOR(235, 83, 0), - BYTE_COLOR_TO_D3DX_COLOR(227, 0, 0), - BYTE_COLOR_TO_D3DX_COLOR(255, 0, 0), -}; -*/ D3DXCOLOR g_akD3DXClrTitle[CInstanceBase::TITLE_NUM]; D3DXCOLOR g_akD3DXClrName[CInstanceBase::NAMECOLOR_NUM]; @@ -86,14 +66,17 @@ const D3DXCOLOR& CInstanceBase::GetIndexedNameColor(UINT eNameColor) void CInstanceBase::AddDamageEffect(DWORD damage, BYTE flag, BOOL bSelf, BOOL bTarget) { + TraceError("AddDamageEffect: damage=%u flag=%u bSelf=%d bTarget=%d IsShowDamage=%d", + damage, flag, bSelf, bTarget, CPythonSystem::Instance().IsShowDamage()); if(CPythonSystem::Instance().IsShowDamage()) - { + { SEffectDamage sDamage; sDamage.bSelf = bSelf; sDamage.bTarget = bTarget; sDamage.damage = damage; sDamage.flag = flag; m_DamageQueue.push_back(sDamage); + TraceError("AddDamageEffect: Queued, queue size now=%d", m_DamageQueue.size()); } } @@ -102,6 +85,8 @@ void CInstanceBase::ProcessDamage() if(m_DamageQueue.empty()) return; + TraceError("ProcessDamage: Queue not empty, processing..."); + SEffectDamage sDamage = m_DamageQueue.front(); m_DamageQueue.pop_front(); @@ -111,11 +96,13 @@ void CInstanceBase::ProcessDamage() BOOL bSelf = sDamage.bSelf; BOOL bTarget = sDamage.bTarget; - CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + TraceError("ProcessDamage: damage=%u flag=%u bSelf=%d bTarget=%d", damage, flag, bSelf, bTarget); + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); float cameraAngle = GetDegreeFromPosition2(pCamera->GetTarget().x,pCamera->GetTarget().y,pCamera->GetEye().x,pCamera->GetEye().y); DWORD FONT_WIDTH = 30; - + CEffectManager& rkEftMgr=CEffectManager::Instance(); D3DXVECTOR3 v3Pos = m_GraphicThingInstance.GetPosition(); @@ -125,6 +112,7 @@ void CInstanceBase::ProcessDamage() if ( (flag & DAMAGE_DODGE) || (flag & DAMAGE_BLOCK) ) { + TraceError("ProcessDamage: DODGE or BLOCK"); if(bSelf) rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[EFFECT_DAMAGE_MISS],v3Pos,v3Rot); else @@ -134,6 +122,7 @@ void CInstanceBase::ProcessDamage() } else if (flag & DAMAGE_CRITICAL) { + TraceError("ProcessDamage: CRITICAL"); //rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[EFFECT_DAMAGE_CRITICAL],v3Pos,v3Rot); //return; 숫자도 표시. } @@ -151,6 +140,7 @@ void CInstanceBase::ProcessDamage() { if (bSelf) { + TraceError("ProcessDamage: bSelf path - damage_"); strDamageType = "damage_"; if (m_bDamageEffectType == 0) @@ -162,6 +152,8 @@ void CInstanceBase::ProcessDamage() } else if (!bTarget || ((IsAffect(AFFECT_INVISIBILITY) || IsAffect(AFFECT_EUNHYEONG)) && bTarget)) { + TraceError("ProcessDamage: non-target path (early return) bTarget=%d INVIS=%d EUNHYEONG=%d", + bTarget, IsAffect(AFFECT_INVISIBILITY), IsAffect(AFFECT_EUNHYEONG)); strDamageType = "nontarget_"; rdwCRCEft = EFFECT_DAMAGE_NOT_TARGET; @@ -169,11 +161,15 @@ void CInstanceBase::ProcessDamage() } else { + TraceError("ProcessDamage: target path - target_"); strDamageType = "target_"; rdwCRCEft = EFFECT_DAMAGE_TARGET; } } + TraceError("ProcessDamage: Creating effect strDamageType=%s rdwCRCEft=%u effectCRC=%u", + strDamageType.c_str(), rdwCRCEft, ms_adwCRCAffectEffect[rdwCRCEft]); + DWORD index = 0; DWORD num = 0; std::vector textures; @@ -192,9 +188,11 @@ void CInstanceBase::ProcessDamage() char numBuf[MAX_PATH]; sprintf(numBuf, "%d.dds", num); textures.push_back("d:/ymir work/effect/affect/damagevalue/" +strDamageType + numBuf); - + + TraceError("ProcessDamage: texture path=%s", textures.back().c_str()); + rkEftMgr.SetEffectTextures(ms_adwCRCAffectEffect[rdwCRCEft],textures); - + D3DXMATRIX matrix, matTrans; D3DXMatrixIdentity(&matrix); @@ -210,9 +208,10 @@ void CInstanceBase::ProcessDamage() matrix = matTrans*matrix; D3DXMatrixMultiply(&matrix, &pCamera->GetViewMatrix(), &matrix); - - rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[rdwCRCEft], D3DXVECTOR3(matrix._41, matrix._42, matrix._43) - ,v3Rot); + + DWORD effectResult = rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[rdwCRCEft], D3DXVECTOR3(matrix._41, matrix._42, matrix._43) + ,v3Rot); + TraceError("ProcessDamage: CreateEffect returned %u", effectResult); textures.clear(); @@ -887,35 +886,6 @@ void CInstanceBase::__SetAffect(UINT eAffect, bool isVisible) if (IsAffect(AFFECT_INVISIBILITY)) return; break; -/* - case AFFECT_GWIGEOM: // 전기 속성 공격으로 바뀔 예정 - if (isVisible) - { - m_GraphicThingInstance.SetBattleHitEffect(ms_adwCRCAffectEffect[EFFECT_ELECTRIC_HIT]); - m_GraphicThingInstance.SetBattleAttachEffect(ms_adwCRCAffectEffect[EFFECT_ELECTRIC_ATTACH]); - } - else - { - m_GraphicThingInstance.SetBattleHitEffect(ms_adwCRCAffectEffect[EFFECT_HIT]); - m_GraphicThingInstance.SetBattleAttachEffect(0); - } - return; - break; - case AFFECT_HWAYEOM: // 화염 속성 공격으로 바뀔 예정 - if (isVisible) - { - m_GraphicThingInstance.SetBattleHitEffect(ms_adwCRCAffectEffect[EFFECT_FLAME_HIT]); - m_GraphicThingInstance.SetBattleAttachEffect(ms_adwCRCAffectEffect[EFFECT_FLAME_ATTACH]); - } - else - { - m_GraphicThingInstance.SetBattleHitEffect(ms_adwCRCAffectEffect[EFFECT_HIT]); - m_GraphicThingInstance.SetBattleAttachEffect(0); - } - // 화염참은 공격할 때만 일시적으로 Visible 합니다. - return; - break; -*/ case AFFECT_CHEONGEUN: m_GraphicThingInstance.SetResistFallen(isVisible); break; diff --git a/src/UserInterface/Packet.h b/src/UserInterface/Packet.h index 6a46605..5da251f 100644 --- a/src/UserInterface/Packet.h +++ b/src/UserInterface/Packet.h @@ -1,319 +1,440 @@ #pragma once -#include "Gamelib/RaceData.h" #include "StdAfx.h" - #include "GameType.h" -typedef uint8_t TPacketHeader; +#include -enum +// Control-plane structs + headers (shared with EterLib/NetStream base class) +#include "EterLib/ControlPackets.h" + +// +// Packet header constants (uint16_t) +// +// Packet framing: [header:2] [length:2] [payload...] +// - header: one of the constants below +// - length: total packet size including header+length (minimum 4) +// - payload: packet-specific data +// +// Ranges: +// 0x0001-0x00FF Control (handshake, phase, ping, key exchange) +// 0x0100-0x01FF Authentication (login, auth, empire) +// 0x0200-0x02FF Character (create, delete, select, stats) +// 0x0300-0x03FF Movement (move, sync, warp) +// 0x0400-0x04FF Combat (attack, skill, damage, pvp) +// 0x0500-0x05FF Items (use, drop, move, exchange, refine) +// 0x0600-0x06FF Chat (chat, whisper) +// 0x0700-0x07FF Social (party, guild, messenger) +// 0x0800-0x08FF Shop/Trade (shop, safebox, mall) +// 0x0900-0x09FF Quest (script, quest confirm) +// 0x0A00-0x0AFF UI/Effect (target, affect, effects) +// 0x0B00-0x0BFF World (dungeon, fishing, land, time) +// 0x0C00-0x0CFF Guild Marks +// + +// Packet header type (used by dispatch/registration systems) +typedef uint16_t TPacketHeader; + +// Minimum packet size: header(2) + length(2) +constexpr uint16_t PACKET_HEADER_SIZE = 4; + +// ============================================================================ +// CG -- Client -> Game +// ============================================================================ +namespace CG { - ///////////////////////////////////////////////// - // To Server - // HEADER_BLANK is the not use(for future use) - HEADER_CG_ATTACK = 2, - HEADER_CG_CHAT = 3, - HEADER_CG_PLAYER_CREATE = 4, // 새로운 플래이어를 생성 - HEADER_CG_PLAYER_DESTROY = 5, // 플래이어를 삭제. - HEADER_CG_PLAYER_SELECT = 6, - HEADER_CG_CHARACTER_MOVE = 7, - HEADER_CG_SYNC_POSITION = 8, - HEADER_CG_DIRECT_ENTER = 9, - HEADER_CG_ENTERGAME = 10, - HEADER_CG_ITEM_USE = 11, - HEADER_CG_ITEM_DROP = 12, - HEADER_CG_ITEM_MOVE = 13, - HEADER_CG_ITEM_PICKUP = 15, - HEADER_CG_QUICKSLOT_ADD = 16, - HEADER_CG_QUICKSLOT_DEL = 17, - HEADER_CG_QUICKSLOT_SWAP = 18, - HEADER_CG_WHISPER = 19, - HEADER_CG_ITEM_DROP2 = 20, - //HEADER_BLANK21 = 21, - //HEADER_BLANK22 = 22, - //HEADER_BLANK22 = 23, - //HEADER_BLANK24 = 24, - //HEADER_BLANK25 = 25, - HEADER_CG_ON_CLICK = 26, - HEADER_CG_EXCHANGE = 27, - HEADER_CG_CHARACTER_POSITION = 28, - HEADER_CG_SCRIPT_ANSWER = 29, - HEADER_CG_QUEST_INPUT_STRING = 30, - HEADER_CG_QUEST_CONFIRM = 31, - HEADER_CG_QUEST_CANCEL = 32, - //HEADER_BLANK33 = 33, - //HEADER_BLANK34 = 34, - //HEADER_BLANK35 = 35, - //HEADER_BLANK36 = 36, - //HEADER_BLANK37 = 37, - //HEADER_BLANK38 = 38, - //HEADER_BLANK39 = 39, - //HEADER_BLANK40 = 40, - HEADER_CG_PVP = 41, - //HEADER_BLANK42 = 42, - //HEADER_BLANK43 = 43, - //HEADER_BLANK44 = 44, - //HEADER_BLANK45 = 45, - //HEADER_BLANK46 = 46, - //HEADER_BLANK47 = 47, - //HEADER_BLANK48 = 48, - //HEADER_BLANK49 = 49, - HEADER_CG_SHOP = 50, - HEADER_CG_FLY_TARGETING = 51, - HEADER_CG_USE_SKILL = 52, - HEADER_CG_ADD_FLY_TARGETING = 53, - HEADER_CG_SHOOT = 54, - HEADER_CG_MYSHOP = 55, - //HEADER_BLANK56 = 56, - //HEADER_BLANK57 = 57, - //HEADER_BLANK58 = 58, - //HEADER_BLANK59 = 59, - HEADER_CG_ITEM_USE_TO_ITEM = 60, - HEADER_CG_TARGET = 61, - //HEADER_BLANK62 = 62, - //HEADER_BLANK63 = 63, - //HEADER_BLANK64 = 64, - HEADER_CG_WARP = 65, - HEADER_CG_SCRIPT_BUTTON = 66, - HEADER_CG_MESSENGER = 67, - //HEADER_BLANK68 = 68, - HEADER_CG_MALL_CHECKOUT = 69, - HEADER_CG_SAFEBOX_CHECKIN = 70, // 아이템을 창고에 넣는다. - HEADER_CG_SAFEBOX_CHECKOUT = 71, // 아이템을 창고로 부터 빼온다. - HEADER_CG_PARTY_INVITE = 72, - HEADER_CG_PARTY_INVITE_ANSWER = 73, - HEADER_CG_PARTY_REMOVE = 74, - HEADER_CG_PARTY_SET_STATE = 75, - HEADER_CG_PARTY_USE_SKILL = 76, - HEADER_CG_SAFEBOX_ITEM_MOVE = 77, - HEADER_CG_PARTY_PARAMETER = 78, - //HEADER_BLANK68 = 79, - HEADER_CG_GUILD = 80, - HEADER_CG_ANSWER_MAKE_GUILD = 81, - HEADER_CG_FISHING = 82, - HEADER_CG_GIVE_ITEM = 83, - //HEADER_BLANK84 = 84, - //HEADER_BLANK85 = 85, - //HEADER_BLANK86 = 86, - //HEADER_BLANK87 = 87, - //HEADER_BLANK88 = 88, - //HEADER_BLANK89 = 89, - HEADER_CG_EMPIRE = 90, - //HEADER_BLANK91 = 91, - //HEADER_BLANK92 = 92, - //HEADER_BLANK93 = 93, - //HEADER_BLANK94 = 94, - //HEADER_BLANK95 = 95, - HEADER_CG_REFINE = 96, - //HEADER_BLANK97 = 97, - //HEADER_BLANK98 = 98, - //HEADER_BLANK99 = 99, + // Control (PONG, KEY_RESPONSE moved to EterLib/ControlPackets.h) + constexpr uint16_t CLIENT_VERSION = 0x000D; + constexpr uint16_t STATE_CHECKER = 0x000F; + constexpr uint16_t TEXT = 0x0011; - HEADER_CG_MARK_LOGIN = 100, - HEADER_CG_MARK_CRCLIST = 101, - HEADER_CG_MARK_UPLOAD = 102, - HEADER_CG_MARK_IDXLIST = 104, + // Authentication + constexpr uint16_t LOGIN2 = 0x0101; + constexpr uint16_t LOGIN3 = 0x0102; + constexpr uint16_t LOGIN_SECURE = 0x0103; + constexpr uint16_t EMPIRE = 0x010A; + constexpr uint16_t CHANGE_NAME = 0x010B; - HEADER_CG_CRC_REPORT = 103, - - HEADER_CG_HACK = 105, - HEADER_CG_CHANGE_NAME = 106, - HEADER_CG_SMS = 107, - HEADER_CG_LOGIN2 = 109, - HEADER_CG_DUNGEON = 110, - HEADER_CG_LOGIN3 = 111, - HEADER_CG_GUILD_SYMBOL_UPLOAD = 112, - HEADER_CG_GUILD_SYMBOL_CRC = 113, - HEADER_CG_SCRIPT_SELECT_ITEM = 114, - HEADER_CG_LOGIN4 = 115, + // Character + constexpr uint16_t CHARACTER_CREATE = 0x0201; + constexpr uint16_t CHARACTER_DELETE = 0x0202; + constexpr uint16_t CHARACTER_SELECT = 0x0203; + constexpr uint16_t ENTERGAME = 0x0204; - HEADER_CG_DRAGON_SOUL_REFINE = 205, - HEADER_CG_STATE_CHECKER = 206, + // Movement + constexpr uint16_t MOVE = 0x0301; + constexpr uint16_t SYNC_POSITION = 0x0303; + constexpr uint16_t WARP = 0x0305; - HEADER_CG_KEY_RESPONSE = 0xf9, // Secure key exchange response - HEADER_CG_LOGIN_SECURE = 0xf6, // Secure login packet - HEADER_CG_TIME_SYNC = 0xfc, - HEADER_CG_CLIENT_VERSION = 0xfd, - HEADER_CG_CLIENT_VERSION2 = 0xf1, - HEADER_CG_PONG = 0xfe, - HEADER_CG_HANDSHAKE = 0xff, - ///////////////////////////////////////////////// - // From Server + // Combat + constexpr uint16_t ATTACK = 0x0401; + constexpr uint16_t USE_SKILL = 0x0402; + constexpr uint16_t SHOOT = 0x0403; + constexpr uint16_t FLY_TARGETING = 0x0404; + constexpr uint16_t ADD_FLY_TARGETING = 0x0405; - HEADER_GC_CHARACTER_ADD = 1, - HEADER_GC_CHARACTER_DEL = 2, - HEADER_GC_CHARACTER_MOVE = 3, - HEADER_GC_CHAT = 4, - HEADER_GC_SYNC_POSITION = 5, - HEADER_GC_LOGIN_SUCCESS3 = 6, - HEADER_GC_LOGIN_FAILURE = 7, - HEADER_GC_PLAYER_CREATE_SUCCESS = 8, - HEADER_GC_PLAYER_CREATE_FAILURE = 9, - HEADER_GC_PLAYER_DELETE_SUCCESS = 10, - HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID = 11, - // 12 - HEADER_GC_STUN = 13, - HEADER_GC_DEAD = 14, + // Items + constexpr uint16_t ITEM_USE = 0x0501; + constexpr uint16_t ITEM_DROP = 0x0502; + constexpr uint16_t ITEM_DROP2 = 0x0503; + constexpr uint16_t ITEM_MOVE = 0x0504; + constexpr uint16_t ITEM_PICKUP = 0x0505; + constexpr uint16_t ITEM_USE_TO_ITEM = 0x0506; + constexpr uint16_t ITEM_GIVE = 0x0507; + constexpr uint16_t EXCHANGE = 0x0508; + constexpr uint16_t QUICKSLOT_ADD = 0x0509; + constexpr uint16_t QUICKSLOT_DEL = 0x050A; + constexpr uint16_t QUICKSLOT_SWAP = 0x050B; + constexpr uint16_t REFINE = 0x050C; + constexpr uint16_t DRAGON_SOUL_REFINE = 0x050D; - HEADER_GC_MAIN_CHARACTER = 15, - HEADER_GC_PLAYER_POINTS = 16, - HEADER_GC_PLAYER_POINT_CHANGE = 17, - HEADER_GC_CHANGE_SPEED = 18, - HEADER_GC_CHARACTER_UPDATE = 19, + // Chat + constexpr uint16_t CHAT = 0x0601; + constexpr uint16_t WHISPER = 0x0602; - HEADER_GC_ITEM_DEL = 20, // 아이템 창에 추가 - HEADER_GC_ITEM_SET = 21, // 아이템 창에 추가 - HEADER_GC_ITEM_USE = 22, // 아이템 사용 (주위 사람들에게 보여주기 위해) - HEADER_GC_ITEM_DROP = 23, // 아이템 버리기 - HEADER_GC_ITEM_UPDATE = 25, // 아이템 수치 업데이트 + // Social + constexpr uint16_t PARTY_INVITE = 0x0701; + constexpr uint16_t PARTY_INVITE_ANSWER = 0x0702; + constexpr uint16_t PARTY_REMOVE = 0x0703; + constexpr uint16_t PARTY_SET_STATE = 0x0704; + constexpr uint16_t PARTY_USE_SKILL = 0x0705; + constexpr uint16_t PARTY_PARAMETER = 0x0706; + constexpr uint16_t GUILD = 0x0720; + constexpr uint16_t ANSWER_MAKE_GUILD = 0x0721; + constexpr uint16_t GUILD_SYMBOL_UPLOAD = 0x0722; + constexpr uint16_t SYMBOL_CRC = 0x0723; + constexpr uint16_t MESSENGER = 0x0740; - HEADER_GC_ITEM_GROUND_ADD = 26, // 바닥에 아이템 추가 - HEADER_GC_ITEM_GROUND_DEL = 27, // 바닥에서 아이템 삭제 - HEADER_GC_QUICKSLOT_ADD = 28, - HEADER_GC_QUICKSLOT_DEL = 29, - HEADER_GC_QUICKSLOT_SWAP = 30, - HEADER_GC_ITEM_OWNERSHIP = 31, - HEADER_GC_LOGIN_SUCCESS4 = 32, - HEADER_GC_ITEM_UNBIND_TIME = 33, - HEADER_GC_WHISPER = 34, - HEADER_GC_ALERT = 35, + // Shop / Safebox / Mall + constexpr uint16_t SHOP = 0x0801; + constexpr uint16_t MYSHOP = 0x0802; + constexpr uint16_t SAFEBOX_CHECKIN = 0x0820; + constexpr uint16_t SAFEBOX_CHECKOUT = 0x0821; + constexpr uint16_t SAFEBOX_ITEM_MOVE = 0x0822; + constexpr uint16_t MALL_CHECKOUT = 0x0840; - HEADER_GC_MOTION = 36, + // Quest + constexpr uint16_t SCRIPT_ANSWER = 0x0901; + constexpr uint16_t SCRIPT_BUTTON = 0x0902; + constexpr uint16_t SCRIPT_SELECT_ITEM = 0x0903; + constexpr uint16_t QUEST_INPUT_STRING = 0x0904; + constexpr uint16_t QUEST_CONFIRM = 0x0905; + constexpr uint16_t QUEST_CANCEL = 0x0906; - HEADER_GC_SHOP = 38, - HEADER_GC_SHOP_SIGN = 39, + // UI / Targeting + constexpr uint16_t TARGET = 0x0A01; + constexpr uint16_t ON_CLICK = 0x0A02; + constexpr uint16_t CHARACTER_POSITION = 0x0A60; - // 39 ~ 41 Balnk - HEADER_GC_DUEL_START = 40, - HEADER_GC_PVP = 41, - HEADER_GC_EXCHANGE = 42, - HEADER_GC_CHARACTER_POSITION = 43, + // World + constexpr uint16_t FISHING = 0x0B01; + constexpr uint16_t DUNGEON = 0x0B02; + constexpr uint16_t HACK = 0x0B03; - HEADER_GC_PING = 44, + // Guild Marks + constexpr uint16_t MARK_LOGIN = 0x0C01; + constexpr uint16_t MARK_CRCLIST = 0x0C02; + constexpr uint16_t MARK_UPLOAD = 0x0C03; + constexpr uint16_t MARK_IDXLIST = 0x0C04; +} - HEADER_GC_SCRIPT = 45, - HEADER_GC_QUEST_CONFIRM = 46, +// ============================================================================ +// GC -- Game -> Client +// ============================================================================ +namespace GC +{ + // Control (PING, PHASE, KEY_CHALLENGE, KEY_COMPLETE moved to EterLib/ControlPackets.h) + constexpr uint16_t RESPOND_CHANNELSTATUS = 0x0010; - HEADER_GC_MOUNT = 61, - HEADER_GC_OWNERSHIP = 62, - HEADER_GC_TARGET = 63, - HEADER_GC_WARP = 65, - HEADER_GC_ADD_FLY_TARGETING = 69, + // Authentication + constexpr uint16_t LOGIN_SUCCESS3 = 0x0104; + constexpr uint16_t LOGIN_SUCCESS4 = 0x0105; + constexpr uint16_t LOGIN_FAILURE = 0x0106; + constexpr uint16_t LOGIN_KEY = 0x0107; + constexpr uint16_t AUTH_SUCCESS = 0x0108; + constexpr uint16_t EMPIRE = 0x0109; + constexpr uint16_t CHANGE_NAME = 0x010C; - HEADER_GC_CREATE_FLY = 70, - HEADER_GC_FLY_TARGETING = 71, - HEADER_GC_SKILL_LEVEL = 72, - HEADER_GC_SKILL_COOLTIME_END = 73, - HEADER_GC_MESSENGER = 74, - HEADER_GC_GUILD = 75, - HEADER_GC_SKILL_LEVEL_NEW = 76, + // Character + constexpr uint16_t CHARACTER_ADD = 0x0205; + constexpr uint16_t CHARACTER_ADD2 = 0x0206; + constexpr uint16_t CHAR_ADDITIONAL_INFO = 0x0207; + constexpr uint16_t CHARACTER_DEL = 0x0208; + constexpr uint16_t CHARACTER_UPDATE = 0x0209; + constexpr uint16_t CHARACTER_UPDATE2 = 0x020A; + constexpr uint16_t CHARACTER_POSITION = 0x020B; + constexpr uint16_t PLAYER_CREATE_SUCCESS = 0x020C; + constexpr uint16_t PLAYER_CREATE_FAILURE = 0x020D; + constexpr uint16_t PLAYER_DELETE_SUCCESS = 0x020E; + constexpr uint16_t PLAYER_DELETE_WRONG_SOCIAL_ID = 0x020F; + constexpr uint16_t MAIN_CHARACTER = 0x0210; + constexpr uint16_t PLAYER_POINTS = 0x0214; + constexpr uint16_t PLAYER_POINT_CHANGE = 0x0215; + constexpr uint16_t STUN = 0x0216; + constexpr uint16_t DEAD = 0x0217; + constexpr uint16_t CHANGE_SPEED = 0x0218; + constexpr uint16_t WALK_MODE = 0x0219; + constexpr uint16_t SKILL_LEVEL = 0x021A; + constexpr uint16_t SKILL_LEVEL_NEW = 0x021B; + constexpr uint16_t SKILL_COOLTIME_END = 0x021C; + constexpr uint16_t CHANGE_SKILL_GROUP = 0x021D; + constexpr uint16_t VIEW_EQUIP = 0x021E; - HEADER_GC_PARTY_INVITE = 77, - HEADER_GC_PARTY_ADD = 78, - HEADER_GC_PARTY_UPDATE = 79, - HEADER_GC_PARTY_REMOVE = 80, + // Movement + constexpr uint16_t MOVE = 0x0302; + constexpr uint16_t SYNC_POSITION = 0x0304; + constexpr uint16_t WARP = 0x0306; + constexpr uint16_t MOTION = 0x0307; + constexpr uint16_t DIG_MOTION = 0x0308; - HEADER_GC_QUEST_INFO = 81, - HEADER_GC_REQUEST_MAKE_GUILD = 82, - HEADER_GC_PARTY_PARAMETER = 83, + // Combat + constexpr uint16_t DAMAGE_INFO = 0x0410; + constexpr uint16_t FLY_TARGETING = 0x0411; + constexpr uint16_t ADD_FLY_TARGETING = 0x0412; + constexpr uint16_t CREATE_FLY = 0x0413; + constexpr uint16_t PVP = 0x0414; + constexpr uint16_t DUEL_START = 0x0415; - HEADER_GC_SAFEBOX_MONEY_CHANGE = 84, - HEADER_GC_SAFEBOX_SET = 85, - HEADER_GC_SAFEBOX_DEL = 86, - HEADER_GC_SAFEBOX_WRONG_PASSWORD = 87, - HEADER_GC_SAFEBOX_SIZE = 88, + // Items + constexpr uint16_t ITEM_DEL = 0x0510; + constexpr uint16_t ITEM_SET = 0x0511; + constexpr uint16_t ITEM_USE = 0x0512; + constexpr uint16_t ITEM_DROP = 0x0513; + constexpr uint16_t ITEM_UPDATE = 0x0514; + constexpr uint16_t ITEM_GROUND_ADD = 0x0515; + constexpr uint16_t ITEM_GROUND_DEL = 0x0516; + constexpr uint16_t ITEM_OWNERSHIP = 0x0517; + constexpr uint16_t ITEM_GET = 0x0518; + constexpr uint16_t QUICKSLOT_ADD = 0x0519; + constexpr uint16_t QUICKSLOT_DEL = 0x051A; + constexpr uint16_t QUICKSLOT_SWAP = 0x051B; + constexpr uint16_t EXCHANGE = 0x051C; + constexpr uint16_t REFINE_INFORMATION = 0x051D; + constexpr uint16_t REFINE_INFORMATION_NEW = 0x051E; + constexpr uint16_t DRAGON_SOUL_REFINE = 0x051F; - HEADER_GC_FISHING = 89, + // Chat + constexpr uint16_t CHAT = 0x0603; + constexpr uint16_t WHISPER = 0x0604; - HEADER_GC_EMPIRE = 90, + // Social + constexpr uint16_t PARTY_INVITE = 0x0710; + constexpr uint16_t PARTY_ADD = 0x0711; + constexpr uint16_t PARTY_UPDATE = 0x0712; + constexpr uint16_t PARTY_REMOVE = 0x0713; + constexpr uint16_t PARTY_LINK = 0x0714; + constexpr uint16_t PARTY_UNLINK = 0x0715; + constexpr uint16_t PARTY_PARAMETER = 0x0716; + constexpr uint16_t GUILD = 0x0730; + constexpr uint16_t REQUEST_MAKE_GUILD = 0x0731; + constexpr uint16_t SYMBOL_DATA = 0x0732; + constexpr uint16_t MESSENGER = 0x0741; + constexpr uint16_t LOVER_INFO = 0x0750; + constexpr uint16_t LOVE_POINT_UPDATE = 0x0751; - HEADER_GC_PARTY_LINK = 91, - HEADER_GC_PARTY_UNLINK = 92, + // Shop / Safebox / Mall + constexpr uint16_t SHOP = 0x0810; + constexpr uint16_t SHOP_SIGN = 0x0811; + constexpr uint16_t SAFEBOX_SET = 0x0830; + constexpr uint16_t SAFEBOX_DEL = 0x0831; + constexpr uint16_t SAFEBOX_WRONG_PASSWORD = 0x0832; + constexpr uint16_t SAFEBOX_SIZE = 0x0833; + constexpr uint16_t SAFEBOX_MONEY_CHANGE = 0x0834; + constexpr uint16_t MALL_OPEN = 0x0841; + constexpr uint16_t MALL_SET = 0x0842; + constexpr uint16_t MALL_DEL = 0x0843; - HEADER_GC_REFINE_INFORMATION = 95, + // Quest + constexpr uint16_t SCRIPT = 0x0910; + constexpr uint16_t QUEST_CONFIRM = 0x0911; + constexpr uint16_t QUEST_INFO = 0x0912; - HEADER_GC_OBSERVER_ADD = 96, - HEADER_GC_OBSERVER_REMOVE = 97, - HEADER_GC_OBSERVER_MOVE = 98, - HEADER_GC_VIEW_EQUIP = 99, + // UI / Effects / Targeting + constexpr uint16_t TARGET = 0x0A10; + constexpr uint16_t TARGET_UPDATE = 0x0A11; + constexpr uint16_t TARGET_DELETE = 0x0A12; + constexpr uint16_t TARGET_CREATE_NEW = 0x0A13; + constexpr uint16_t AFFECT_ADD = 0x0A20; + constexpr uint16_t AFFECT_REMOVE = 0x0A21; + constexpr uint16_t SEPCIAL_EFFECT = 0x0A30; + constexpr uint16_t SPECIFIC_EFFECT = 0x0A31; + constexpr uint16_t MOUNT = 0x0A40; + constexpr uint16_t OWNERSHIP = 0x0A41; + constexpr uint16_t NPC_POSITION = 0x0A50; - HEADER_GC_MARK_BLOCK = 100, - HEADER_GC_MARK_DIFF_DATA = 101, - HEADER_GC_MARK_IDXLIST = 102, - HEADER_GC_MARK_UPDATE = 103, + // World + constexpr uint16_t FISHING = 0x0B10; + constexpr uint16_t DUNGEON = 0x0B11; + constexpr uint16_t LAND_LIST = 0x0B12; + constexpr uint16_t TIME = 0x0B13; + constexpr uint16_t CHANNEL = 0x0B14; + constexpr uint16_t MARK_UPDATE = 0x0B15; + constexpr uint16_t OBSERVER_ADD = 0x0B20; + constexpr uint16_t OBSERVER_REMOVE = 0x0B21; + constexpr uint16_t OBSERVER_MOVE = 0x0B22; - //HEADER_GC_SLOW_TIMER = 105, - HEADER_GC_TIME = 106, - HEADER_GC_CHANGE_NAME = 107, + // Guild Marks + constexpr uint16_t MARK_BLOCK = 0x0C10; + constexpr uint16_t MARK_IDXLIST = 0x0C11; + constexpr uint16_t MARK_DIFF_DATA = 0x0C12; +} - HEADER_GC_DUNGEON = 110, - HEADER_GC_WALK_MODE = 111, - HEADER_GC_CHANGE_SKILL_GROUP = 112, +// --- Phase constants --- - // SUPPORT_BGM - HEADER_GC_MAIN_CHARACTER2_EMPIRE = 113, - // END_OF_SUPPORT_BGM +enum EPhases +{ + PHASE_CLOSE, + PHASE_HANDSHAKE, + PHASE_LOGIN, + PHASE_SELECT, + PHASE_LOADING, + PHASE_GAME, + PHASE_DEAD, - HEADER_GC_SEPCIAL_EFFECT = 114, - HEADER_GC_NPC_POSITION = 115, - - HEADER_GC_CHARACTER_UPDATE2 = 117, - HEADER_GC_LOGIN_KEY = 118, - HEADER_GC_REFINE_INFORMATION_NEW = 119, - HEADER_GC_CHARACTER_ADD2 = 120, - HEADER_GC_CHANNEL = 121, - - HEADER_GC_MALL_OPEN = 122, - HEADER_GC_TARGET_UPDATE = 123, - HEADER_GC_TARGET_DELETE = 124, - HEADER_GC_TARGET_CREATE_NEW = 125, - - HEADER_GC_AFFECT_ADD = 126, - HEADER_GC_AFFECT_REMOVE = 127, - - HEADER_GC_MALL_SET = 128, - HEADER_GC_MALL_DEL = 129, - HEADER_GC_LAND_LIST = 130, - HEADER_GC_LOVER_INFO = 131, - HEADER_GC_LOVE_POINT_UPDATE = 132, - HEADER_GC_GUILD_SYMBOL_DATA = 133, - HEADER_GC_DIG_MOTION = 134, - - HEADER_GC_DAMAGE_INFO = 135, - HEADER_GC_CHAR_ADDITIONAL_INFO = 136, - - // SUPPORT_BGM - HEADER_GC_MAIN_CHARACTER3_BGM = 137, - HEADER_GC_MAIN_CHARACTER4_BGM_VOL = 138, - // END_OF_SUPPORT_BGM - - HEADER_GC_AUTH_SUCCESS = 150, - - HEADER_GC_SPECIFIC_EFFECT = 208, - HEADER_GC_DRAGON_SOUL_REFINE = 209, - HEADER_GC_RESPOND_CHANNELSTATUS = 210, - - HEADER_GC_ITEM_GET = 211, - - HEADER_GC_KEY_CHALLENGE = 0xf8, // Secure key exchange challenge - HEADER_GC_KEY_COMPLETE = 0xf7, // Secure key exchange complete - HEADER_GC_HANDSHAKE_OK = 0xfc, // 252 - HEADER_GC_PHASE = 0xfd, // 253 - HEADER_GC_BINDUDP = 0xfe, // 254 - HEADER_GC_HANDSHAKE = 0xff, // 255 - - ///////////////////////////////////////////////// - // Client To Client for UDP - /* - HEADER_CC_STATE_WAITING = 1, - HEADER_CC_STATE_WALKING = 2, - HEADER_CC_STATE_GOING = 3, - HEADER_CC_EVENT_NORMAL_ATTACKING = 4, - HEADER_CC_EVENT_COMBO_ATTACKING = 5, - HEADER_CC_EVENT_HIT = 6, - */ + PHASE_CLIENT_CONNECTING, + PHASE_DBCLIENT, + PHASE_P2P, + PHASE_AUTH, }; +// ============================================================================ +// Subheader enums — grouped by feature +// ============================================================================ + +namespace GuildSub { + namespace CG { enum : uint8_t { + ADD_MEMBER, + REMOVE_MEMBER, + CHANGE_GRADE_NAME, + CHANGE_GRADE_AUTHORITY, + OFFER, + POST_COMMENT, + DELETE_COMMENT, + REFRESH_COMMENT, + CHANGE_MEMBER_GRADE, + USE_SKILL, + CHANGE_MEMBER_GENERAL, + GUILD_INVITE_ANSWER, + CHARGE_GSP, + DEPOSIT_MONEY, + WITHDRAW_MONEY, + }; } + namespace GC { enum : uint8_t { + LOGIN, + LOGOUT, + LIST, + GRADE, + ADD, + REMOVE, + GRADE_NAME, + GRADE_AUTH, + INFO, + COMMENTS, + CHANGE_EXP, + CHANGE_MEMBER_GRADE, + SKILL_INFO, + CHANGE_MEMBER_GENERAL, + GUILD_INVITE, + WAR, + GUILD_NAME, + GUILD_WAR_LIST, + GUILD_WAR_END_LIST, + WAR_POINT, + MONEY_CHANGE, + }; } +} + +namespace ShopSub { + namespace CG { enum : uint8_t { + END, + BUY, + SELL, + SELL2, + }; } + namespace GC { enum : uint8_t { + START, + END, + UPDATE_ITEM, + UPDATE_PRICE, + OK, + NOT_ENOUGH_MONEY, + SOLDOUT, + INVENTORY_FULL, + INVALID_POS, + SOLD_OUT, + START_EX, + NOT_ENOUGH_MONEY_EX, + }; } +} + +namespace ExchangeSub { + namespace CG { enum : uint8_t { + START, + ITEM_ADD, + ITEM_DEL, + ELK_ADD, + ACCEPT, + CANCEL, + }; } + namespace GC { enum : uint8_t { + START, + ITEM_ADD, + ITEM_DEL, + ELK_ADD, + ACCEPT, + END, + ALREADY, + LESS_ELK, + }; } +} + +namespace MessengerSub { + namespace CG { enum : uint8_t { + ADD_BY_VID, + ADD_BY_NAME, + REMOVE, + }; } + namespace GC { enum : uint8_t { + LIST, + LOGIN, + LOGOUT, + INVITE, + REMOVE_FRIEND, + }; } +} + +namespace FishingSub { + namespace GC { enum : uint8_t { + START, + STOP, + REACT, + SUCCESS, + FAIL, + FISH, + }; } +} + +namespace DungeonSub { + namespace GC { enum : uint8_t { + TIME_ATTACK_START = 0, + DESTINATION_POSITION = 1, + }; } +} + +namespace DragonSoulSub { enum : uint8_t { + OPEN, + CLOSE, + DO_UPGRADE, + DO_IMPROVEMENT, + DO_REFINE, + REFINE_FAIL, + REFINE_FAIL_MAX_REFINE, + REFINE_FAIL_INVALID_MATERIAL, + REFINE_FAIL_NOT_ENOUGH_MONEY, + REFINE_FAIL_NOT_ENOUGH_MATERIAL, + REFINE_FAIL_TOO_MUCH_MATERIAL, + REFINE_SUCCEED, +}; } + enum { ID_MAX_NUM = 30, @@ -366,33 +487,38 @@ enum // Mark typedef struct command_mark_login { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t handle; uint32_t random_key; } TPacketCGMarkLogin; typedef struct command_mark_upload { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t gid; uint8_t image[16*12*4]; } TPacketCGMarkUpload; typedef struct command_mark_idxlist { - uint8_t header; + uint16_t header; + uint16_t length; } TPacketCGMarkIDXList; typedef struct command_mark_crclist { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t imgIdx; uint32_t crclist[80]; } TPacketCGMarkCRCList; typedef struct packet_mark_idxlist { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t bufSize; uint16_t count; //뒤에 size * (uint16_t + uint16_t)만큼 데이터 붙음 @@ -400,7 +526,8 @@ typedef struct packet_mark_idxlist typedef struct packet_mark_block { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t bufSize; uint8_t imgIdx; uint32_t count; @@ -409,21 +536,23 @@ typedef struct packet_mark_block typedef struct packet_mark_update { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t guildID; uint16_t imgIdx; } TPacketGCMarkUpdate; typedef struct command_symbol_upload { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint32_t handle; } TPacketCGSymbolUpload; typedef struct command_symbol_crc { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwGuildID; uint32_t dwCRC; uint32_t dwSize; @@ -431,8 +560,8 @@ typedef struct command_symbol_crc typedef struct packet_symbol_data { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint32_t guild_id; } TPacketGCGuildSymbolData; @@ -441,7 +570,8 @@ typedef struct packet_symbol_data // typedef struct packet_observer_add { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint16_t x; uint16_t y; @@ -449,7 +579,8 @@ typedef struct packet_observer_add typedef struct packet_observer_move { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint16_t x; uint16_t y; @@ -458,7 +589,8 @@ typedef struct packet_observer_move typedef struct packet_observer_remove { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; } TPacketGCObserverRemove; @@ -468,7 +600,8 @@ typedef struct packet_observer_remove typedef struct command_checkin { - uint8_t header; + uint16_t header; + uint16_t length; char name[ID_MAX_NUM+1]; char pwd[PASS_MAX_NUM+1]; } TPacketCGCheckin; @@ -476,21 +609,24 @@ typedef struct command_checkin // start - 권한 서버 접속을 위한 패킷들 typedef struct command_login2 { - uint8_t header; + uint16_t header; + uint16_t length; char name[ID_MAX_NUM + 1]; uint32_t login_key; } TPacketCGLogin2; typedef struct command_login3 { - uint8_t header; + uint16_t header; + uint16_t length; char name[ID_MAX_NUM + 1]; char pwd[PASS_MAX_NUM + 1]; } TPacketCGLogin3; typedef struct command_direct_enter { - uint8_t bHeader; + uint16_t header; + uint16_t length; char login[ID_MAX_NUM + 1]; char passwd[PASS_MAX_NUM + 1]; uint8_t index; @@ -498,13 +634,15 @@ typedef struct command_direct_enter typedef struct command_player_select { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t player_index; } TPacketCGSelectCharacter; typedef struct command_attack { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t bType; // 공격 유형 uint32_t dwVictimVID; // 적 VID uint8_t bCRCMagicCubeProcPiece; @@ -513,25 +651,18 @@ typedef struct command_attack typedef struct command_chat { - uint8_t header; + uint16_t header; uint16_t length; uint8_t type; } TPacketCGChat; typedef struct command_whisper { - uint8_t bHeader; - uint16_t wSize; + uint16_t header; + uint16_t length; char szNameTo[CHARACTER_NAME_MAX_LEN + 1]; } TPacketCGWhisper; -typedef struct command_sms -{ - uint8_t bHeader; - uint16_t wSize; - char szNameTo[CHARACTER_NAME_MAX_LEN + 1]; -} TPacketCGSMS; - enum EBattleMode { BATTLEMODE_ATTACK = 0, @@ -540,32 +671,37 @@ enum EBattleMode typedef struct command_EnterFrontGame { - uint8_t header; + uint16_t header; + uint16_t length; } TPacketCGEnterFrontGame; typedef struct command_item_use { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos pos; } TPacketCGItemUse; typedef struct command_item_use_to_item { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos source_pos; TItemPos target_pos; } TPacketCGItemUseToItem; typedef struct command_item_drop { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos pos; uint32_t elk; } TPacketCGItemDrop; typedef struct command_item_drop2 { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos pos; uint32_t gold; uint8_t count; @@ -573,7 +709,8 @@ typedef struct command_item_drop2 typedef struct command_item_move { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos pos; TItemPos change_pos; uint8_t num; @@ -581,64 +718,53 @@ typedef struct command_item_move typedef struct command_item_pickup { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; } TPacketCGItemPickUp; typedef struct command_quickslot_add { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; TQuickSlot slot; }TPacketCGQuickSlotAdd; typedef struct command_quickslot_del { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; }TPacketCGQuickSlotDel; typedef struct command_quickslot_swap { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; uint8_t change_pos; }TPacketCGQuickSlotSwap; typedef struct command_on_click { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; } TPacketCGOnClick; -enum -{ - SHOP_SUBHEADER_CG_END, - SHOP_SUBHEADER_CG_BUY, - SHOP_SUBHEADER_CG_SELL, - SHOP_SUBHEADER_CG_SELL2, -}; - typedef struct command_shop { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t subheader; } TPacketCGShop; -enum -{ - EXCHANGE_SUBHEADER_CG_START, // arg1 == vid of target character - EXCHANGE_SUBHEADER_CG_ITEM_ADD, // arg1 == position of item - EXCHANGE_SUBHEADER_CG_ITEM_DEL, // arg1 == position of item - EXCHANGE_SUBHEADER_CG_ELK_ADD, // arg1 == amount of elk - EXCHANGE_SUBHEADER_CG_ACCEPT, // arg1 == not used - EXCHANGE_SUBHEADER_CG_CANCEL, // arg1 == not used -}; - typedef struct command_exchange { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t subheader; uint32_t arg1; uint8_t arg2; @@ -647,37 +773,42 @@ typedef struct command_exchange typedef struct command_position { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t position; } TPacketCGPosition; typedef struct command_script_answer { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t answer; } TPacketCGScriptAnswer; typedef struct command_script_button { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t idx; } TPacketCGScriptButton; typedef struct command_target { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; } TPacketCGTarget; typedef struct command_move { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bFunc; uint8_t bArg; uint8_t bRot; - uint32_t lX; - uint32_t lY; - uint32_t dwTime; + int32_t lX; // Signed to match server (can be negative coordinates) + int32_t lY; // Signed to match server + uint32_t dwTime; } TPacketCGMove; typedef struct command_sync_position_element @@ -689,13 +820,14 @@ typedef struct command_sync_position_element typedef struct command_sync_position { - uint8_t bHeader; - uint16_t wSize; + uint16_t header; + uint16_t length; } TPacketCGSyncPosition; typedef struct command_fly_targeting { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwTargetVID; int32_t lX; int32_t lY; @@ -703,7 +835,8 @@ typedef struct command_fly_targeting typedef struct packet_fly_targeting { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwShooterVID; uint32_t dwTargetVID; int32_t lX; @@ -712,29 +845,21 @@ typedef struct packet_fly_targeting typedef struct packet_shoot { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bType; } TPacketCGShoot; typedef struct command_warp { - uint8_t bHeader; + uint16_t header; + uint16_t length; } TPacketCGWarp; -enum -{ - MESSENGER_SUBHEADER_GC_LIST, - MESSENGER_SUBHEADER_GC_LOGIN, - MESSENGER_SUBHEADER_GC_LOGOUT, - MESSENGER_SUBHEADER_GC_INVITE, - MESSENGER_SUBHEADER_GC_MOBILE, - MESSENGER_SUBHEADER_GC_REMOVE_FRIEND -}; - typedef struct packet_messenger { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint8_t subheader; } TPacketGCMessenger; @@ -748,7 +873,6 @@ enum { MESSENGER_CONNECTED_STATE_OFFLINE, MESSENGER_CONNECTED_STATE_ONLINE, - MESSENGER_CONNECTED_STATE_MOBILE, }; typedef struct packet_messenger_list_online @@ -770,16 +894,10 @@ typedef struct packet_messenger_logout uint8_t length; } TPacketGCMessengerLogout; -enum -{ - MESSENGER_SUBHEADER_CG_ADD_BY_VID, - MESSENGER_SUBHEADER_CG_ADD_BY_NAME, - MESSENGER_SUBHEADER_CG_REMOVE, -}; - typedef struct command_messenger { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t subheader; } TPacketCGMessenger; @@ -796,28 +914,32 @@ enum typedef struct command_safebox_money { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bState; uint32_t dwMoney; } TPacketCGSafeboxMoney; typedef struct command_safebox_checkout { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckout; typedef struct command_safebox_checkin { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckin; typedef struct command_mall_checkout { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bMallPos; TItemPos ItemPos; } TPacketCGMallCheckout; @@ -827,33 +949,38 @@ typedef struct command_mall_checkout typedef struct command_use_skill { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwVnum; uint32_t dwTargetVID; } TPacketCGUseSkill; typedef struct command_party_invite { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; } TPacketCGPartyInvite; typedef struct command_party_invite_answer { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t leader_pid; uint8_t accept; } TPacketCGPartyInviteAnswer; typedef struct command_party_remove { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t pid; } TPacketCGPartyRemove; typedef struct command_party_set_state { - uint8_t byHeader; + uint16_t header; + uint16_t length; uint32_t dwVID; uint8_t byState; uint8_t byFlag; @@ -861,59 +988,46 @@ typedef struct command_party_set_state typedef struct packet_party_link { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t pid; uint32_t vid; } TPacketGCPartyLink; typedef struct packet_party_unlink { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t pid; uint32_t vid; } TPacketGCPartyUnlink; typedef struct command_party_use_skill { - uint8_t byHeader; + uint16_t header; + uint16_t length; uint8_t bySkillIndex; uint32_t dwTargetVID; } TPacketCGPartyUseSkill; -enum -{ - GUILD_SUBHEADER_CG_ADD_MEMBER, - GUILD_SUBHEADER_CG_REMOVE_MEMBER, - GUILD_SUBHEADER_CG_CHANGE_GRADE_NAME, - GUILD_SUBHEADER_CG_CHANGE_GRADE_AUTHORITY, - GUILD_SUBHEADER_CG_OFFER, - GUILD_SUBHEADER_CG_POST_COMMENT, - GUILD_SUBHEADER_CG_DELETE_COMMENT, - GUILD_SUBHEADER_CG_REFRESH_COMMENT, - GUILD_SUBHEADER_CG_CHANGE_MEMBER_GRADE, - GUILD_SUBHEADER_CG_USE_SKILL, - GUILD_SUBHEADER_CG_CHANGE_MEMBER_GENERAL, - GUILD_SUBHEADER_CG_GUILD_INVITE_ANSWER, - GUILD_SUBHEADER_CG_CHARGE_GSP, - GUILD_SUBHEADER_CG_DEPOSIT_MONEY, - GUILD_SUBHEADER_CG_WITHDRAW_MONEY, -}; - typedef struct command_guild { - uint8_t byHeader; + uint16_t header; + uint16_t length; uint8_t bySubHeader; } TPacketCGGuild; typedef struct command_guild_answer_make_guild { - uint8_t header; + uint16_t header; + uint16_t length; char guild_name[GUILD_NAME_MAX_LEN+1]; } TPacketCGAnswerMakeGuild; typedef struct command_give_item { - uint8_t byHeader; + uint16_t header; + uint16_t length; uint32_t dwTargetVID; TItemPos ItemPos; uint8_t byItemCount; @@ -921,14 +1035,15 @@ typedef struct command_give_item typedef struct SPacketCGHack { - uint8_t bHeader; + uint16_t header; + uint16_t length; char szBuf[255 + 1]; } TPacketCGHack; typedef struct command_dungeon { - uint8_t bHeader; - uint16_t size; + uint16_t header; + uint16_t length; } TPacketCGDungeon; // Private Shop @@ -944,42 +1059,40 @@ typedef struct SShopItemTable typedef struct SPacketCGMyShop { - uint8_t bHeader; + uint16_t header; + uint16_t length; char szSign[SHOP_SIGN_MAX_LEN + 1]; uint8_t bCount; // count of TShopItemTable, max 39 } TPacketCGMyShop; typedef struct SPacketCGRefine { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; uint8_t type; } TPacketCGRefine; typedef struct SPacketCGChangeName { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t index; char name[CHARACTER_NAME_MAX_LEN+1]; } TPacketCGChangeName; typedef struct command_client_version { - uint8_t header; + uint16_t header; + uint16_t length; char filename[32+1]; char timestamp[32+1]; } TPacketCGClientVersion; -typedef struct command_client_version2 -{ - uint8_t header; - char filename[32+1]; - char timestamp[32+1]; -} TPacketCGClientVersion2; - typedef struct command_crc_report { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t byPackMode; uint32_t dwBinaryCRC32; uint32_t dwProcessCRC32; @@ -994,88 +1107,54 @@ enum EPartyExpDistributionType typedef struct command_party_parameter { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bDistributeMode; } TPacketCGPartyParameter; typedef struct command_quest_input_string { - uint8_t bHeader; + uint16_t header; + uint16_t length; char szString[QUEST_INPUT_STRING_MAX_NUM+1]; } TPacketCGQuestInputString; typedef struct command_quest_confirm { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t answer; uint32_t requestPID; } TPacketCGQuestConfirm; typedef struct command_quest_cancel { - uint8_t header; + uint16_t header; + uint16_t length; } TPacketCGQuestCancel; typedef struct command_script_select_item { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t selection; } TPacketCGScriptSelectItem; -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// From Server -enum EPhase -{ - PHASE_CLOSE, // 끊기는 상태 (또는 끊기 전 상태) - PHASE_HANDSHAKE, // 악수..;; - PHASE_LOGIN, // 로그인 중 - PHASE_SELECT, // 캐릭터 선택 화면 - PHASE_LOADING, // 선택 후 로딩 화면 - PHASE_GAME, // 게임 화면 - PHASE_DEAD, // 죽었을 때.. (게임 안에 있는 것일 수도..) - PHASE_DBCLIENT_CONNECTING, // 서버용 - PHASE_DBCLIENT, // 서버용 - PHASE_P2P, // 서버용 - PHASE_AUTH, // 로그인 인증 용 -}; +// TPacketGCPhase moved to EterLib/ControlPackets.h -typedef struct packet_phase +typedef struct packet_blank { - uint8_t header; - uint8_t phase; -} TPacketGCPhase; - -typedef struct packet_blank // 공백패킷. -{ - uint8_t header; + uint16_t header; + uint16_t length; } TPacketGCBlank; -typedef struct packet_blank_dynamic -{ - uint8_t header; - uint16_t size; -} TPacketGCBlankDynamic; - -typedef struct packet_header_handshake -{ - uint8_t header; - uint32_t dwHandshake; - uint32_t dwTime; - int32_t lDelta; -} TPacketGCHandshake; - -typedef struct packet_header_bindudp -{ - uint8_t header; - uint32_t addr; - uint16_t port; -} TPacketGCBindUDP; +typedef TPacketGCBlank TPacketGCBlankDynamic; typedef struct packet_header_dynamic_size { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; } TDynamicSizePacketHeader; typedef struct SSimplePlayerInformation @@ -1099,7 +1178,8 @@ typedef struct SSimplePlayerInformation typedef struct packet_login_success3 { - uint8_t header; + uint16_t header; + uint16_t length; TSimplePlayerInformation akSimplePlayerInformation[PLAYER_PER_ACCOUNT3]; uint32_t guild_id[PLAYER_PER_ACCOUNT3]; char guild_name[PLAYER_PER_ACCOUNT3][GUILD_NAME_MAX_LEN+1]; @@ -1109,7 +1189,8 @@ typedef struct packet_login_success3 typedef struct packet_login_success4 { - uint8_t header; + uint16_t header; + uint16_t length; TSimplePlayerInformation akSimplePlayerInformation[PLAYER_PER_ACCOUNT4]; uint32_t guild_id[PLAYER_PER_ACCOUNT4]; char guild_name[PLAYER_PER_ACCOUNT4][GUILD_NAME_MAX_LEN+1]; @@ -1121,13 +1202,15 @@ typedef struct packet_login_success4 enum { LOGIN_STATUS_MAX_LEN = 8 }; typedef struct packet_login_failure { - uint8_t header; + uint16_t header; + uint16_t length; char szStatus[LOGIN_STATUS_MAX_LEN + 1]; } TPacketGCLoginFailure; typedef struct command_player_create { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t index; char name[CHARACTER_NAME_MAX_LEN + 1]; uint16_t job; @@ -1140,27 +1223,31 @@ typedef struct command_player_create typedef struct command_player_create_success { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t bAccountCharacterSlot; TSimplePlayerInformation kSimplePlayerInfomation; } TPacketGCPlayerCreateSuccess; typedef struct command_create_failure { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t bType; } TPacketGCCreateFailure; typedef struct command_player_delete { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t index; char szPrivateCode[PRIVATE_CODE_LENGTH]; } TPacketCGDestroyCharacter; typedef struct packet_player_delete_success { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t account_index; } TPacketGCDestroyCharacterSuccess; @@ -1196,7 +1283,8 @@ enum ECharacterEquipmentPart typedef struct packet_char_additional_info { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; char name[CHARACTER_NAME_MAX_LEN + 1]; uint16_t awPart[CHR_EQUIPPART_NUM]; @@ -1210,7 +1298,8 @@ typedef struct packet_char_additional_info typedef struct packet_add_char { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; @@ -1238,7 +1327,8 @@ typedef struct packet_add_char typedef struct packet_add_char2 { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; @@ -1267,7 +1357,8 @@ typedef struct packet_add_char2 typedef struct packet_update_char { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; uint16_t awPart[CHR_EQUIPPART_NUM]; @@ -1285,7 +1376,8 @@ typedef struct packet_update_char typedef struct packet_update_char2 { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; uint16_t awPart[CHR_EQUIPPART_NUM]; @@ -1303,13 +1395,15 @@ typedef struct packet_update_char2 typedef struct packet_del_char { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; } TPacketGCCharacterDelete; typedef struct packet_GlobalTime { - uint8_t header; + uint16_t header; + uint16_t length; float GlobalTime; } TPacketGCGlobalTime; @@ -1329,8 +1423,8 @@ enum EChatType typedef struct packet_chatting { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint8_t type; uint32_t dwVID; uint8_t bEmpire; @@ -1338,80 +1432,42 @@ typedef struct packet_chatting typedef struct packet_whisper // 가변 패킷 { - uint8_t bHeader; - uint16_t wSize; + uint16_t header; + uint16_t length; uint8_t bType; char szNameFrom[CHARACTER_NAME_MAX_LEN + 1]; } TPacketGCWhisper; typedef struct packet_stun { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; } TPacketGCStun; typedef struct packet_dead { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; } TPacketGCDead; typedef struct packet_main_character { - uint8_t header; - uint32_t dwVID; - uint16_t wRaceNum; - char szName[CHARACTER_NAME_MAX_LEN + 1]; - int32_t lX, lY, lZ; + enum { MUSIC_NAME_MAX_LEN = 24 }; + + uint16_t header; + uint16_t length; + uint32_t dwVID; + uint16_t wRaceNum; + char szName[CHARACTER_NAME_MAX_LEN + 1]; + char szBGMName[MUSIC_NAME_MAX_LEN + 1]; + float fBGMVol; + int32_t lX, lY, lZ; + uint8_t byEmpire; uint8_t bySkillGroup; } TPacketGCMainCharacter; -// SUPPORT_BGM -typedef struct packet_main_character2_empire -{ - uint8_t header; - uint32_t dwVID; - uint16_t wRaceNum; - char szName[CHARACTER_NAME_MAX_LEN + 1]; - int32_t lX, lY, lZ; - uint8_t byEmpire; - uint8_t bySkillGroup; -} TPacketGCMainCharacter2_EMPIRE; - -typedef struct packet_main_character3_bgm -{ - enum - { - MUSIC_NAME_MAX_LEN = 24, - }; - uint8_t header; - uint32_t dwVID; - uint16_t wRaceNum; - char szUserName[CHARACTER_NAME_MAX_LEN + 1]; - char szBGMName[MUSIC_NAME_MAX_LEN + 1]; - int32_t lX, lY, lZ; - uint8_t byEmpire; - uint8_t bySkillGroup; -} TPacketGCMainCharacter3_BGM; - -typedef struct packet_main_character4_bgm_vol -{ - enum - { - MUSIC_NAME_MAX_LEN = 24, - }; - uint8_t header; - uint32_t dwVID; - uint16_t wRaceNum; - char szUserName[CHARACTER_NAME_MAX_LEN + 1]; - char szBGMName[MUSIC_NAME_MAX_LEN + 1]; - float fBGMVol; - int32_t lX, lY, lZ; - uint8_t byEmpire; - uint8_t bySkillGroup; -} TPacketGCMainCharacter4_BGM_VOL; -// END_OF_SUPPORT_BGM - enum EPointTypes { POINT_NONE, // 0 @@ -1583,13 +1639,15 @@ enum EPointTypes typedef struct packet_points { - uint8_t header; + uint16_t header; + uint16_t length; int32_t points[POINT_MAX_NUM]; } TPacketGCPoints; typedef struct packet_point_change { - int32_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; uint8_t Type; @@ -1600,7 +1658,8 @@ typedef struct packet_point_change typedef struct packet_motion { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint32_t victim_vid; uint16_t motion; @@ -1608,13 +1667,15 @@ typedef struct packet_motion typedef struct packet_del_item { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos pos; } TPacketGCItemDel; typedef struct packet_set_item { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos pos; uint32_t vnum; uint8_t count; @@ -1627,7 +1688,8 @@ typedef struct packet_set_item typedef struct packet_item_get { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwItemVnum; uint8_t bCount; uint8_t bArg; // 0: normal, 1: from party member @@ -1636,7 +1698,8 @@ typedef struct packet_item_get typedef struct packet_use_item { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos Cell; uint32_t ch_vid; uint32_t victim_vid; @@ -1646,7 +1709,8 @@ typedef struct packet_use_item typedef struct packet_update_item { - uint8_t header; + uint16_t header; + uint16_t length; TItemPos Cell; uint8_t count; int32_t alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; @@ -1655,7 +1719,8 @@ typedef struct packet_update_item typedef struct packet_ground_add_item { - uint8_t bHeader; + uint16_t header; + uint16_t length; int32_t lX; int32_t lY; int32_t lZ; @@ -1666,33 +1731,38 @@ typedef struct packet_ground_add_item typedef struct packet_ground_del_item { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; } TPacketGCItemGroundDel; typedef struct packet_item_ownership { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwVID; char szName[CHARACTER_NAME_MAX_LEN + 1]; } TPacketGCItemOwnership; typedef struct packet_quickslot_add { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; TQuickSlot slot; } TPacketGCQuickSlotAdd; typedef struct packet_quickslot_del { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; } TPacketGCQuickSlotDel; typedef struct packet_quickslot_swap { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; uint8_t change_pos; } TPacketGCQuickSlotSwap; @@ -1726,32 +1796,17 @@ typedef struct packet_shop_update_price int32_t iElkAmount; } TPacketGCShopUpdatePrice; -enum EPacketShopSubHeaders -{ - SHOP_SUBHEADER_GC_START, - SHOP_SUBHEADER_GC_END, - SHOP_SUBHEADER_GC_UPDATE_ITEM, - SHOP_SUBHEADER_GC_UPDATE_PRICE, - SHOP_SUBHEADER_GC_OK, - SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY, - SHOP_SUBHEADER_GC_SOLDOUT, - SHOP_SUBHEADER_GC_INVENTORY_FULL, - SHOP_SUBHEADER_GC_INVALID_POS, - SHOP_SUBHEADER_GC_SOLD_OUT, - SHOP_SUBHEADER_GC_START_EX, - SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_EX, -}; - typedef struct packet_shop { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint8_t subheader; } TPacketGCShop; typedef struct packet_exchange { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t subheader; uint8_t is_me; uint32_t arg1; @@ -1761,54 +1816,36 @@ typedef struct packet_exchange TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; } TPacketGCExchange; -enum -{ - EXCHANGE_SUBHEADER_GC_START, // arg1 == vid - EXCHANGE_SUBHEADER_GC_ITEM_ADD, // arg1 == vnum arg2 == pos arg3 == count - EXCHANGE_SUBHEADER_GC_ITEM_DEL, // arg1 == pos - EXCHANGE_SUBHEADER_GC_ELK_ADD, // arg1 == elk - EXCHANGE_SUBHEADER_GC_ACCEPT, // arg1 == accept - EXCHANGE_SUBHEADER_GC_END, // arg1 == not used - EXCHANGE_SUBHEADER_GC_ALREADY, // arg1 == not used - EXCHANGE_SUBHEADER_GC_LESS_ELK, // arg1 == not used -}; - typedef struct packet_position { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint8_t position; } TPacketGCPosition; -typedef struct packet_ping -{ - uint8_t header; -} TPacketGCPing; - -typedef struct packet_pong -{ - uint8_t bHeader; - uint8_t bSequence; -} TPacketCGPong; +// TPacketGCPing, TPacketCGPong moved to EterLib/ControlPackets.h typedef struct packet_script { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint8_t skin; uint16_t src_size; } TPacketGCScript; typedef struct packet_target { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; uint8_t bHPPercent; } TPacketGCTarget; typedef struct packet_damage_info { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; uint8_t flag; int32_t damage; @@ -1816,7 +1853,8 @@ typedef struct packet_damage_info typedef struct packet_mount { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint32_t mount_vid; uint8_t pos; @@ -1825,14 +1863,16 @@ typedef struct packet_mount typedef struct packet_change_speed { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint16_t moving_speed; } TPacketGCChangeSpeed; typedef struct packet_move { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bFunc; uint8_t bArg; uint8_t bRot; @@ -1856,15 +1896,16 @@ enum typedef struct packet_quest_info { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint16_t index; uint8_t flag; } TPacketGCQuestInfo; typedef struct packet_quest_confirm { - uint8_t header; + uint16_t header; + uint16_t length; char msg[64+1]; int32_t timeout; uint32_t requestPID; @@ -1872,7 +1913,8 @@ typedef struct packet_quest_confirm typedef struct packet_attack { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; uint32_t dwVictimVID; // 적 VID uint8_t bType; // 공격 유형 @@ -1880,8 +1922,8 @@ typedef struct packet_attack typedef struct packet_c2c { - uint8_t header; - uint16_t wSize; + uint16_t header; + uint16_t length; } TPacketGCC2C; typedef struct packetd_sync_position_element @@ -1893,13 +1935,14 @@ typedef struct packetd_sync_position_element typedef struct packetd_sync_position { - uint8_t bHeader; - uint16_t wSize; + uint16_t header; + uint16_t length; } TPacketGCSyncPosition; typedef struct packet_ownership { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwOwnerVID; uint32_t dwVictimVID; } TPacketGCOwnership; @@ -1908,7 +1951,8 @@ typedef struct packet_ownership typedef struct packet_skill_level { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t abSkillLevels[SKILL_MAX_NUM]; } TPacketGCSkillLevel; @@ -1921,14 +1965,16 @@ typedef struct SPlayerSkill typedef struct packet_skill_level_new { - uint8_t bHeader; + uint16_t header; + uint16_t length; TPlayerSkill skills[SKILL_MAX_NUM]; } TPacketGCSkillLevelNew; // fly typedef struct packet_fly { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bType; uint32_t dwStartVID; uint32_t dwEndVID; @@ -1944,13 +1990,14 @@ enum EPVPModes typedef struct packet_duel_start { - uint8_t header ; - uint16_t wSize ; // uint32_t가 몇개? 개수 = (wSize - sizeof(TPacketGCPVPList)) / 4 + uint16_t header; + uint16_t length; } TPacketGCDuelStart ; typedef struct packet_pvp { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVIDSrc; uint32_t dwVIDDst; uint8_t bMode; @@ -1958,13 +2005,15 @@ typedef struct packet_pvp typedef struct packet_skill_cooltime_end { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t bSkill; } TPacketGCSkillCoolTimeEnd; typedef struct packet_warp { - uint8_t bHeader; + uint16_t header; + uint16_t length; int32_t lX; int32_t lY; int32_t lAddr; @@ -1973,20 +2022,23 @@ typedef struct packet_warp typedef struct packet_party_invite { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t leader_pid; } TPacketGCPartyInvite; typedef struct packet_party_add { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t pid; char name[CHARACTER_NAME_MAX_LEN+1]; } TPacketGCPartyAdd; typedef struct packet_party_update { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t pid; uint8_t state; uint8_t percent_hp; @@ -1995,7 +2047,8 @@ typedef struct packet_party_update typedef struct packet_party_remove { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t pid; } TPacketGCPartyRemove; @@ -2004,46 +2057,49 @@ typedef TPacketCGSafeboxCheckin TPacketGCSafeboxCheckin; typedef struct packet_safebox_wrong_password { - uint8_t bHeader; + uint16_t header; + uint16_t length; } TPacketGCSafeboxWrongPassword; typedef struct packet_safebox_size { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bSize; } TPacketGCSafeboxSize; typedef struct packet_safebox_money_change { - uint8_t bHeader; - uint32_t dwMoney; + uint16_t header; + uint16_t length; + int32_t lMoney; // Signed to match server (uses int32_t lMoney) } TPacketGCSafeboxMoneyChange; typedef struct command_empire { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bEmpire; } TPacketCGEmpire; typedef struct packet_empire { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bEmpire; } TPacketGCEmpire; -enum +typedef struct command_fishing { - FISHING_SUBHEADER_GC_START, - FISHING_SUBHEADER_GC_STOP, - FISHING_SUBHEADER_GC_REACT, - FISHING_SUBHEADER_GC_SUCCESS, - FISHING_SUBHEADER_GC_FAIL, - FISHING_SUBHEADER_GC_FISH, -}; + uint16_t header; + uint16_t length; + uint8_t dir; +} TPacketCGFishing; typedef struct packet_fishing { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t subheader; uint32_t info; uint8_t dir; @@ -2051,42 +2107,18 @@ typedef struct packet_fishing typedef struct paryt_parameter { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bDistributeMode; } TPacketGCPartyParameter; ////////////////////////////////////////////////////////////////////////// // Guild -enum -{ - GUILD_SUBHEADER_GC_LOGIN, - GUILD_SUBHEADER_GC_LOGOUT, - GUILD_SUBHEADER_GC_LIST, - GUILD_SUBHEADER_GC_GRADE, - GUILD_SUBHEADER_GC_ADD, - GUILD_SUBHEADER_GC_REMOVE, - GUILD_SUBHEADER_GC_GRADE_NAME, - GUILD_SUBHEADER_GC_GRADE_AUTH, - GUILD_SUBHEADER_GC_INFO, - GUILD_SUBHEADER_GC_COMMENTS, - GUILD_SUBHEADER_GC_CHANGE_EXP, - GUILD_SUBHEADER_GC_CHANGE_MEMBER_GRADE, - GUILD_SUBHEADER_GC_SKILL_INFO, - GUILD_SUBHEADER_GC_CHANGE_MEMBER_GENERAL, - GUILD_SUBHEADER_GC_GUILD_INVITE, - GUILD_SUBHEADER_GC_WAR, - GUILD_SUBHEADER_GC_GUILD_NAME, - GUILD_SUBHEADER_GC_GUILD_WAR_LIST, - GUILD_SUBHEADER_GC_GUILD_WAR_END_LIST, - GUILD_SUBHEADER_GC_WAR_POINT, - GUILD_SUBHEADER_GC_MONEY_CHANGE, -}; - typedef struct packet_guild { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint8_t subheader; } TPacketGCGuild; @@ -2160,31 +2192,26 @@ typedef struct SPacketGuildWarPoint int32_t lPoint; } TPacketGuildWarPoint; -// SubHeader - Dungeon -enum -{ - DUNGEON_SUBHEADER_GC_TIME_ATTACK_START = 0, - DUNGEON_SUBHEADER_GC_DESTINATION_POSITION = 1, -}; - typedef struct packet_dungeon { - uint8_t bHeader; - uint16_t size; + uint16_t header; + uint16_t length; uint8_t subheader; } TPacketGCDungeon; // Private Shop typedef struct SPacketGCShopSign { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwVID; char szSign[SHOP_SIGN_MAX_LEN + 1]; } TPacketGCShopSign; typedef struct SPacketGCTime { - uint8_t bHeader; + uint16_t header; + uint16_t length; time_t time; } TPacketGCTime; @@ -2196,14 +2223,16 @@ enum typedef struct SPacketGCWalkMode { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint8_t mode; } TPacketGCWalkMode; typedef struct SPacketGCChangeSkillGroup { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t skill_group; } TPacketGCChangeSkillGroup; @@ -2225,14 +2254,16 @@ typedef struct SRefineTable typedef struct SPacketGCRefineInformation { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t pos; TRefineTable refine_table; } TPacketGCRefineInformation; typedef struct SPacketGCRefineInformationNew { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t type; uint8_t pos; TRefineTable refine_table; @@ -2270,15 +2301,16 @@ enum SPECIAL_EFFECT typedef struct SPacketGCSpecialEffect { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t type; uint32_t vid; } TPacketGCSpecialEffect; typedef struct SPacketGCNPCPosition { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; uint16_t count; } TPacketGCNPCPosition; @@ -2293,7 +2325,8 @@ struct TNPCPosition typedef struct SPacketGCChangeName { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t pid; char name[CHARACTER_NAME_MAX_LEN+1]; } TPacketGCChangeName; @@ -2310,20 +2343,23 @@ enum EBlockAction typedef struct packet_login_key { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwLoginKey; } TPacketGCLoginKey; typedef struct packet_auth_success { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwLoginKey; uint8_t bResult; } TPacketGCAuthSuccess; typedef struct packet_channel { - uint8_t header; + uint16_t header; + uint16_t length; uint8_t channel; } TPacketGCChannel; @@ -2337,7 +2373,8 @@ typedef struct SEquipmentItemSet typedef struct pakcet_view_equip { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t dwVID; TEquipmentItemSet equips[WEAR_MAX_NUM]; } TPacketGCViewEquip; @@ -2352,13 +2389,14 @@ typedef struct typedef struct packet_land_list { - uint8_t header; - uint16_t size; + uint16_t header; + uint16_t length; } TPacketGCLandList; typedef struct { - uint8_t bHeader; + uint16_t header; + uint16_t length; int32_t lID; char szTargetName[32+1]; } TPacketGCTargetCreate; @@ -2372,7 +2410,8 @@ enum typedef struct { - uint8_t bHeader; + uint16_t header; + uint16_t length; int32_t lID; char szTargetName[32+1]; uint32_t dwVID; @@ -2381,14 +2420,16 @@ typedef struct typedef struct { - uint8_t bHeader; + uint16_t header; + uint16_t length; int32_t lID; int32_t lX, lY; } TPacketGCTargetUpdate; typedef struct { - uint8_t bHeader; + uint16_t header; + uint16_t length; int32_t lID; } TPacketGCTargetDelete; @@ -2404,39 +2445,45 @@ typedef struct typedef struct { - uint8_t bHeader; + uint16_t header; + uint16_t length; TPacketAffectElement elem; } TPacketGCAffectAdd; typedef struct { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint32_t dwType; uint8_t bApplyOn; } TPacketGCAffectRemove; typedef struct packet_mall_open { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bSize; } TPacketGCMallOpen; typedef struct packet_lover_info { - uint8_t bHeader; + uint16_t header; + uint16_t length; char szName[CHARACTER_NAME_MAX_LEN + 1]; uint8_t byLovePoint; } TPacketGCLoverInfo; typedef struct packet_love_point_update { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t byLovePoint; } TPacketGCLovePointUpdate; typedef struct packet_dig_motion { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; uint32_t target_vid; uint8_t count; @@ -2444,13 +2491,15 @@ typedef struct packet_dig_motion typedef struct SPacketGCOnTime { - uint8_t header; + uint16_t header; + uint16_t length; int32_t ontime; // sec } TPacketGCOnTime; typedef struct SPacketGCResetOnTime { - uint8_t header; + uint16_t header; + uint16_t length; } TPacketGCResetOnTime; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2458,7 +2507,8 @@ typedef struct SPacketGCResetOnTime typedef struct packet_state { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bFunc; uint8_t bArg; uint8_t bRot; @@ -2470,44 +2520,25 @@ typedef struct packet_state // AUTOBAN typedef struct packet_autoban_quiz { - uint8_t bHeader; + uint16_t header; + uint16_t length; uint8_t bDuration; uint8_t bCaptcha[64*32]; char szQuiz[256]; } TPacketGCAutoBanQuiz; // END_OF_AUTOBAN +// TPacketGCKeyChallenge, TPacketCGKeyResponse, TPacketGCKeyComplete +// moved to EterLib/ControlPackets.h + // Secure authentication packets (libsodium/XChaCha20-Poly1305) #pragma pack(push, 1) -// Server -> Client: Key exchange challenge -struct TPacketGCKeyChallenge -{ - uint8_t bHeader; // HEADER_GC_KEY_CHALLENGE (0xf8) - uint8_t server_pk[32]; // Server's X25519 public key - uint8_t challenge[32]; // Random challenge bytes -}; - -// Client -> Server: Key exchange response -struct TPacketCGKeyResponse -{ - uint8_t bHeader; // HEADER_CG_KEY_RESPONSE (0xf9) - uint8_t client_pk[32]; // Client's X25519 public key - uint8_t challenge_response[32]; // HMAC(challenge, rx_key) -}; - -// Server -> Client: Key exchange complete -struct TPacketGCKeyComplete -{ - uint8_t bHeader; // HEADER_GC_KEY_COMPLETE (0xf7) - uint8_t encrypted_token[32 + 16]; // Session token + Poly1305 tag - uint8_t nonce[24]; // XChaCha20 nonce -}; - // Client -> Server: Secure login struct TPacketCGLoginSecure { - uint8_t bHeader; // HEADER_CG_LOGIN_SECURE (0xf6) + uint16_t header; // CG::LOGIN_SECURE + uint16_t length; char name[ID_MAX_NUM + 1]; char pwd[PASS_MAX_NUM + 1]; uint8_t session_token[32]; // Session token from KeyComplete @@ -2517,7 +2548,8 @@ struct TPacketCGLoginSecure typedef struct SPacketGCSpecificEffect { - uint8_t header; + uint16_t header; + uint16_t length; uint32_t vid; char effect_file[128]; } TPacketGCSpecificEffect; @@ -2530,36 +2562,22 @@ enum EDragonSoulRefineWindowRefineType DragonSoulRefineWindow_REFINE, }; -enum EPacketCGDragonSoulSubHeaderType -{ - DS_SUB_HEADER_OPEN, - DS_SUB_HEADER_CLOSE, - DS_SUB_HEADER_DO_UPGRADE, - DS_SUB_HEADER_DO_IMPROVEMENT, - DS_SUB_HEADER_DO_REFINE, - DS_SUB_HEADER_REFINE_FAIL, - DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, - DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, - DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, - DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, - DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, - DS_SUB_HEADER_REFINE_SUCCEED, -}; - typedef struct SPacketCGDragonSoulRefine { - SPacketCGDragonSoulRefine() : header (HEADER_CG_DRAGON_SOUL_REFINE) + SPacketCGDragonSoulRefine() : header(CG::DRAGON_SOUL_REFINE), length(sizeof(SPacketCGDragonSoulRefine)) {} - uint8_t header; + uint16_t header; + uint16_t length; uint8_t bSubType; TItemPos ItemGrid[DS_REFINE_WINDOW_MAX_NUM]; } TPacketCGDragonSoulRefine; typedef struct SPacketGCDragonSoulRefine { - SPacketGCDragonSoulRefine() : header(HEADER_GC_DRAGON_SOUL_REFINE) + SPacketGCDragonSoulRefine() : header(GC::DRAGON_SOUL_REFINE), length(sizeof(SPacketGCDragonSoulRefine)) {} - uint8_t header; + uint16_t header; + uint16_t length; uint8_t bSubType; TItemPos Pos; } TPacketGCDragonSoulRefine; diff --git a/src/UserInterface/PythonApplication.cpp b/src/UserInterface/PythonApplication.cpp index 0e64143..949406e 100644 --- a/src/UserInterface/PythonApplication.cpp +++ b/src/UserInterface/PythonApplication.cpp @@ -424,94 +424,6 @@ bool CPythonApplication::Process() #ifdef __VTUNE__ s_bFrameSkip = false; #endif - /* - static bool s_isPrevFrameSkip=false; - static DWORD s_dwFrameSkipCount=0; - static DWORD s_dwFrameSkipEndTime=0; - - static DWORD ERROR_FRAME_SKIP_COUNT = 60*5; - static DWORD ERROR_FRAME_SKIP_TIME = ERROR_FRAME_SKIP_COUNT*18; - - //static DWORD MAX_FRAME_SKIP=0; - - if (IsActive()) - { - DWORD dwFrameSkipCurTime=ELTimer_GetMSec(); - - if (s_bFrameSkip) - { - // ÀÌÀü ÇÁ·¹ÀÓµµ ½ºÅµÀ̶ó¸é.. - if (s_isPrevFrameSkip) - { - if (s_dwFrameSkipEndTime==0) - { - s_dwFrameSkipCount=0; // ÇÁ·¹ÀÓ Ã¼Å©´Â ·Îµù ´ëºñ - s_dwFrameSkipEndTime=dwFrameSkipCurTime+ERROR_FRAME_SKIP_TIME; // ½Ã°£ üũ´Â ·ÎµùÈÄ ÇÁ·¹ÀÓ ½ºÅµ üũ - - //printf("FrameSkipCheck Start\n"); - } - ++s_dwFrameSkipCount; - - //if (MAX_FRAME_SKIPERROR_FRAME_SKIP_COUNT && s_dwFrameSkipEndTime void RemoveFriend(const char * c_szKey); void OnFriendLogin(const char * c_szKey); void OnFriendLogout(const char * c_szKey); - void SetMobile(const char * c_szKey, BYTE byState); BOOL IsFriendByKey(const char * c_szKey); BOOL IsFriendByName(const char * c_szName); diff --git a/src/UserInterface/PythonNetworkDatagram.cpp b/src/UserInterface/PythonNetworkDatagram.cpp deleted file mode 100644 index 0ffdd21..0000000 --- a/src/UserInterface/PythonNetworkDatagram.cpp +++ /dev/null @@ -1,213 +0,0 @@ -#include "StdAfx.h" - -/* -#include "PythonNetworkDatagram.h" -#include "PythonNetworkStream.h" - -class CDatagramPacketHeaderMap : public CNetworkPacketHeaderMap -{ - public: - CDatagramPacketHeaderMap() - { - Set(HEADER_CC_STATE_WALKING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketCCState), false)); - } -}; - -void CPythonNetworkDatagram::Destroy() -{ - m_NetSenderPool.Clear(); -} - -BOOL CPythonNetworkDatagram::CheckPacket(TPacketHeader * piRetHeader) -{ - static CDatagramPacketHeaderMap s_packetHeaderMap; - - if (!m_NetReceiver.isBind()) - return FALSE; - - *piRetHeader = 0; - - TPacketHeader header; - - if (!m_NetReceiver.Peek(&header, sizeof(TPacketHeader))) - return false; - - CNetworkPacketHeaderMap::TPacketType PacketType; - - if (!s_packetHeaderMap.Get(header, &PacketType)) - { - Tracef("Unknown UDP packet header"); - assert(!"Unknown UDP packet header"); - return FALSE; - } - - if (!header) - return FALSE; - - *piRetHeader = header; - return TRUE; -} - -void CPythonNetworkDatagram::Process() -{ - while (m_NetReceiver.Process()) - { - TPacketHeader iHeader; - - if (!CheckPacket(&iHeader)) - continue; - - switch(iHeader) - { - case HEADER_CC_STATE_WALKING: - RecvStateWalkingPacket(); - break; - - case HEADER_CC_STATE_WAITING: - case HEADER_CC_STATE_GOING: - case HEADER_CC_EVENT_NORMAL_ATTACKING: - case HEADER_CC_EVENT_COMBO_ATTACKING: - case HEADER_CC_EVENT_HIT: - break; - } - } -} - -void CPythonNetworkDatagram::SetConnection(const char * c_szIP, WORD wPortIndex) -{ - m_NetSender.SetSocket(c_szIP, wPortIndex); -} - -void CPythonNetworkDatagram::SetRecvBufferSize(DWORD dwSize) -{ - m_NetReceiver.SetRecvBufferSize(dwSize); -} - -void CPythonNetworkDatagram::SendToServer(const void * c_pBuffer, DWORD dwSize) -{ - if (!m_NetSender.isSocket()) - { - assert(!"UDP Socket has not set!"); - return; - } - - m_NetSender.Send(c_pBuffer, dwSize); -} - -void CPythonNetworkDatagram::Bind(DWORD dwAddress, WORD wPortIndex) -{ - m_NetReceiver.Bind(dwAddress, wPortIndex); -} - -void CPythonNetworkDatagram::RegisterSender(DWORD dwID, DWORD dwAddress, WORD wPortIndex) -{ - CNetDatagramSender * pSender = m_NetSenderPool.Alloc(); - - pSender->SetSocket(dwAddress, wPortIndex); - - m_NetSenderMap.insert(TNetSenderMap::value_type(dwID, pSender)); -} -void CPythonNetworkDatagram::DeleteSender(DWORD dwID) -{ - CNetDatagramSender * pSender; - if (!GetSenderPointer(dwID, &pSender)) - return; - - m_NetSenderPool.Free(pSender); - - m_NetSenderMap.erase(dwID); -} - -void CPythonNetworkDatagram::Select(DWORD dwID) -{ - CNetDatagramSender * pSender; - if (!GetSenderPointer(dwID, &pSender)) - return; - - m_NetSenderList.push_back(pSender); -} -void CPythonNetworkDatagram::SendToSenders(const void * c_pBuffer, DWORD dwSize) -{ - // NOTE : Temporary Code - // Now, Send to every around client. - for (TNetSenderMapIterator itorMap = m_NetSenderMap.begin(); itorMap != m_NetSenderMap.end(); ++itorMap) - { - CNetDatagramSender * pSender = itorMap->second; - m_NetSenderList.push_back(pSender); - } - // NOTE : Temporary Code - - for (TNetSenderListIterator itor = m_NetSenderList.begin(); itor != m_NetSenderList.end(); ++itor) - { - CNetDatagramSender * pSender = *itor; - - pSender->Send(c_pBuffer, dwSize); - } - - m_NetSenderList.clear(); -} - -BOOL CPythonNetworkDatagram::GetSenderPointer(DWORD dwID, CNetDatagramSender ** ppSender) -{ - TNetSenderMapIterator itor = m_NetSenderMap.find(dwID); - - if (m_NetSenderMap.end() == itor) - return FALSE; - - *ppSender = itor->second; - - return TRUE; -} - -////////////////////////////////// -// Walking - -void CPythonNetworkDatagram::SendCharacterStatePacket(DWORD dwVID, DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) -{ - fDstRot=fmod(fDstRot, 360.0f); - - if (fDstRot<0) - fDstRot=360.0f-fDstRot; - - TPacketCCState kStatePacket; - kStatePacket.bHeader=HEADER_CC_STATE_WALKING; - kStatePacket.dwVID=dwVID; - kStatePacket.bFunc=eFunc; - kStatePacket.bArg=uArg; - kStatePacket.bRot=fDstRot/5.0f; - kStatePacket.dwTime=dwCmdTime; - kStatePacket.kPPos=c_rkPPosDst; - //SendToSenders(&kStatePacket, sizeof(kStatePacket)); -} - -BOOL CPythonNetworkDatagram::RecvStateWalkingPacket() -{ - TPacketCCState kStatePacket; - if (!m_NetReceiver.Recv(&kStatePacket, sizeof(kStatePacket))) - { - assert(!"CPythonNetworkDatagram::RecvStatePacket - PAKCET READ ERROR"); - Tracenf("CPythonNetworkDatagram::RecvStatePacket - PAKCET READ ERROR"); - return FALSE; - } - - CInstanceBase * pkChrInst = CPythonCharacterManager::Instance().GetInstancePtr(kStatePacket.dwVID); - - if (!pkChrInst) - { - //Tracenf("CPythonNetworkDatagram::RecvStatePacket - NOT EXIST VID(kStateWaitingPacket.vid = %d)", kStatePacket.m_dwVID); - return TRUE; - } - - pkChrInst->PushUDPState(kStatePacket.dwTime, kStatePacket.kPPos, kStatePacket.bRot*5.0f, kStatePacket.bFunc, kStatePacket.bArg); - return TRUE; -} - -CPythonNetworkDatagram::CPythonNetworkDatagram() -{ -} - -CPythonNetworkDatagram::~CPythonNetworkDatagram() -{ -} - - */ \ No newline at end of file diff --git a/src/UserInterface/PythonNetworkDatagram.h b/src/UserInterface/PythonNetworkDatagram.h deleted file mode 100644 index 05a9274..0000000 --- a/src/UserInterface/PythonNetworkDatagram.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -/* -#include "EterLib/NetDatagramReceiver.h" -#include "EterLib/NetDatagramSender.h" -#include "Packet.h" - -class CPythonNetworkDatagram : public CSingleton -{ - public: - CPythonNetworkDatagram(); - virtual ~CPythonNetworkDatagram(); - - void Destroy(); - - // With Server - void SetRecvBufferSize(DWORD dwSize); - void SetConnection(const char * c_szIP, WORD wPortIndex); - void SendToServer(const void * c_pBuffer, DWORD dwSize); - void Bind(DWORD dwAddress, WORD wPortIndex); - - // With UDP Senders - void RegisterSender(DWORD dwID, DWORD dwAddress, WORD wPortIndex); - void DeleteSender(DWORD dwID); - - void Select(DWORD dwID); - void SendToSenders(const void * c_pBuffer, DWORD dwSize); - - // Regulary update function - void Process(); - void SendCharacterStatePacket(DWORD dwVID, DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg); - - protected: - BOOL CheckPacket(TPacketHeader * piRetHeader); - BOOL GetSenderPointer(DWORD dwID, CNetDatagramSender ** ppSender); - BOOL RecvStateWalkingPacket(); - - protected: - // Sender Map - typedef std::map TNetSenderMap; - typedef TNetSenderMap::iterator TNetSenderMapIterator; - // Sender List - typedef std::list TNetSenderList; - typedef TNetSenderList::iterator TNetSenderListIterator; - - protected: - // Sender - TNetSenderMap m_NetSenderMap; - TNetSenderList m_NetSenderList; - - // Connection with server - CNetDatagramSender m_NetSender; - CNetDatagramReceiver m_NetReceiver; - - private: - CDynamicPool m_NetSenderPool; -}; -*/ \ No newline at end of file diff --git a/src/UserInterface/PythonNetworkDatagramModule.cpp b/src/UserInterface/PythonNetworkDatagramModule.cpp deleted file mode 100644 index 217d108..0000000 --- a/src/UserInterface/PythonNetworkDatagramModule.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "StdAfx.h" -#include "PythonNetworkDatagram.h" -/* -PyObject * udpEnable(PyObject* poSelf, PyObject* poArgs) -{ - CPythonNetworkDatagram::Instance().Enable(); - return Py_BuildNone(); -} - -PyObject * udpDisable(PyObject* poSelf, PyObject* poArgs) -{ - CPythonNetworkDatagram::Instance().Disable(); - return Py_BuildNone(); -} -*/ -void initudp() -{ - /* - static PyMethodDef s_methods[] = - { - { "Enable", udpEnable, METH_VARARGS }, - { "Disable", udpDisable, METH_VARARGS }, - - { NULL, NULL, NULL } - }; - - PyObject * poModule = Py_InitModule("udp", s_methods); - */ -} diff --git a/src/UserInterface/PythonNetworkStream.cpp b/src/UserInterface/PythonNetworkStream.cpp index 1a4bc2c..155beef 100644 --- a/src/UserInterface/PythonNetworkStream.cpp +++ b/src/UserInterface/PythonNetworkStream.cpp @@ -1,5 +1,4 @@ #include "StdAfx.h" -#include "EterLib/NetPacketHeaderMap.h" #include "PythonNetworkStream.h" #include "Packet.h" @@ -15,172 +14,6 @@ static DWORD gs_nextDownloadMarkTime = 0; // END_OF_MARK_BUG_FIX -// Packet --------------------------------------------------------------------------- -class CMainPacketHeaderMap : public CNetworkPacketHeaderMap -{ - public: - enum - { - STATIC_SIZE_PACKET = false, - DYNAMIC_SIZE_PACKET = true, - }; - - public: - CMainPacketHeaderMap() - { - Set(HEADER_GC_EMPIRE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCEmpire), STATIC_SIZE_PACKET)); - Set(HEADER_GC_WARP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCWarp), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SKILL_COOLTIME_END, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSkillCoolTimeEnd), STATIC_SIZE_PACKET)); - Set(HEADER_GC_QUEST_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuestInfo), DYNAMIC_SIZE_PACKET)); - Set(HEADER_GC_REQUEST_MAKE_GUILD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PVP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPVP), STATIC_SIZE_PACKET)); - Set(HEADER_GC_DUEL_START, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDuelStart), DYNAMIC_SIZE_PACKET)); - Set(HEADER_GC_CHARACTER_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterAdd), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHAR_ADDITIONAL_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterAdditionalInfo), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHARACTER_ADD2, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterAdd2), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHARACTER_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterUpdate), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHARACTER_UPDATE2, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterUpdate2), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHARACTER_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterDelete), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHARACTER_MOVE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMove), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHAT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChat), DYNAMIC_SIZE_PACKET)); - - Set(HEADER_GC_SYNC_POSITION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCC2C), DYNAMIC_SIZE_PACKET)); - - Set(HEADER_GC_LOGIN_SUCCESS3, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginSuccess3), STATIC_SIZE_PACKET)); - Set(HEADER_GC_LOGIN_SUCCESS4, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginSuccess4), STATIC_SIZE_PACKET)); - Set(HEADER_GC_LOGIN_FAILURE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginFailure), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_PLAYER_CREATE_SUCCESS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPlayerCreateSuccess), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PLAYER_CREATE_FAILURE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCreateFailure), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PLAYER_DELETE_SUCCESS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_STUN, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCStun), STATIC_SIZE_PACKET)); - Set(HEADER_GC_DEAD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDead), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_MAIN_CHARACTER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter), STATIC_SIZE_PACKET)); - - // SUPPORT_BGM - Set(HEADER_GC_MAIN_CHARACTER2_EMPIRE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter2_EMPIRE), STATIC_SIZE_PACKET)); - Set(HEADER_GC_MAIN_CHARACTER3_BGM, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter3_BGM), STATIC_SIZE_PACKET)); - Set(HEADER_GC_MAIN_CHARACTER4_BGM_VOL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter4_BGM_VOL), STATIC_SIZE_PACKET)); - // END_OFSUPPORT_BGM - - Set(HEADER_GC_PLAYER_POINTS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPoints), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PLAYER_POINT_CHANGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPointChange), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_ITEM_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemDel), STATIC_SIZE_PACKET)); - Set(HEADER_GC_ITEM_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); - Set(HEADER_GC_ITEM_GET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemGet), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_ITEM_USE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemUse), STATIC_SIZE_PACKET)); - Set(HEADER_GC_ITEM_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemUpdate), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_ITEM_GROUND_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemGroundAdd), STATIC_SIZE_PACKET)); - Set(HEADER_GC_ITEM_GROUND_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemGroundDel), STATIC_SIZE_PACKET)); - Set(HEADER_GC_ITEM_OWNERSHIP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemOwnership), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_QUICKSLOT_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuickSlotAdd), STATIC_SIZE_PACKET)); - Set(HEADER_GC_QUICKSLOT_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuickSlotDel), STATIC_SIZE_PACKET)); - Set(HEADER_GC_QUICKSLOT_SWAP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuickSlotSwap), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_WHISPER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCWhisper), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_CHARACTER_POSITION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPosition), STATIC_SIZE_PACKET)); - Set(HEADER_GC_MOTION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMotion), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_SHOP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCShop), DYNAMIC_SIZE_PACKET)); - Set(HEADER_GC_SHOP_SIGN, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCShopSign), STATIC_SIZE_PACKET)); - Set(HEADER_GC_EXCHANGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCExchange), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_PING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPing), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_SCRIPT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCScript), DYNAMIC_SIZE_PACKET)); - Set(HEADER_GC_QUEST_CONFIRM, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuestConfirm), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_TARGET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTarget), STATIC_SIZE_PACKET)); - Set(HEADER_GC_MOUNT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMount), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_CHANGE_SPEED, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChangeSpeed), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_HANDSHAKE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHandshake), STATIC_SIZE_PACKET)); - Set(HEADER_GC_HANDSHAKE_OK, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); - Set(HEADER_GC_BINDUDP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBindUDP), STATIC_SIZE_PACKET)); - Set(HEADER_GC_OWNERSHIP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCOwnership), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CREATE_FLY, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCreateFly), STATIC_SIZE_PACKET)); - // Secure key exchange (libsodium) - Set(HEADER_GC_KEY_CHALLENGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCKeyChallenge), STATIC_SIZE_PACKET)); - Set(HEADER_GC_KEY_COMPLETE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCKeyComplete), STATIC_SIZE_PACKET)); - Set(HEADER_GC_ADD_FLY_TARGETING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFlyTargeting), STATIC_SIZE_PACKET)); - Set(HEADER_GC_FLY_TARGETING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFlyTargeting), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_PHASE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPhase), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SKILL_LEVEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSkillLevel), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SKILL_LEVEL_NEW, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSkillLevelNew), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_MESSENGER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMessenger), DYNAMIC_SIZE_PACKET)); - Set(HEADER_GC_GUILD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCGuild), DYNAMIC_SIZE_PACKET)); - Set(HEADER_GC_MARK_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMarkUpdate), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_PARTY_INVITE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyInvite), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PARTY_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyAdd), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PARTY_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyUpdate), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PARTY_REMOVE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyRemove), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PARTY_LINK, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyLink), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PARTY_UNLINK, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyUnlink), STATIC_SIZE_PACKET)); - Set(HEADER_GC_PARTY_PARAMETER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyParameter), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_SAFEBOX_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SAFEBOX_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemDel), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SAFEBOX_WRONG_PASSWORD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSafeboxWrongPassword), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SAFEBOX_SIZE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSafeboxSize), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SAFEBOX_MONEY_CHANGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSafeboxMoneyChange), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_FISHING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFishing), STATIC_SIZE_PACKET)); - Set(HEADER_GC_DUNGEON, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDungeon), DYNAMIC_SIZE_PACKET)); - //Set(HEADER_GC_SLOW_TIMER, CNetworkPacketHeaderMap::TPacketType(sizeof(BYTE), STATIC_SIZE_PACKET)); - Set(HEADER_GC_TIME, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTime), STATIC_SIZE_PACKET)); - Set(HEADER_GC_WALK_MODE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCWalkMode), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHANGE_SKILL_GROUP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChangeSkillGroup), STATIC_SIZE_PACKET)); - Set(HEADER_GC_REFINE_INFORMATION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCRefineInformation), STATIC_SIZE_PACKET)); - Set(HEADER_GC_REFINE_INFORMATION_NEW, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCRefineInformationNew), STATIC_SIZE_PACKET)); - Set(HEADER_GC_SEPCIAL_EFFECT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSpecialEffect), STATIC_SIZE_PACKET)); - Set(HEADER_GC_NPC_POSITION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCNPCPosition), DYNAMIC_SIZE_PACKET)); - Set(HEADER_GC_CHANGE_NAME, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChangeName), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_LOGIN_KEY, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginKey), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_AUTH_SUCCESS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCAuthSuccess), STATIC_SIZE_PACKET)); - Set(HEADER_GC_CHANNEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChannel), STATIC_SIZE_PACKET)); - Set(HEADER_GC_VIEW_EQUIP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCViewEquip), STATIC_SIZE_PACKET)); - Set(HEADER_GC_LAND_LIST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLandList), DYNAMIC_SIZE_PACKET)); - - //Set(HEADER_GC_TARGET_CREATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetCreate), STATIC_SIZE_PACKET)); - Set(HEADER_GC_TARGET_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetUpdate), STATIC_SIZE_PACKET)); - Set(HEADER_GC_TARGET_DELETE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetDelete), STATIC_SIZE_PACKET)); - Set(HEADER_GC_TARGET_CREATE_NEW, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetCreateNew), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_AFFECT_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCAffectAdd), STATIC_SIZE_PACKET)); - Set(HEADER_GC_AFFECT_REMOVE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCAffectRemove), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_MALL_OPEN, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMallOpen), STATIC_SIZE_PACKET)); - Set(HEADER_GC_MALL_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); - Set(HEADER_GC_MALL_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemDel), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_LOVER_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoverInfo), STATIC_SIZE_PACKET)); - Set(HEADER_GC_LOVE_POINT_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLovePointUpdate), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_DIG_MOTION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDigMotion), STATIC_SIZE_PACKET)); - Set(HEADER_GC_DAMAGE_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDamageInfo), STATIC_SIZE_PACKET)); - - Set(HEADER_GC_SPECIFIC_EFFECT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSpecificEffect), STATIC_SIZE_PACKET)); - Set(HEADER_GC_DRAGON_SOUL_REFINE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDragonSoulRefine), STATIC_SIZE_PACKET)); - - } -}; - -static std::vector gs_vecLastHeaders; - void CPythonNetworkStream::ExitApplication() { if (__IsNotPing()) @@ -486,107 +319,70 @@ void CPythonNetworkStream::SetLoginKey(DWORD dwLoginKey) m_dwLoginKey = dwLoginKey; } -bool CPythonNetworkStream::CheckPacket(TPacketHeader * pRetHeader) +// Table-driven packet dispatch — replaces CheckPacket() + per-phase switch statements. +// Returns true if a packet was processed and more may follow. +// Returns false to exit the phase loop (no data, error, or exitPhase handler). +bool CPythonNetworkStream::DispatchPacket(const PacketHandlerMap& handlers) { - *pRetHeader = 0; - - static CMainPacketHeaderMap s_packetHeaderMap; - TPacketHeader header; - if (!Peek(sizeof(TPacketHeader), &header)) return false; - if (0 == header) + // Skip zero-padding (can occur from encryption alignment) + while (0 == header) { if (!Recv(sizeof(TPacketHeader), &header)) return false; - - while (Peek(sizeof(TPacketHeader), &header)) - { - if (0 == header) - { - if (!Recv(sizeof(TPacketHeader), &header)) - return false; - } - else - { - break; - } - } - - if (0 == header) + if (!Peek(sizeof(TPacketHeader), &header)) return false; } - CNetworkPacketHeaderMap::TPacketType PacketType; - - if (!s_packetHeaderMap.Get(header, &PacketType)) + // Look up handler in this phase's table + auto it = handlers.find(header); + if (it == handlers.end()) { - TraceError("Unknown packet header: %u(0x%X), Phase: %s, Last packets:", header, header, m_strPhase.c_str()); - for (const auto& it : gs_vecLastHeaders) - TraceError("%u(0x%X)", it, it); - + TraceError("Unknown packet header: 0x%04X (recv_seq #%u), Phase: %s", header, m_dwRecvPacketSeq, m_strPhase.c_str()); + DumpRecentPackets(); ClearRecvBuffer(); + return false; + } + // All packets use uniform framing: [header:2][length:2][payload...] + TDynamicSizePacketHeader packetFrame; + if (!Peek(sizeof(TDynamicSizePacketHeader), &packetFrame)) + return false; + + constexpr uint16_t MAX_PACKET_LENGTH = 65000; + if (packetFrame.length < PACKET_HEADER_SIZE || packetFrame.length > MAX_PACKET_LENGTH) + { + TraceError("DispatchPacket: Invalid packet length: header 0x%04X length: %u (min %u, max %u), recv_seq #%u", + header, packetFrame.length, PACKET_HEADER_SIZE, MAX_PACKET_LENGTH, m_dwRecvPacketSeq); + DumpRecentPackets(); + ClearRecvBuffer(); PostQuitMessage(0); return false; } - // Code for dynamic size packet - if (PacketType.isDynamicSizePacket) - { - TDynamicSizePacketHeader DynamicSizePacketHeader; - - if (!Peek(sizeof(TDynamicSizePacketHeader), &DynamicSizePacketHeader)) - return false; - - if (!Peek(DynamicSizePacketHeader.size)) - { - TraceError("CPythonNetworkStream::CheckPacket - Not enough dynamic packet size: header %d packet size: %d", - DynamicSizePacketHeader.header, - DynamicSizePacketHeader.size); - return false; - } - } - else - { - if (!Peek(PacketType.iPacketSize)) - { - TraceError("Not enough packet size: header %d packet size: %d, recv buffer size: %d last packets:", - header, - PacketType.iPacketSize, - GetRecvBufferSize() - ); - - for (const auto& it : gs_vecLastHeaders) - TraceError("%u(0x%X)", it, it); - - return false; - } - } - - if (!header) + // Wait for full packet to be received + if (!Peek(packetFrame.length)) return false; - *pRetHeader = header; + // Log this packet + LogRecvPacket(header, packetFrame.length); - // Add to last headers, if last header is contain more than 10 headers, remove first header - if (gs_vecLastHeaders.size() > 10) - gs_vecLastHeaders.erase(gs_vecLastHeaders.begin()); + // Call handler + bool ret = (this->*(it->second.handler))(); - gs_vecLastHeaders.push_back(header); + if (!ret || it->second.exitPhase) + return false; - //Tracenf("header %d size %d", header, PacketType.iPacketSize); - //Tracenf("header %d size %d outputpos[%d] security %u", header, PacketType.iPacketSize, m_recvBufOutputPos, IsSecurityMode()); return true; } bool CPythonNetworkStream::RecvErrorPacket(int header) { - TraceError("Phase %s does not handle this header (header: %u(0x%X)) Last packets: ", m_strPhase.c_str(), header, header); - for (const auto& it : gs_vecLastHeaders) - TraceError("%u(0x%X)", it, it); + TraceError("Phase %s does not handle header 0x%04X (recv_seq #%u)", m_strPhase.c_str(), header, m_dwRecvPacketSeq - 1); + DumpRecentPackets(); ClearRecvBuffer(); return true; @@ -601,43 +397,41 @@ bool CPythonNetworkStream::RecvPhasePacket() switch (packet_phase.phase) { - case PHASE_CLOSE: // 끊기는 상태 (또는 끊기 전 상태) + case PHASE_CLOSE: ClosePhase(); break; - case PHASE_HANDSHAKE: // 악수..;; + case PHASE_HANDSHAKE: SetHandShakePhase(); break; - case PHASE_LOGIN: // 로그인 중 + case PHASE_LOGIN: SetLoginPhase(); break; - case PHASE_SELECT: // 캐릭터 선택 화면 + case PHASE_SELECT: SetSelectPhase(); #if defined(ENABLE_DISCORD_RPC) Discord_Update(false); #endif - BuildProcessCRC(); - // MARK_BUG_FIX __DownloadMark(); // END_OF_MARK_BUG_FIX break; - case PHASE_LOADING: // 선택 후 로딩 화면 + case PHASE_LOADING: SetLoadingPhase(); break; - case PHASE_GAME: // 게임 화면 + case PHASE_GAME: SetGamePhase(); #if defined(ENABLE_DISCORD_RPC) Discord_Update(true); #endif break; - case PHASE_DEAD: // 죽었을 때.. (게임 안에 있는 것일 수도..) + case PHASE_DEAD: break; } @@ -646,8 +440,6 @@ bool CPythonNetworkStream::RecvPhasePacket() bool CPythonNetworkStream::RecvPingPacket() { - Tracef("recv ping packet. (securitymode %u)\n", IsSecurityMode()); - TPacketGCPing kPacketPing; if (!Recv(sizeof(TPacketGCPing), &kPacketPing)) @@ -655,9 +447,12 @@ bool CPythonNetworkStream::RecvPingPacket() m_dwLastGamePingTime = ELTimer_GetMSec(); + // Sync server time from ping + ELTimer_SetServerMSec(kPacketPing.server_time); + TPacketCGPong kPacketPong; - kPacketPong.bHeader = HEADER_CG_PONG; - kPacketPong.bSequence = GetNextSequence(); + kPacketPong.header = CG::PONG; + kPacketPong.length = sizeof(kPacketPong); if (!Send(sizeof(TPacketCGPong), &kPacketPong)) return false; @@ -665,36 +460,20 @@ bool CPythonNetworkStream::RecvPingPacket() return true; } -bool CPythonNetworkStream::RecvDefaultPacket(int header) -{ - if (!header) - return true; - - TraceError("처리되지 않은 패킷 헤더 %d, state %s\n", header, m_strPhase.c_str()); - ClearRecvBuffer(); - return true; -} - bool CPythonNetworkStream::OnProcess() { if (m_isStartGame) { m_isStartGame = FALSE; - PyCallClassMemberFunc(m_poHandler, "SetGamePhase", Py_BuildValue("()")); -// PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartGame", Py_BuildValue("()")); } - + m_rokNetActorMgr->Update(); if (m_phaseProcessFunc.IsEmpty()) return true; - //TPacketHeader header; - //while(CheckPacket(&header)) - { - m_phaseProcessFunc.Run(); - } + m_phaseProcessFunc.Run(); return true; } @@ -706,6 +485,7 @@ void CPythonNetworkStream::SetOffLinePhase() if ("OffLine" != m_strPhase) m_phaseLeaveFunc.Run(); + Tracef("[PHASE] Entering phase: OffLine\n"); m_strPhase = "OffLine"; Tracen(""); @@ -908,6 +688,15 @@ CPythonNetworkStream::CPythonNetworkStream() std::fill(m_apoPhaseWnd, m_apoPhaseWnd+PHASE_WINDOW_NUM, (PyObject*)NULL); m_poSerCommandParserWnd = NULL; + // Register packet handlers for all phases + // Note: GameHandlers must be registered before LoadingHandlers (loading copies game handlers as fallback) + RegisterOfflineHandlers(); + RegisterHandshakeHandlers(); + RegisterLoginHandlers(); + RegisterSelectHandlers(); + RegisterGameHandlers(); + RegisterLoadingHandlers(); + SetOffLinePhase(); } @@ -915,3 +704,256 @@ CPythonNetworkStream::~CPythonNetworkStream() { Tracen("PythonNetworkMainStream Clear"); } + +// --------------------------------------------------------------------------- +// Phase 5: Packet handler registration tables +// Each phase registers {header → handler, minSize, exitPhase} +// --------------------------------------------------------------------------- + +void CPythonNetworkStream::RegisterOfflineHandlers() +{ + auto& h = m_offlineHandlers; + h[GC::PHASE] = { &CPythonNetworkStream::RecvPhasePacket, sizeof(TPacketGCPhase), true }; +} + +void CPythonNetworkStream::RegisterHandshakeHandlers() +{ + auto& h = m_handshakeHandlers; + h[GC::PHASE] = { &CPythonNetworkStream::RecvPhasePacket, sizeof(TPacketGCPhase), true }; + h[GC::PING] = { &CPythonNetworkStream::RecvPingPacket, sizeof(TPacketGCPing), true }; + h[GC::KEY_CHALLENGE] = { &CPythonNetworkStream::RecvKeyChallenge, sizeof(TPacketGCKeyChallenge), true }; + h[GC::KEY_COMPLETE] = { &CPythonNetworkStream::RecvKeyComplete, sizeof(TPacketGCKeyComplete), true }; +} + +void CPythonNetworkStream::RegisterLoginHandlers() +{ + auto& h = m_loginHandlers; + h[GC::PHASE] = { &CPythonNetworkStream::RecvPhasePacket, sizeof(TPacketGCPhase), true }; + h[GC::LOGIN_SUCCESS3] = { &CPythonNetworkStream::__RecvLoginSuccessPacket3, sizeof(TPacketGCLoginSuccess3), false }; + h[GC::LOGIN_SUCCESS4] = { &CPythonNetworkStream::__RecvLoginSuccessPacket4, sizeof(TPacketGCLoginSuccess4), false }; + h[GC::LOGIN_FAILURE] = { &CPythonNetworkStream::__RecvLoginFailurePacket, sizeof(TPacketGCLoginFailure), false }; + h[GC::EMPIRE] = { &CPythonNetworkStream::__RecvEmpirePacket, sizeof(TPacketGCEmpire), false }; + h[GC::LOGIN_KEY] = { &CPythonNetworkStream::__RecvLoginKeyPacket, sizeof(TPacketGCLoginKey), false }; + h[GC::PING] = { &CPythonNetworkStream::RecvPingPacket, sizeof(TPacketGCPing), false }; + h[GC::KEY_CHALLENGE] = { &CPythonNetworkStream::RecvKeyChallenge, sizeof(TPacketGCKeyChallenge), true }; + h[GC::KEY_COMPLETE] = { &CPythonNetworkStream::RecvKeyComplete, sizeof(TPacketGCKeyComplete), true }; +} + +void CPythonNetworkStream::RegisterSelectHandlers() +{ + auto& h = m_selectHandlers; + h[GC::PHASE] = { &CPythonNetworkStream::RecvPhasePacket, sizeof(TPacketGCPhase), true }; + h[GC::EMPIRE] = { &CPythonNetworkStream::__RecvEmpirePacket, sizeof(TPacketGCEmpire), false }; + h[GC::LOGIN_SUCCESS3] = { &CPythonNetworkStream::__RecvLoginSuccessPacket3, sizeof(TPacketGCLoginSuccess3), false }; + h[GC::LOGIN_SUCCESS4] = { &CPythonNetworkStream::__RecvLoginSuccessPacket4, sizeof(TPacketGCLoginSuccess4), false }; + h[GC::PLAYER_CREATE_SUCCESS] = { &CPythonNetworkStream::__RecvPlayerCreateSuccessPacket, sizeof(TPacketGCPlayerCreateSuccess), false }; + h[GC::PLAYER_CREATE_FAILURE] = { &CPythonNetworkStream::__RecvPlayerCreateFailurePacket, sizeof(TPacketGCCreateFailure), false }; + h[GC::PLAYER_DELETE_WRONG_SOCIAL_ID] = { &CPythonNetworkStream::__RecvPlayerDestroyFailurePacket, sizeof(TPacketGCBlank), false }; + h[GC::PLAYER_DELETE_SUCCESS] = { &CPythonNetworkStream::__RecvPlayerDestroySuccessPacket, sizeof(TPacketGCDestroyCharacterSuccess), false }; + h[GC::CHANGE_NAME] = { &CPythonNetworkStream::__RecvChangeName, sizeof(TPacketGCChangeName), false }; + h[GC::PLAYER_POINT_CHANGE] = { &CPythonNetworkStream::RecvPointChange, sizeof(TPacketGCPointChange), false }; + h[GC::PING] = { &CPythonNetworkStream::RecvPingPacket, sizeof(TPacketGCPing), false }; + h[GC::KEY_CHALLENGE] = { &CPythonNetworkStream::RecvKeyChallenge, sizeof(TPacketGCKeyChallenge), true }; + h[GC::KEY_COMPLETE] = { &CPythonNetworkStream::RecvKeyComplete, sizeof(TPacketGCKeyComplete), true }; +} + +void CPythonNetworkStream::RegisterGameHandlers() +{ + auto& h = m_gameHandlers; + + // Phase / control + h[GC::PHASE] = { &CPythonNetworkStream::RecvPhasePacket, sizeof(TPacketGCPhase), true }; + h[GC::KEY_CHALLENGE] = { &CPythonNetworkStream::RecvKeyChallenge, sizeof(TPacketGCKeyChallenge), true }; + h[GC::KEY_COMPLETE] = { &CPythonNetworkStream::RecvKeyComplete, sizeof(TPacketGCKeyComplete), true }; + h[GC::PING] = { &CPythonNetworkStream::RecvPingPacket, sizeof(TPacketGCPing), false }; + + // Observer + h[GC::OBSERVER_ADD] = { &CPythonNetworkStream::RecvObserverAddPacket, sizeof(TPacketGCObserverAdd), false }; + h[GC::OBSERVER_REMOVE] = { &CPythonNetworkStream::RecvObserverRemovePacket, sizeof(TPacketGCObserverRemove), false }; + h[GC::OBSERVER_MOVE] = { &CPythonNetworkStream::RecvObserverMovePacket, sizeof(TPacketGCObserverMove), false }; + + // Warp / PVP + h[GC::WARP] = { &CPythonNetworkStream::RecvWarpPacket, sizeof(TPacketGCWarp), false }; + h[GC::PVP] = { &CPythonNetworkStream::RecvPVPPacket, sizeof(TPacketGCPVP), false }; + h[GC::DUEL_START] = { &CPythonNetworkStream::RecvDuelStartPacket, sizeof(TPacketGCDuelStart), false }; + + // Character + h[GC::CHARACTER_ADD] = { &CPythonNetworkStream::RecvCharacterAppendPacket, sizeof(TPacketGCCharacterAdd), false }; + h[GC::CHAR_ADDITIONAL_INFO] = { &CPythonNetworkStream::RecvCharacterAdditionalInfo, sizeof(TPacketGCCharacterAdditionalInfo), false }; + h[GC::CHARACTER_ADD2] = { &CPythonNetworkStream::RecvCharacterAppendPacketNew, sizeof(TPacketGCCharacterAdd2), false }; + h[GC::CHARACTER_UPDATE] = { &CPythonNetworkStream::RecvCharacterUpdatePacket, sizeof(TPacketGCCharacterUpdate), false }; + h[GC::CHARACTER_UPDATE2] = { &CPythonNetworkStream::RecvCharacterUpdatePacketNew, sizeof(TPacketGCCharacterUpdate2), false }; + h[GC::CHARACTER_DEL] = { &CPythonNetworkStream::RecvCharacterDeletePacket, sizeof(TPacketGCCharacterDelete), false }; + h[GC::CHAT] = { &CPythonNetworkStream::RecvChatPacket, sizeof(TPacketGCChat), false }; + h[GC::SYNC_POSITION] = { &CPythonNetworkStream::RecvSyncPositionPacket, sizeof(TPacketGCC2C), false }; + h[GC::OWNERSHIP] = { &CPythonNetworkStream::RecvOwnerShipPacket, sizeof(TPacketGCOwnership), false }; + h[GC::WHISPER] = { &CPythonNetworkStream::RecvWhisperPacket, sizeof(TPacketGCWhisper), false }; + h[GC::MOVE] = { &CPythonNetworkStream::RecvCharacterMovePacket, sizeof(TPacketGCMove), false }; + h[GC::CHARACTER_POSITION] = { &CPythonNetworkStream::RecvCharacterPositionPacket, sizeof(TPacketGCPosition), false }; + + // Combat + h[GC::STUN] = { &CPythonNetworkStream::RecvStunPacket, sizeof(TPacketGCStun), false }; + h[GC::DEAD] = { &CPythonNetworkStream::RecvDeadPacket, sizeof(TPacketGCDead), false }; + h[GC::PLAYER_POINT_CHANGE] = { &CPythonNetworkStream::RecvPointChange, sizeof(TPacketGCPointChange), false }; + h[GC::DAMAGE_INFO] = { &CPythonNetworkStream::RecvDamageInfoPacket, sizeof(TPacketGCDamageInfo), false }; + + // Items + h[GC::ITEM_DEL] = { &CPythonNetworkStream::RecvItemDelPacket, sizeof(TPacketGCItemDel), false }; + h[GC::ITEM_SET] = { &CPythonNetworkStream::RecvItemSetPacket, sizeof(TPacketGCItemSet), false }; + h[GC::ITEM_GET] = { &CPythonNetworkStream::RecvItemGetPacket, sizeof(TPacketGCItemGet), false }; + h[GC::ITEM_USE] = { &CPythonNetworkStream::RecvItemUsePacket, sizeof(TPacketGCItemUse), false }; + h[GC::ITEM_UPDATE] = { &CPythonNetworkStream::RecvItemUpdatePacket, sizeof(TPacketGCItemUpdate), false }; + h[GC::ITEM_GROUND_ADD] = { &CPythonNetworkStream::RecvItemGroundAddPacket, sizeof(TPacketGCItemGroundAdd), false }; + h[GC::ITEM_GROUND_DEL] = { &CPythonNetworkStream::RecvItemGroundDelPacket, sizeof(TPacketGCItemGroundDel), false }; + h[GC::ITEM_OWNERSHIP] = { &CPythonNetworkStream::RecvItemOwnership, sizeof(TPacketGCItemOwnership), false }; + + // Quickslot + h[GC::QUICKSLOT_ADD] = { &CPythonNetworkStream::RecvQuickSlotAddPacket, sizeof(TPacketGCQuickSlotAdd), false }; + h[GC::QUICKSLOT_DEL] = { &CPythonNetworkStream::RecvQuickSlotDelPacket, sizeof(TPacketGCQuickSlotDel), false }; + h[GC::QUICKSLOT_SWAP] = { &CPythonNetworkStream::RecvQuickSlotMovePacket, sizeof(TPacketGCQuickSlotSwap), false }; + + // Motion / Movement + h[GC::MOTION] = { &CPythonNetworkStream::RecvMotionPacket, sizeof(TPacketGCMotion), false }; + h[GC::CHANGE_SPEED] = { &CPythonNetworkStream::RecvChangeSpeedPacket, sizeof(TPacketGCChangeSpeed), false }; + + // Shop / Exchange + h[GC::SHOP] = { &CPythonNetworkStream::RecvShopPacket, sizeof(TPacketGCShop), false }; + h[GC::SHOP_SIGN] = { &CPythonNetworkStream::RecvShopSignPacket, sizeof(TPacketGCShopSign), false }; + h[GC::EXCHANGE] = { &CPythonNetworkStream::RecvExchangePacket, sizeof(TPacketGCExchange), false }; + + // Quest + h[GC::QUEST_INFO] = { &CPythonNetworkStream::RecvQuestInfoPacket, sizeof(TPacketGCQuestInfo), false }; + h[GC::REQUEST_MAKE_GUILD] = { &CPythonNetworkStream::RecvRequestMakeGuild, sizeof(TPacketGCBlank), false }; + h[GC::SCRIPT] = { &CPythonNetworkStream::RecvScriptPacket, sizeof(TPacketGCScript), false }; + h[GC::QUEST_CONFIRM] = { &CPythonNetworkStream::RecvQuestConfirmPacket, sizeof(TPacketGCQuestConfirm), false }; + + // Target / Mount + h[GC::TARGET] = { &CPythonNetworkStream::RecvTargetPacket, sizeof(TPacketGCTarget), false }; + h[GC::MOUNT] = { &CPythonNetworkStream::RecvMountPacket, sizeof(TPacketGCMount), false }; + + // Points + h[GC::PLAYER_POINTS] = { &CPythonNetworkStream::__RecvPlayerPoints, sizeof(TPacketGCPoints), false }; + + // Fly + h[GC::CREATE_FLY] = { &CPythonNetworkStream::RecvCreateFlyPacket, sizeof(TPacketGCCreateFly), false }; + h[GC::FLY_TARGETING] = { &CPythonNetworkStream::RecvFlyTargetingPacket, sizeof(TPacketGCFlyTargeting), false }; + h[GC::ADD_FLY_TARGETING] = { &CPythonNetworkStream::RecvAddFlyTargetingPacket, sizeof(TPacketGCFlyTargeting), false }; + + // Skills + h[GC::SKILL_LEVEL] = { &CPythonNetworkStream::RecvSkillLevel, sizeof(TPacketGCSkillLevel), false }; + h[GC::SKILL_LEVEL_NEW] = { &CPythonNetworkStream::RecvSkillLevelNew, sizeof(TPacketGCSkillLevelNew), false }; + h[GC::SKILL_COOLTIME_END] = { &CPythonNetworkStream::RecvSkillCoolTimeEnd, sizeof(TPacketGCSkillCoolTimeEnd), false }; + + // Messenger / Guild + h[GC::MESSENGER] = { &CPythonNetworkStream::RecvMessenger, sizeof(TPacketGCMessenger), false }; + h[GC::GUILD] = { &CPythonNetworkStream::RecvGuild, sizeof(TPacketGCGuild), false }; + h[GC::MARK_UPDATE] = { &CPythonNetworkStream::RecvMarkUpdate, sizeof(TPacketGCMarkUpdate), false }; + + // Party + h[GC::PARTY_INVITE] = { &CPythonNetworkStream::RecvPartyInvite, sizeof(TPacketGCPartyInvite), false }; + h[GC::PARTY_ADD] = { &CPythonNetworkStream::RecvPartyAdd, sizeof(TPacketGCPartyAdd), false }; + h[GC::PARTY_UPDATE] = { &CPythonNetworkStream::RecvPartyUpdate, sizeof(TPacketGCPartyUpdate), false }; + h[GC::PARTY_REMOVE] = { &CPythonNetworkStream::RecvPartyRemove, sizeof(TPacketGCPartyRemove), false }; + h[GC::PARTY_LINK] = { &CPythonNetworkStream::RecvPartyLink, sizeof(TPacketGCPartyLink), false }; + h[GC::PARTY_UNLINK] = { &CPythonNetworkStream::RecvPartyUnlink, sizeof(TPacketGCPartyUnlink), false }; + h[GC::PARTY_PARAMETER] = { &CPythonNetworkStream::RecvPartyParameter, sizeof(TPacketGCPartyParameter), false }; + + // Safebox + h[GC::SAFEBOX_SET] = { &CPythonNetworkStream::RecvSafeBoxSetPacket, sizeof(TPacketGCItemSet), false }; + h[GC::SAFEBOX_DEL] = { &CPythonNetworkStream::RecvSafeBoxDelPacket, sizeof(TPacketGCItemDel), false }; + h[GC::SAFEBOX_WRONG_PASSWORD] = { &CPythonNetworkStream::RecvSafeBoxWrongPasswordPacket, sizeof(TPacketGCSafeboxWrongPassword), false }; + h[GC::SAFEBOX_SIZE] = { &CPythonNetworkStream::RecvSafeBoxSizePacket, sizeof(TPacketGCSafeboxSize), false }; + h[GC::SAFEBOX_MONEY_CHANGE] = { &CPythonNetworkStream::RecvSafeBoxMoneyChangePacket, sizeof(TPacketGCSafeboxMoneyChange), false }; + + // Fishing / Dungeon / Time + h[GC::FISHING] = { &CPythonNetworkStream::RecvFishing, sizeof(TPacketGCFishing), false }; + h[GC::DUNGEON] = { &CPythonNetworkStream::RecvDungeon, sizeof(TPacketGCDungeon), false }; + h[GC::TIME] = { &CPythonNetworkStream::RecvTimePacket, sizeof(TPacketGCTime), false }; + + // Walk / Skill group / Refine + h[GC::WALK_MODE] = { &CPythonNetworkStream::RecvWalkModePacket, sizeof(TPacketGCWalkMode), false }; + h[GC::CHANGE_SKILL_GROUP] = { &CPythonNetworkStream::RecvChangeSkillGroupPacket, sizeof(TPacketGCChangeSkillGroup), false }; + h[GC::REFINE_INFORMATION] = { &CPythonNetworkStream::RecvRefineInformationPacket, sizeof(TPacketGCRefineInformation), false }; + h[GC::REFINE_INFORMATION_NEW] = { &CPythonNetworkStream::RecvRefineInformationPacketNew, sizeof(TPacketGCRefineInformationNew), false }; + + // Effects + h[GC::SEPCIAL_EFFECT] = { &CPythonNetworkStream::RecvSpecialEffect, sizeof(TPacketGCSpecialEffect), false }; + h[GC::SPECIFIC_EFFECT] = { &CPythonNetworkStream::RecvSpecificEffect, sizeof(TPacketGCSpecificEffect), false }; + + // Map / NPC + h[GC::NPC_POSITION] = { &CPythonNetworkStream::RecvNPCList, sizeof(TPacketGCNPCPosition), false }; + h[GC::CHANNEL] = { &CPythonNetworkStream::RecvChannelPacket, sizeof(TPacketGCChannel), false }; + h[GC::VIEW_EQUIP] = { &CPythonNetworkStream::RecvViewEquipPacket, sizeof(TPacketGCViewEquip), false }; + h[GC::LAND_LIST] = { &CPythonNetworkStream::RecvLandPacket, sizeof(TPacketGCLandList), false }; + + // Target + h[GC::TARGET_CREATE_NEW] = { &CPythonNetworkStream::RecvTargetCreatePacketNew, sizeof(TPacketGCTargetCreateNew), false }; + h[GC::TARGET_UPDATE] = { &CPythonNetworkStream::RecvTargetUpdatePacket, sizeof(TPacketGCTargetUpdate), false }; + h[GC::TARGET_DELETE] = { &CPythonNetworkStream::RecvTargetDeletePacket, sizeof(TPacketGCTargetDelete), false }; + + // Affect + h[GC::AFFECT_ADD] = { &CPythonNetworkStream::RecvAffectAddPacket, sizeof(TPacketGCAffectAdd), false }; + h[GC::AFFECT_REMOVE] = { &CPythonNetworkStream::RecvAffectRemovePacket, sizeof(TPacketGCAffectRemove), false }; + + // Mall + h[GC::MALL_OPEN] = { &CPythonNetworkStream::RecvMallOpenPacket, sizeof(TPacketGCMallOpen), false }; + h[GC::MALL_SET] = { &CPythonNetworkStream::RecvMallItemSetPacket, sizeof(TPacketGCItemSet), false }; + h[GC::MALL_DEL] = { &CPythonNetworkStream::RecvMallItemDelPacket, sizeof(TPacketGCItemDel), false }; + + // Lover + h[GC::LOVER_INFO] = { &CPythonNetworkStream::RecvLoverInfoPacket, sizeof(TPacketGCLoverInfo), false }; + h[GC::LOVE_POINT_UPDATE] = { &CPythonNetworkStream::RecvLovePointUpdatePacket, sizeof(TPacketGCLovePointUpdate), false }; + + // Misc + h[GC::DIG_MOTION] = { &CPythonNetworkStream::RecvDigMotionPacket, sizeof(TPacketGCDigMotion), false }; + h[GC::DRAGON_SOUL_REFINE] = { &CPythonNetworkStream::RecvDragonSoulRefine, sizeof(TPacketGCDragonSoulRefine), false }; +} + +void CPythonNetworkStream::RegisterLoadingHandlers() +{ + // Loading phase: start with ALL game handlers as fallback (old code: default -> GamePhase()) + m_loadingHandlers = m_gameHandlers; + + // Override/add loading-specific handlers + m_loadingHandlers[GC::PHASE] = { &CPythonNetworkStream::RecvPhasePacket, sizeof(TPacketGCPhase), true }; + m_loadingHandlers[GC::MAIN_CHARACTER] = { &CPythonNetworkStream::RecvMainCharacter, sizeof(TPacketGCMainCharacter), false }; +} + +// --- Packet sequence tracking --- + +void CPythonNetworkStream::LogRecvPacket(uint16_t header, uint16_t length) +{ + auto& e = m_aRecentRecvPackets[m_dwRecvPacketSeq % PACKET_LOG_SIZE]; + e.seq = m_dwRecvPacketSeq; + e.header = header; + e.length = length; + m_dwRecvPacketSeq++; +} + +void CPythonNetworkStream::DumpRecentPackets() const +{ + const uint32_t recvCount = std::min(m_dwRecvPacketSeq, (uint32_t)PACKET_LOG_SIZE); + const uint32_t sentCount = std::min(m_dwSentPacketSeq, (uint32_t)SENT_PACKET_LOG_SIZE); + + TraceError("=== Recent RECV packets (last %u of %u total) ===", recvCount, m_dwRecvPacketSeq); + + for (uint32_t i = 0; i < recvCount; i++) + { + uint32_t idx = (m_dwRecvPacketSeq > PACKET_LOG_SIZE) + ? (m_dwRecvPacketSeq - PACKET_LOG_SIZE + i) + : i; + const auto& e = m_aRecentRecvPackets[idx % PACKET_LOG_SIZE]; + TraceError(" RECV #%u: header=0x%04X len=%u", e.seq, e.header, e.length); + } + + TraceError("=== Recent SENT packets (last %u of %u total) ===", sentCount, m_dwSentPacketSeq); + + for (uint32_t i = 0; i < sentCount; i++) + { + uint32_t idx = (m_dwSentPacketSeq > SENT_PACKET_LOG_SIZE) + ? (m_dwSentPacketSeq - SENT_PACKET_LOG_SIZE + i) + : i; + const auto& e = m_aSentPacketLog[idx % SENT_PACKET_LOG_SIZE]; + TraceError(" SENT #%u: header=0x%04X len=%u", e.seq, e.header, e.length); + } +} diff --git a/src/UserInterface/PythonNetworkStream.h b/src/UserInterface/PythonNetworkStream.h index ceb2b14..6c6af6d 100644 --- a/src/UserInterface/PythonNetworkStream.h +++ b/src/UserInterface/PythonNetworkStream.h @@ -1,8 +1,10 @@ #pragma once +#include +#include + #include "EterLib/FuncObject.h" #include "EterLib/NetStream.h" -#include "EterLib/NetPacketHeaderMap.h" #include "InsultChecker.h" @@ -15,6 +17,15 @@ struct SNetworkUpdateActorData; class CPythonNetworkStream : public CNetworkStream, public CSingleton { + public: + // Table-driven packet dispatch (Phase 5) + struct PacketHandlerEntry { + bool (CPythonNetworkStream::*handler)(); + uint16_t minSize; + bool exitPhase; // true = stop dispatch loop after handling (phase-changing packets) + }; + using PacketHandlerMap = std::unordered_map; + public: enum { @@ -266,13 +277,9 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton& buf); + bool RecvShopSub_StartEx(const std::vector& buf); + bool RecvShopSub_End(const std::vector& buf); + bool RecvShopSub_UpdateItem(const std::vector& buf); + bool RecvShopSub_UpdatePrice(const std::vector& buf); + bool RecvShopSub_NotEnoughMoney(const std::vector& buf); + bool RecvShopSub_NotEnoughMoneyEx(const std::vector& buf); + bool RecvShopSub_Soldout(const std::vector& buf); + bool RecvShopSub_InventoryFull(const std::vector& buf); + bool RecvShopSub_InvalidPos(const std::vector& buf); + bool RecvShopSignPacket(); + bool RecvExchangePacket(); + // Exchange sub-handlers + bool RecvExchangeSub_Start(const TPacketGCExchange& pack); + bool RecvExchangeSub_ItemAdd(const TPacketGCExchange& pack); + bool RecvExchangeSub_ItemDel(const TPacketGCExchange& pack); + bool RecvExchangeSub_ElkAdd(const TPacketGCExchange& pack); + bool RecvExchangeSub_Accept(const TPacketGCExchange& pack); + bool RecvExchangeSub_End(const TPacketGCExchange& pack); + bool RecvExchangeSub_Already(const TPacketGCExchange& pack); + bool RecvExchangeSub_LessElk(const TPacketGCExchange& pack); // Quest bool RecvScriptPacket(); @@ -489,6 +513,28 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton m_kQue_stHack; + // Per-phase handler dispatch tables + PacketHandlerMap m_offlineHandlers; + PacketHandlerMap m_handshakeHandlers; + PacketHandlerMap m_loginHandlers; + PacketHandlerMap m_selectHandlers; + PacketHandlerMap m_loadingHandlers; + PacketHandlerMap m_gameHandlers; + private: struct SDirectEnterMode { @@ -726,4 +786,23 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton kMap_kPacketInfo; - kMap_kPacketInfo.clear(); #endif - const DWORD MAX_RECV_COUNT = 4; + const DWORD MAX_RECV_COUNT = 32; const DWORD SAFE_RECV_BUFSIZE = 8192; DWORD dwRecvCount = 0; - while (ret) + while (true) { - if(dwRecvCount++ >= MAX_RECV_COUNT-1 && GetRecvBufferSize() < SAFE_RECV_BUFSIZE - && m_strPhase == "Game") //phase_game 이 아니어도 여기로 들어오는 경우가 있다. + if (dwRecvCount++ >= MAX_RECV_COUNT-1 && GetRecvBufferSize() < SAFE_RECV_BUFSIZE + && m_strPhase == "Game") break; - if (!CheckPacket(&header)) + if (!DispatchPacket(m_gameHandlers)) break; - -#ifdef __PERFORMANCE_CHECK__ - DWORD timeBeginPacket=timeGetTime(); -#endif - - switch (header) - { - case HEADER_GC_OBSERVER_ADD: - ret = RecvObserverAddPacket(); - break; - case HEADER_GC_OBSERVER_REMOVE: - ret = RecvObserverRemovePacket(); - break; - case HEADER_GC_OBSERVER_MOVE: - ret = RecvObserverMovePacket(); - break; - case HEADER_GC_WARP: - ret = RecvWarpPacket(); - break; - - case HEADER_GC_PHASE: - ret = RecvPhasePacket(); - return; // 도중에 Phase 가 바뀌면 일단 무조건 GamePhase 탈출 - [levites] - break; - - case HEADER_GC_PVP: - ret = RecvPVPPacket(); - break; - - case HEADER_GC_DUEL_START: - ret = RecvDuelStartPacket(); - break; - - case HEADER_GC_CHARACTER_ADD: - ret = RecvCharacterAppendPacket(); - break; - - case HEADER_GC_CHAR_ADDITIONAL_INFO: - ret = RecvCharacterAdditionalInfo(); - break; - - case HEADER_GC_CHARACTER_ADD2: - ret = RecvCharacterAppendPacketNew(); - break; - - case HEADER_GC_CHARACTER_UPDATE: - ret = RecvCharacterUpdatePacket(); - break; - - case HEADER_GC_CHARACTER_UPDATE2: - ret = RecvCharacterUpdatePacketNew(); - break; - - case HEADER_GC_CHARACTER_DEL: - ret = RecvCharacterDeletePacket(); - break; - - case HEADER_GC_CHAT: - ret = RecvChatPacket(); - break; - - case HEADER_GC_SYNC_POSITION: - ret = RecvSyncPositionPacket(); - break; - - case HEADER_GC_OWNERSHIP: - ret = RecvOwnerShipPacket(); - break; - - case HEADER_GC_WHISPER: - ret = RecvWhisperPacket(); - break; - - case HEADER_GC_CHARACTER_MOVE: - ret = RecvCharacterMovePacket(); - break; - - // Position - case HEADER_GC_CHARACTER_POSITION: - ret = RecvCharacterPositionPacket(); - break; - - // Battle Packet - case HEADER_GC_STUN: - ret = RecvStunPacket(); - break; - - case HEADER_GC_DEAD: - ret = RecvDeadPacket(); - break; - - case HEADER_GC_PLAYER_POINT_CHANGE: - ret = RecvPointChange(); - break; - - // item packet. - case HEADER_GC_ITEM_DEL: - ret = RecvItemDelPacket(); - break; - - case HEADER_GC_ITEM_SET: - ret = RecvItemSetPacket(); - break; - - case HEADER_GC_ITEM_GET: - ret = RecvItemGetPacket(); - break; - - case HEADER_GC_ITEM_USE: - ret = RecvItemUsePacket(); - break; - - case HEADER_GC_ITEM_UPDATE: - ret = RecvItemUpdatePacket(); - break; - - case HEADER_GC_ITEM_GROUND_ADD: - ret = RecvItemGroundAddPacket(); - break; - - case HEADER_GC_ITEM_GROUND_DEL: - ret = RecvItemGroundDelPacket(); - break; - - case HEADER_GC_ITEM_OWNERSHIP: - ret = RecvItemOwnership(); - break; - - case HEADER_GC_QUICKSLOT_ADD: - ret = RecvQuickSlotAddPacket(); - break; - - case HEADER_GC_QUICKSLOT_DEL: - ret = RecvQuickSlotDelPacket(); - break; - - case HEADER_GC_QUICKSLOT_SWAP: - ret = RecvQuickSlotMovePacket(); - break; - - case HEADER_GC_MOTION: - ret = RecvMotionPacket(); - break; - - case HEADER_GC_SHOP: - ret = RecvShopPacket(); - break; - - case HEADER_GC_SHOP_SIGN: - ret = RecvShopSignPacket(); - break; - - case HEADER_GC_EXCHANGE: - ret = RecvExchangePacket(); - break; - - case HEADER_GC_QUEST_INFO: - ret = RecvQuestInfoPacket(); - break; - - case HEADER_GC_REQUEST_MAKE_GUILD: - ret = RecvRequestMakeGuild(); - break; - - case HEADER_GC_PING: - ret = RecvPingPacket(); - break; - - case HEADER_GC_SCRIPT: - ret = RecvScriptPacket(); - break; - - case HEADER_GC_QUEST_CONFIRM: - ret = RecvQuestConfirmPacket(); - break; - - case HEADER_GC_TARGET: - ret = RecvTargetPacket(); - break; - - case HEADER_GC_DAMAGE_INFO: - ret = RecvDamageInfoPacket(); - break; - - case HEADER_GC_MOUNT: - ret = RecvMountPacket(); - break; - - case HEADER_GC_CHANGE_SPEED: - ret = RecvChangeSpeedPacket(); - break; - - case HEADER_GC_PLAYER_POINTS: - ret = __RecvPlayerPoints(); - break; - - case HEADER_GC_CREATE_FLY: - ret = RecvCreateFlyPacket(); - break; - - case HEADER_GC_FLY_TARGETING: - ret = RecvFlyTargetingPacket(); - break; - - case HEADER_GC_ADD_FLY_TARGETING: - ret = RecvAddFlyTargetingPacket(); - break; - - case HEADER_GC_SKILL_LEVEL: - ret = RecvSkillLevel(); - break; - - case HEADER_GC_SKILL_LEVEL_NEW: - ret = RecvSkillLevelNew(); - break; - - case HEADER_GC_MESSENGER: - ret = RecvMessenger(); - break; - - case HEADER_GC_GUILD: - ret = RecvGuild(); - break; - - case HEADER_GC_MARK_UPDATE: - ret = RecvMarkUpdate(); - break; - - case HEADER_GC_PARTY_INVITE: - ret = RecvPartyInvite(); - break; - - case HEADER_GC_PARTY_ADD: - ret = RecvPartyAdd(); - break; - - case HEADER_GC_PARTY_UPDATE: - ret = RecvPartyUpdate(); - break; - - case HEADER_GC_PARTY_REMOVE: - ret = RecvPartyRemove(); - break; - - case HEADER_GC_PARTY_LINK: - ret = RecvPartyLink(); - break; - - case HEADER_GC_PARTY_UNLINK: - ret = RecvPartyUnlink(); - break; - - case HEADER_GC_PARTY_PARAMETER: - ret = RecvPartyParameter(); - break; - - case HEADER_GC_SAFEBOX_SET: - ret = RecvSafeBoxSetPacket(); - break; - - case HEADER_GC_SAFEBOX_DEL: - ret = RecvSafeBoxDelPacket(); - break; - - case HEADER_GC_SAFEBOX_WRONG_PASSWORD: - ret = RecvSafeBoxWrongPasswordPacket(); - break; - - case HEADER_GC_SAFEBOX_SIZE: - ret = RecvSafeBoxSizePacket(); - break; - - case HEADER_GC_SAFEBOX_MONEY_CHANGE: - ret = RecvSafeBoxMoneyChangePacket(); - break; - - case HEADER_GC_FISHING: - ret = RecvFishing(); - break; - - case HEADER_GC_DUNGEON: - ret = RecvDungeon(); - break; - - case HEADER_GC_TIME: - ret = RecvTimePacket(); - break; - - case HEADER_GC_WALK_MODE: - ret = RecvWalkModePacket(); - break; - - case HEADER_GC_CHANGE_SKILL_GROUP: - ret = RecvChangeSkillGroupPacket(); - break; - - case HEADER_GC_REFINE_INFORMATION: - ret = RecvRefineInformationPacket(); - break; - - case HEADER_GC_REFINE_INFORMATION_NEW: - ret = RecvRefineInformationPacketNew(); - break; - - case HEADER_GC_SEPCIAL_EFFECT: - ret = RecvSpecialEffect(); - break; - - case HEADER_GC_NPC_POSITION: - ret = RecvNPCList(); - break; - - case HEADER_GC_CHANNEL: - ret = RecvChannelPacket(); - break; - - case HEADER_GC_VIEW_EQUIP: - ret = RecvViewEquipPacket(); - break; - - case HEADER_GC_LAND_LIST: - ret = RecvLandPacket(); - break; - - //case HEADER_GC_TARGET_CREATE: - // ret = RecvTargetCreatePacket(); - // break; - - case HEADER_GC_TARGET_CREATE_NEW: - ret = RecvTargetCreatePacketNew(); - break; - - case HEADER_GC_TARGET_UPDATE: - ret = RecvTargetUpdatePacket(); - break; - - case HEADER_GC_TARGET_DELETE: - ret = RecvTargetDeletePacket(); - break; - - case HEADER_GC_AFFECT_ADD: - ret = RecvAffectAddPacket(); - break; - - case HEADER_GC_AFFECT_REMOVE: - ret = RecvAffectRemovePacket(); - break; - - case HEADER_GC_MALL_OPEN: - ret = RecvMallOpenPacket(); - break; - - case HEADER_GC_MALL_SET: - ret = RecvMallItemSetPacket(); - break; - - case HEADER_GC_MALL_DEL: - ret = RecvMallItemDelPacket(); - break; - - case HEADER_GC_LOVER_INFO: - ret = RecvLoverInfoPacket(); - break; - - case HEADER_GC_LOVE_POINT_UPDATE: - ret = RecvLovePointUpdatePacket(); - break; - - case HEADER_GC_DIG_MOTION: - ret = RecvDigMotionPacket(); - break; - - case HEADER_GC_HANDSHAKE: - RecvHandshakePacket(); - return; - break; - - case HEADER_GC_HANDSHAKE_OK: - RecvHandshakeOKPacket(); - return; - break; - - case HEADER_GC_KEY_CHALLENGE: - RecvKeyChallenge(); - return; - break; - - case HEADER_GC_KEY_COMPLETE: - RecvKeyComplete(); - return; - break; - - case HEADER_GC_SPECIFIC_EFFECT: - ret = RecvSpecificEffect(); - break; - - case HEADER_GC_DRAGON_SOUL_REFINE: - ret = RecvDragonSoulRefine(); - break; - - default: - ret = RecvDefaultPacket(header); - break; - } -#ifdef __PERFORMANCE_CHECK__ - DWORD timeEndPacket=timeGetTime(); - - { - PERF_PacketInfo& rkPacketInfo=kMap_kPacketInfo[header]; - rkPacketInfo.dwCount++; - rkPacketInfo.dwTime+=timeEndPacket-timeBeginPacket; - } - - { - PERF_PacketInfo& rkPacketInfo=gs_kPacketTimeAnalyzer.m_kMap_kPacketInfo[header]; - rkPacketInfo.dwCount++; - rkPacketInfo.dwTime+=timeEndPacket-timeBeginPacket; - } -#endif } #ifdef __PERFORMANCE_CHECK__ DWORD timeEndDispatch=timeGetTime(); - + if (timeEndDispatch-timeBeginDispatch>2) { - static FILE* fp=fopen("perf_dispatch_packet.txt", "w"); - + static FILE* fp=fopen("perf_dispatch_packet.txt", "w"); fprintf(fp, "delay %d\n", timeEndDispatch-timeBeginDispatch); - for (std::map::iterator i=kMap_kPacketInfo.begin(); i!=kMap_kPacketInfo.end(); ++i) - { - if (i->second.dwTime>0) - fprintf(fp, "header %d: count %d, time %d\n", i->first, i->second.dwCount, i->second.dwTime); - } fputs("=====================================================\n", fp); fflush(fp); } #endif - if (!ret) - RecvErrorPacket(header); - static DWORD s_nextRefreshTime = ELTimer_GetMSec(); DWORD curTime = ELTimer_GetMSec(); @@ -847,18 +413,12 @@ void CPythonNetworkStream::SetGamePhase() if ("Game"!=m_strPhase) m_phaseLeaveFunc.Run(); - Tracen(""); - Tracen("## Network - Game Phase ##"); - Tracen(""); - m_strPhase = "Game"; m_dwChangingPhaseTime = ELTimer_GetMSec(); m_phaseProcessFunc.Set(this, &CPythonNetworkStream::GamePhase); m_phaseLeaveFunc.Set(this, &CPythonNetworkStream::__LeaveGamePhase); - // Main Character 등록O - IAbstractPlayer & rkPlayer = IAbstractPlayer::GetSingleton(); rkPlayer.SetMainCharacterIndex(GetMainActorVID()); @@ -881,7 +441,7 @@ bool CPythonNetworkStream::RecvObserverAddPacket() bool CPythonNetworkStream::RecvObserverRemovePacket() { - TPacketGCObserverAdd kObserverRemovePacket; + TPacketGCObserverRemove kObserverRemovePacket; if (!Recv(sizeof(kObserverRemovePacket), &kObserverRemovePacket)) return false; @@ -927,7 +487,7 @@ bool CPythonNetworkStream::RecvDuelStartPacket() if (!Recv(sizeof(kDuelStartPacket), &kDuelStartPacket)) return false; - DWORD count = (kDuelStartPacket.wSize - sizeof(kDuelStartPacket))/sizeof(DWORD); + DWORD count = (kDuelStartPacket.length - sizeof(kDuelStartPacket))/sizeof(DWORD); CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); @@ -1021,7 +581,8 @@ bool CPythonNetworkStream::RecvPVPPacket() void CPythonNetworkStream::__SendWarpPacket() { TPacketCGWarp kWarpPacket; - kWarpPacket.bHeader=HEADER_GC_WARP; + kWarpPacket.header=GC::WARP; + kWarpPacket.length = sizeof(kWarpPacket); if (!Send(sizeof(kWarpPacket), &kWarpPacket)) { return; @@ -1042,32 +603,35 @@ bool CPythonNetworkStream::__SendHack(const char* c_szMsg) Tracen(c_szMsg); TPacketCGHack kPacketHack; - kPacketHack.bHeader=HEADER_CG_HACK; + kPacketHack.header=CG::HACK; + kPacketHack.length = sizeof(kPacketHack); strncpy(kPacketHack.szBuf, c_szMsg, sizeof(kPacketHack.szBuf)-1); if (!Send(sizeof(kPacketHack), &kPacketHack)) return false; - return SendSequence(); + return true; } bool CPythonNetworkStream::SendMessengerAddByVIDPacket(DWORD vid) { TPacketCGMessenger packet; - packet.header = HEADER_CG_MESSENGER; - packet.subheader = MESSENGER_SUBHEADER_CG_ADD_BY_VID; + packet.header = CG::MESSENGER; + packet.length = sizeof(packet) + sizeof(vid); + packet.subheader = MessengerSub::CG::ADD_BY_VID; if (!Send(sizeof(packet), &packet)) return false; if (!Send(sizeof(vid), &vid)) return false; - return SendSequence(); + return true; } bool CPythonNetworkStream::SendMessengerAddByNamePacket(const char * c_szName) { TPacketCGMessenger packet; - packet.header = HEADER_CG_MESSENGER; - packet.subheader = MESSENGER_SUBHEADER_CG_ADD_BY_NAME; + packet.header = CG::MESSENGER; + packet.length = sizeof(packet) + sizeof(char[CHARACTER_NAME_MAX_LEN]); + packet.subheader = MessengerSub::CG::ADD_BY_NAME; if (!Send(sizeof(packet), &packet)) return false; char szName[CHARACTER_NAME_MAX_LEN]; @@ -1077,14 +641,15 @@ bool CPythonNetworkStream::SendMessengerAddByNamePacket(const char * c_szName) if (!Send(sizeof(szName), &szName)) return false; Tracef(" SendMessengerAddByNamePacket : %s\n", c_szName); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendMessengerRemovePacket(const char * c_szKey, const char * c_szName) { TPacketCGMessenger packet; - packet.header = HEADER_CG_MESSENGER; - packet.subheader = MESSENGER_SUBHEADER_CG_REMOVE; + packet.header = CG::MESSENGER; + packet.length = sizeof(packet) + sizeof(char[CHARACTER_NAME_MAX_LEN]); + packet.subheader = MessengerSub::CG::REMOVE; if (!Send(sizeof(packet), &packet)) return false; char szKey[CHARACTER_NAME_MAX_LEN]; @@ -1092,7 +657,7 @@ bool CPythonNetworkStream::SendMessengerRemovePacket(const char * c_szKey, const if (!Send(sizeof(szKey), &szKey)) return false; __RefreshTargetBoardByName(c_szName); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendCharacterStatePacket(const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) @@ -1108,7 +673,8 @@ bool CPythonNetworkStream::SendCharacterStatePacket(const TPixelPosition& c_rkPP // TODO: 나중에 패킷이름을 바꾸자 TPacketCGMove kStatePacket; - kStatePacket.bHeader = HEADER_CG_CHARACTER_MOVE; + kStatePacket.header = CG::MOVE; + kStatePacket.length = sizeof(kStatePacket); kStatePacket.bFunc = eFunc; kStatePacket.bArg = uArg; kStatePacket.bRot = fDstRot/5.0f; @@ -1132,7 +698,7 @@ bool CPythonNetworkStream::SendCharacterStatePacket(const TPixelPosition& c_rkPP return false; } NANOEND - return SendSequence(); + return true; } // NOTE : SlotIndex는 임시 @@ -1140,7 +706,8 @@ bool CPythonNetworkStream::SendUseSkillPacket(DWORD dwSkillIndex, DWORD dwTarget { TPacketCGUseSkill UseSkillPacket; - UseSkillPacket.bHeader = HEADER_CG_USE_SKILL; + UseSkillPacket.header = CG::USE_SKILL; + UseSkillPacket.length = sizeof(UseSkillPacket); UseSkillPacket.dwVnum = dwSkillIndex; UseSkillPacket.dwTargetVID = dwTargetVID; @@ -1176,7 +743,7 @@ bool CPythonNetworkStream::SendUseSkillPacket(DWORD dwSkillIndex, DWORD dwTarget return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendChatPacket(const char * c_szChat, BYTE byType) @@ -1205,7 +772,7 @@ bool CPythonNetworkStream::SendChatPacket(const char * c_szChat, BYTE byType) int iTextLen = strlen(c_szChat) + 1; TPacketCGChat ChatPacket; - ChatPacket.header = HEADER_CG_CHAT; + ChatPacket.header = CG::CHAT; ChatPacket.length = sizeof(ChatPacket) + iTextLen; ChatPacket.type = byType; @@ -1215,7 +782,7 @@ bool CPythonNetworkStream::SendChatPacket(const char * c_szChat, BYTE byType) if (!Send(iTextLen, c_szChat)) return false; - return SendSequence(); + return true; } ////////////////////////////////////////////////////////////////////////// @@ -1403,7 +970,7 @@ bool CPythonNetworkStream::RecvChatPacket() if (!Recv(sizeof(kChat), &kChat)) return false; - UINT uChatSize=kChat.size - sizeof(kChat); + UINT uChatSize=kChat.length - sizeof(kChat); if (!Recv(uChatSize, buf)) return false; @@ -1526,12 +1093,12 @@ bool CPythonNetworkStream::RecvWhisperPacket() if (!Recv(sizeof(whisperPacket), &whisperPacket)) return false; - assert(whisperPacket.wSize - sizeof(whisperPacket) < 512); + assert(whisperPacket.length - sizeof(whisperPacket) < 512); - if (!Recv(whisperPacket.wSize - sizeof(whisperPacket), &buf)) + if (!Recv(whisperPacket.length - sizeof(whisperPacket), &buf)) return false; - buf[whisperPacket.wSize - sizeof(whisperPacket)] = '\0'; + buf[whisperPacket.length - sizeof(whisperPacket)] = '\0'; static char line[256]; if (CPythonChat::WHISPER_TYPE_CHAT == whisperPacket.bType || CPythonChat::WHISPER_TYPE_GM == whisperPacket.bType) @@ -1558,8 +1125,8 @@ bool CPythonNetworkStream::SendWhisperPacket(const char * name, const char * c_s int iTextLen = strlen(c_szChat) + 1; TPacketCGWhisper WhisperPacket; - WhisperPacket.bHeader = HEADER_CG_WHISPER; - WhisperPacket.wSize = sizeof(WhisperPacket) + iTextLen; + WhisperPacket.header = CG::WHISPER; + WhisperPacket.length = sizeof(WhisperPacket) + iTextLen; strncpy(WhisperPacket.szNameTo, name, sizeof(WhisperPacket.szNameTo) - 1); @@ -1569,25 +1136,7 @@ bool CPythonNetworkStream::SendWhisperPacket(const char * name, const char * c_s if (!Send(iTextLen, c_szChat)) return false; - return SendSequence(); -} - -bool CPythonNetworkStream::SendMobileMessagePacket(const char * name, const char * c_szChat) -{ - int iTextLen = strlen(c_szChat) + 1; - TPacketCGSMS SMSPacket; - SMSPacket.bHeader = HEADER_CG_SMS; - SMSPacket.wSize = sizeof(SMSPacket) + iTextLen; - - strncpy(SMSPacket.szNameTo, name, sizeof(SMSPacket.szNameTo) - 1); - - if (!Send(sizeof(SMSPacket), &SMSPacket)) - return false; - - if (!Send(iTextLen, c_szChat)) - return false; - - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvPointChange() @@ -1733,7 +1282,8 @@ bool CPythonNetworkStream::SendCharacterPositionPacket(BYTE iPosition) { TPacketCGPosition PositionPacket; - PositionPacket.header = HEADER_CG_CHARACTER_POSITION; + PositionPacket.header = CG::CHARACTER_POSITION; + PositionPacket.length = sizeof(PositionPacket); PositionPacket.position = iPosition; if (!Send(sizeof(TPacketCGPosition), &PositionPacket)) @@ -1742,13 +1292,14 @@ bool CPythonNetworkStream::SendCharacterPositionPacket(BYTE iPosition) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendOnClickPacket(DWORD vid) { TPacketCGOnClick OnClickPacket; - OnClickPacket.header = HEADER_CG_ON_CLICK; + OnClickPacket.header = CG::ON_CLICK; + OnClickPacket.length = sizeof(OnClickPacket); OnClickPacket.vid = vid; if (!Send(sizeof(OnClickPacket), &OnClickPacket)) @@ -1758,7 +1309,7 @@ bool CPythonNetworkStream::SendOnClickPacket(DWORD vid) } Tracef("SendOnClickPacket\n"); - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvCharacterPositionPacket() @@ -1799,114 +1350,137 @@ bool CPythonNetworkStream::RecvMotionPacket() bool CPythonNetworkStream::RecvShopPacket() { - std::vector vecBuffer; - vecBuffer.clear(); - - TPacketGCShop packet_shop; + TPacketGCShop packet_shop; if (!Recv(sizeof(packet_shop), &packet_shop)) return false; - int iSize = packet_shop.size - sizeof(packet_shop); + std::vector buf; + int iSize = packet_shop.length - sizeof(packet_shop); if (iSize > 0) { - vecBuffer.resize(iSize); - if (!Recv(iSize, &vecBuffer[0])) + buf.resize(iSize); + if (!Recv(iSize, &buf[0])) return false; } - switch (packet_shop.subheader) + static const std::unordered_map&)> handlers = { + { ShopSub::GC::START, &CPythonNetworkStream::RecvShopSub_Start }, + { ShopSub::GC::START_EX, &CPythonNetworkStream::RecvShopSub_StartEx }, + { ShopSub::GC::END, &CPythonNetworkStream::RecvShopSub_End }, + { ShopSub::GC::UPDATE_ITEM, &CPythonNetworkStream::RecvShopSub_UpdateItem }, + { ShopSub::GC::UPDATE_PRICE, &CPythonNetworkStream::RecvShopSub_UpdatePrice }, + { ShopSub::GC::NOT_ENOUGH_MONEY, &CPythonNetworkStream::RecvShopSub_NotEnoughMoney }, + { ShopSub::GC::NOT_ENOUGH_MONEY_EX,&CPythonNetworkStream::RecvShopSub_NotEnoughMoneyEx }, + { ShopSub::GC::SOLDOUT, &CPythonNetworkStream::RecvShopSub_Soldout }, + { ShopSub::GC::INVENTORY_FULL, &CPythonNetworkStream::RecvShopSub_InventoryFull }, + { ShopSub::GC::INVALID_POS, &CPythonNetworkStream::RecvShopSub_InvalidPos }, + }; + + auto it = handlers.find(packet_shop.subheader); + if (it == handlers.end()) { - case SHOP_SUBHEADER_GC_START: - { - CPythonShop::Instance().Clear(); + TraceError("RecvShopPacket: unknown subheader %d", packet_shop.subheader); + return true; + } + return (this->*(it->second))(buf); +} - DWORD dwVID = *(DWORD *)&vecBuffer[0]; +bool CPythonNetworkStream::RecvShopSub_Start(const std::vector& buf) +{ + CPythonShop::Instance().Clear(); - TPacketGCShopStart * pShopStartPacket = (TPacketGCShopStart *)&vecBuffer[4]; - for (BYTE iItemIndex = 0; iItemIndex < SHOP_HOST_ITEM_MAX_NUM; ++iItemIndex) - { - CPythonShop::Instance().SetItemData(iItemIndex, pShopStartPacket->items[iItemIndex]); - } + DWORD dwVID = *(DWORD *)&buf[0]; - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartShop", Py_BuildValue("(i)", dwVID)); - } - break; - - case SHOP_SUBHEADER_GC_START_EX: - { - CPythonShop::Instance().Clear(); - - TPacketGCShopStartEx * pShopStartPacket = (TPacketGCShopStartEx *)&vecBuffer[0]; - size_t read_point = sizeof(TPacketGCShopStartEx); - - DWORD dwVID = pShopStartPacket->owner_vid; - BYTE shop_tab_count = pShopStartPacket->shop_tab_count; - - CPythonShop::instance().SetTabCount(shop_tab_count); - - for (unsigned char i = 0; i < shop_tab_count; i++) - { - TPacketGCShopStartEx::TSubPacketShopTab* pPackTab = (TPacketGCShopStartEx::TSubPacketShopTab*)&vecBuffer[read_point]; - read_point += sizeof(TPacketGCShopStartEx::TSubPacketShopTab); - - CPythonShop::instance().SetTabCoinType(i, pPackTab->coin_type); - CPythonShop::instance().SetTabName(i, pPackTab->name); - - struct packet_shop_item* item = &pPackTab->items[0]; - - for (BYTE j = 0; j < SHOP_HOST_ITEM_MAX_NUM; j++) - { - TShopItemData* itemData = (item + j); - CPythonShop::Instance().SetItemData(i, j, *itemData); - } - } - - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartShop", Py_BuildValue("(i)", dwVID)); - } - break; - - - case SHOP_SUBHEADER_GC_END: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "EndShop", Py_BuildValue("()")); - break; - - case SHOP_SUBHEADER_GC_UPDATE_ITEM: - { - TPacketGCShopUpdateItem * pShopUpdateItemPacket = (TPacketGCShopUpdateItem *)&vecBuffer[0]; - CPythonShop::Instance().SetItemData(pShopUpdateItemPacket->pos, pShopUpdateItemPacket->item); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshShop", Py_BuildValue("()")); - } - break; - - case SHOP_SUBHEADER_GC_UPDATE_PRICE: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetShopSellingPrice", Py_BuildValue("(i)", *(int *)&vecBuffer[0])); - break; - - case SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "NOT_ENOUGH_MONEY")); - break; - - case SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_EX: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "NOT_ENOUGH_MONEY_EX")); - break; - - case SHOP_SUBHEADER_GC_SOLDOUT: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "SOLDOUT")); - break; - - case SHOP_SUBHEADER_GC_INVENTORY_FULL: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "INVENTORY_FULL")); - break; - - case SHOP_SUBHEADER_GC_INVALID_POS: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "INVALID_POS")); - break; - - default: - TraceError("CPythonNetworkStream::RecvShopPacket: Unknown subheader\n"); - break; + TPacketGCShopStart * pShopStartPacket = (TPacketGCShopStart *)&buf[4]; + for (BYTE iItemIndex = 0; iItemIndex < SHOP_HOST_ITEM_MAX_NUM; ++iItemIndex) + { + CPythonShop::Instance().SetItemData(iItemIndex, pShopStartPacket->items[iItemIndex]); } + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartShop", Py_BuildValue("(i)", dwVID)); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_StartEx(const std::vector& buf) +{ + CPythonShop::Instance().Clear(); + + TPacketGCShopStartEx * pShopStartPacket = (TPacketGCShopStartEx *)&buf[0]; + size_t read_point = sizeof(TPacketGCShopStartEx); + + DWORD dwVID = pShopStartPacket->owner_vid; + BYTE shop_tab_count = pShopStartPacket->shop_tab_count; + + CPythonShop::instance().SetTabCount(shop_tab_count); + + for (unsigned char i = 0; i < shop_tab_count; i++) + { + TPacketGCShopStartEx::TSubPacketShopTab* pPackTab = (TPacketGCShopStartEx::TSubPacketShopTab*)&buf[read_point]; + read_point += sizeof(TPacketGCShopStartEx::TSubPacketShopTab); + + CPythonShop::instance().SetTabCoinType(i, pPackTab->coin_type); + CPythonShop::instance().SetTabName(i, pPackTab->name); + + struct packet_shop_item* item = &pPackTab->items[0]; + + for (BYTE j = 0; j < SHOP_HOST_ITEM_MAX_NUM; j++) + { + TShopItemData* itemData = (item + j); + CPythonShop::Instance().SetItemData(i, j, *itemData); + } + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartShop", Py_BuildValue("(i)", dwVID)); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_End(const std::vector& buf) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "EndShop", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_UpdateItem(const std::vector& buf) +{ + TPacketGCShopUpdateItem * pShopUpdateItemPacket = (TPacketGCShopUpdateItem *)&buf[0]; + CPythonShop::Instance().SetItemData(pShopUpdateItemPacket->pos, pShopUpdateItemPacket->item); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshShop", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_UpdatePrice(const std::vector& buf) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetShopSellingPrice", Py_BuildValue("(i)", *(int *)&buf[0])); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_NotEnoughMoney(const std::vector& buf) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "NOT_ENOUGH_MONEY")); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_NotEnoughMoneyEx(const std::vector& buf) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "NOT_ENOUGH_MONEY_EX")); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_Soldout(const std::vector& buf) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "SOLDOUT")); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_InventoryFull(const std::vector& buf) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "INVENTORY_FULL")); + return true; +} + +bool CPythonNetworkStream::RecvShopSub_InvalidPos(const std::vector& buf) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "INVALID_POS")); return true; } @@ -1917,96 +1491,126 @@ bool CPythonNetworkStream::RecvExchangePacket() if (!Recv(sizeof(exchange_packet), &exchange_packet)) return false; - switch (exchange_packet.subheader) - { - case EXCHANGE_SUBHEADER_GC_START: - CPythonExchange::Instance().Clear(); - CPythonExchange::Instance().Start(); - CPythonExchange::Instance().SetSelfName(CPythonPlayer::Instance().GetName()); - - { - CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetInstancePtr(exchange_packet.arg1); - - if (pCharacterInstance) - CPythonExchange::Instance().SetTargetName(pCharacterInstance->GetNameString()); - } - - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartExchange", Py_BuildValue("()")); - break; - - case EXCHANGE_SUBHEADER_GC_ITEM_ADD: - if (exchange_packet.is_me) - { - int iSlotIndex = exchange_packet.arg2.cell; - CPythonExchange::Instance().SetItemToSelf(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3); - for (int i = 0; i < ITEM_SOCKET_SLOT_MAX_NUM; ++i) - CPythonExchange::Instance().SetItemMetinSocketToSelf(iSlotIndex, i, exchange_packet.alValues[i]); - for (int j = 0; j < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++j) - CPythonExchange::Instance().SetItemAttributeToSelf(iSlotIndex, j, exchange_packet.aAttr[j].bType, exchange_packet.aAttr[j].sValue); - } - else - { - int iSlotIndex = exchange_packet.arg2.cell; - CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3); - for (int i = 0; i < ITEM_SOCKET_SLOT_MAX_NUM; ++i) - CPythonExchange::Instance().SetItemMetinSocketToTarget(iSlotIndex, i, exchange_packet.alValues[i]); - for (int j = 0; j < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++j) - CPythonExchange::Instance().SetItemAttributeToTarget(iSlotIndex, j, exchange_packet.aAttr[j].bType, exchange_packet.aAttr[j].sValue); - } - - __RefreshExchangeWindow(); - __RefreshInventoryWindow(); - break; - - case EXCHANGE_SUBHEADER_GC_ITEM_DEL: - if (exchange_packet.is_me) - { - CPythonExchange::Instance().DelItemOfSelf((BYTE) exchange_packet.arg1); - } - else - { - CPythonExchange::Instance().DelItemOfTarget((BYTE) exchange_packet.arg1); - } - __RefreshExchangeWindow(); - __RefreshInventoryWindow(); - break; - - case EXCHANGE_SUBHEADER_GC_ELK_ADD: - if (exchange_packet.is_me) - CPythonExchange::Instance().SetElkToSelf(exchange_packet.arg1); - else - CPythonExchange::Instance().SetElkToTarget(exchange_packet.arg1); - - __RefreshExchangeWindow(); - break; - - case EXCHANGE_SUBHEADER_GC_ACCEPT: - if (exchange_packet.is_me) - { - CPythonExchange::Instance().SetAcceptToSelf((BYTE) exchange_packet.arg1); - } - else - { - CPythonExchange::Instance().SetAcceptToTarget((BYTE) exchange_packet.arg1); - } - __RefreshExchangeWindow(); - break; - - case EXCHANGE_SUBHEADER_GC_END: - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "EndExchange", Py_BuildValue("()")); - __RefreshInventoryWindow(); - CPythonExchange::Instance().End(); - break; - - case EXCHANGE_SUBHEADER_GC_ALREADY: - Tracef("trade_already"); - break; - - case EXCHANGE_SUBHEADER_GC_LESS_ELK: - Tracef("trade_less_elk"); - break; + static const std::unordered_map handlers = { + { ExchangeSub::GC::START, &CPythonNetworkStream::RecvExchangeSub_Start }, + { ExchangeSub::GC::ITEM_ADD, &CPythonNetworkStream::RecvExchangeSub_ItemAdd }, + { ExchangeSub::GC::ITEM_DEL, &CPythonNetworkStream::RecvExchangeSub_ItemDel }, + { ExchangeSub::GC::ELK_ADD, &CPythonNetworkStream::RecvExchangeSub_ElkAdd }, + { ExchangeSub::GC::ACCEPT, &CPythonNetworkStream::RecvExchangeSub_Accept }, + { ExchangeSub::GC::END, &CPythonNetworkStream::RecvExchangeSub_End }, + { ExchangeSub::GC::ALREADY, &CPythonNetworkStream::RecvExchangeSub_Already }, + { ExchangeSub::GC::LESS_ELK, &CPythonNetworkStream::RecvExchangeSub_LessElk }, }; + auto it = handlers.find(exchange_packet.subheader); + if (it == handlers.end()) + { + TraceError("RecvExchangePacket: unknown subheader %d", exchange_packet.subheader); + return true; + } + return (this->*(it->second))(exchange_packet); +} + +bool CPythonNetworkStream::RecvExchangeSub_Start(const TPacketGCExchange& pack) +{ + CPythonExchange::Instance().Clear(); + CPythonExchange::Instance().Start(); + CPythonExchange::Instance().SetSelfName(CPythonPlayer::Instance().GetName()); + + { + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetInstancePtr(pack.arg1); + + if (pCharacterInstance) + CPythonExchange::Instance().SetTargetName(pCharacterInstance->GetNameString()); + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartExchange", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::RecvExchangeSub_ItemAdd(const TPacketGCExchange& pack) +{ + if (pack.is_me) + { + int iSlotIndex = pack.arg2.cell; + CPythonExchange::Instance().SetItemToSelf(iSlotIndex, pack.arg1, (BYTE) pack.arg3); + for (int i = 0; i < ITEM_SOCKET_SLOT_MAX_NUM; ++i) + CPythonExchange::Instance().SetItemMetinSocketToSelf(iSlotIndex, i, pack.alValues[i]); + for (int j = 0; j < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++j) + CPythonExchange::Instance().SetItemAttributeToSelf(iSlotIndex, j, pack.aAttr[j].bType, pack.aAttr[j].sValue); + } + else + { + int iSlotIndex = pack.arg2.cell; + CPythonExchange::Instance().SetItemToTarget(iSlotIndex, pack.arg1, (BYTE) pack.arg3); + for (int i = 0; i < ITEM_SOCKET_SLOT_MAX_NUM; ++i) + CPythonExchange::Instance().SetItemMetinSocketToTarget(iSlotIndex, i, pack.alValues[i]); + for (int j = 0; j < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++j) + CPythonExchange::Instance().SetItemAttributeToTarget(iSlotIndex, j, pack.aAttr[j].bType, pack.aAttr[j].sValue); + } + + __RefreshExchangeWindow(); + __RefreshInventoryWindow(); + return true; +} + +bool CPythonNetworkStream::RecvExchangeSub_ItemDel(const TPacketGCExchange& pack) +{ + if (pack.is_me) + { + CPythonExchange::Instance().DelItemOfSelf((BYTE) pack.arg1); + } + else + { + CPythonExchange::Instance().DelItemOfTarget((BYTE) pack.arg1); + } + __RefreshExchangeWindow(); + __RefreshInventoryWindow(); + return true; +} + +bool CPythonNetworkStream::RecvExchangeSub_ElkAdd(const TPacketGCExchange& pack) +{ + if (pack.is_me) + CPythonExchange::Instance().SetElkToSelf(pack.arg1); + else + CPythonExchange::Instance().SetElkToTarget(pack.arg1); + + __RefreshExchangeWindow(); + return true; +} + +bool CPythonNetworkStream::RecvExchangeSub_Accept(const TPacketGCExchange& pack) +{ + if (pack.is_me) + { + CPythonExchange::Instance().SetAcceptToSelf((BYTE) pack.arg1); + } + else + { + CPythonExchange::Instance().SetAcceptToTarget((BYTE) pack.arg1); + } + __RefreshExchangeWindow(); + return true; +} + +bool CPythonNetworkStream::RecvExchangeSub_End(const TPacketGCExchange& pack) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "EndExchange", Py_BuildValue("()")); + __RefreshInventoryWindow(); + CPythonExchange::Instance().End(); + return true; +} + +bool CPythonNetworkStream::RecvExchangeSub_Already(const TPacketGCExchange& pack) +{ + Tracef("trade_already"); + return true; +} + +bool CPythonNetworkStream::RecvExchangeSub_LessElk(const TPacketGCExchange& pack) +{ + Tracef("trade_less_elk"); return true; } @@ -2020,7 +1624,7 @@ bool CPythonNetworkStream::RecvQuestInfoPacket() return false; } - if (!Peek(QuestInfo.size)) + if (!Peek(QuestInfo.length)) { Tracen("Recv Quest Info Packet Error #2"); return false; @@ -2191,8 +1795,9 @@ bool CPythonNetworkStream::SendExchangeStartPacket(DWORD vid) TPacketCGExchange packet; - packet.header = HEADER_CG_EXCHANGE; - packet.subheader = EXCHANGE_SUBHEADER_CG_START; + packet.header = CG::EXCHANGE; + packet.length = sizeof(packet); + packet.subheader = ExchangeSub::CG::START; packet.arg1 = vid; if (!Send(sizeof(packet), &packet)) @@ -2202,7 +1807,7 @@ bool CPythonNetworkStream::SendExchangeStartPacket(DWORD vid) } Tracef("send_trade_start_packet vid %d \n", vid); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendExchangeElkAddPacket(DWORD elk) @@ -2212,8 +1817,9 @@ bool CPythonNetworkStream::SendExchangeElkAddPacket(DWORD elk) TPacketCGExchange packet; - packet.header = HEADER_CG_EXCHANGE; - packet.subheader = EXCHANGE_SUBHEADER_CG_ELK_ADD; + packet.header = CG::EXCHANGE; + packet.length = sizeof(packet); + packet.subheader = ExchangeSub::CG::ELK_ADD; packet.arg1 = elk; if (!Send(sizeof(packet), &packet)) @@ -2222,7 +1828,7 @@ bool CPythonNetworkStream::SendExchangeElkAddPacket(DWORD elk) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendExchangeItemAddPacket(TItemPos ItemPos, BYTE byDisplayPos) @@ -2232,8 +1838,9 @@ bool CPythonNetworkStream::SendExchangeItemAddPacket(TItemPos ItemPos, BYTE byDi TPacketCGExchange packet; - packet.header = HEADER_CG_EXCHANGE; - packet.subheader = EXCHANGE_SUBHEADER_CG_ITEM_ADD; + packet.header = CG::EXCHANGE; + packet.length = sizeof(packet); + packet.subheader = ExchangeSub::CG::ITEM_ADD; packet.Pos = ItemPos; packet.arg2 = byDisplayPos; @@ -2243,7 +1850,7 @@ bool CPythonNetworkStream::SendExchangeItemAddPacket(TItemPos ItemPos, BYTE byDi return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendExchangeItemDelPacket(BYTE pos) @@ -2256,8 +1863,9 @@ bool CPythonNetworkStream::SendExchangeItemDelPacket(BYTE pos) TPacketCGExchange packet; - packet.header = HEADER_CG_EXCHANGE; - packet.subheader = EXCHANGE_SUBHEADER_CG_ITEM_DEL; + packet.header = CG::EXCHANGE; + packet.length = sizeof(packet); + packet.subheader = ExchangeSub::CG::ITEM_DEL; packet.arg1 = pos; if (!Send(sizeof(packet), &packet)) @@ -2266,7 +1874,7 @@ bool CPythonNetworkStream::SendExchangeItemDelPacket(BYTE pos) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendExchangeAcceptPacket() @@ -2276,8 +1884,9 @@ bool CPythonNetworkStream::SendExchangeAcceptPacket() TPacketCGExchange packet; - packet.header = HEADER_CG_EXCHANGE; - packet.subheader = EXCHANGE_SUBHEADER_CG_ACCEPT; + packet.header = CG::EXCHANGE; + packet.length = sizeof(packet); + packet.subheader = ExchangeSub::CG::ACCEPT; if (!Send(sizeof(packet), &packet)) { @@ -2285,7 +1894,7 @@ bool CPythonNetworkStream::SendExchangeAcceptPacket() return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendExchangeExitPacket() @@ -2295,8 +1904,9 @@ bool CPythonNetworkStream::SendExchangeExitPacket() TPacketCGExchange packet; - packet.header = HEADER_CG_EXCHANGE; - packet.subheader = EXCHANGE_SUBHEADER_CG_CANCEL; + packet.header = CG::EXCHANGE; + packet.length = sizeof(packet); + packet.subheader = ExchangeSub::CG::CANCEL; if (!Send(sizeof(packet), &packet)) { @@ -2304,7 +1914,7 @@ bool CPythonNetworkStream::SendExchangeExitPacket() return false; } - return SendSequence(); + return true; } // PointReset 개임시 @@ -2337,19 +1947,19 @@ bool CPythonNetworkStream::RecvScriptPacket() return false; } - if (ScriptPacket.size < sizeof(TPacketGCScript)) + if (ScriptPacket.length < sizeof(TPacketGCScript)) { TraceError("RecvScriptPacket_SizeError"); return false; } - ScriptPacket.size -= sizeof(TPacketGCScript); + ScriptPacket.length -= sizeof(TPacketGCScript); static std::string str; str = ""; - str.resize(ScriptPacket.size+1); + str.resize(ScriptPacket.length+1); - if (!Recv(ScriptPacket.size, &str[0])) + if (!Recv(ScriptPacket.length, &str[0])) return false; str[str.size()-1] = '\0'; @@ -2369,7 +1979,8 @@ bool CPythonNetworkStream::SendScriptAnswerPacket(int iAnswer) { TPacketCGScriptAnswer ScriptAnswer; - ScriptAnswer.header = HEADER_CG_SCRIPT_ANSWER; + ScriptAnswer.header = CG::SCRIPT_ANSWER; + ScriptAnswer.length = sizeof(ScriptAnswer); ScriptAnswer.answer = (BYTE) iAnswer; if (!Send(sizeof(TPacketCGScriptAnswer), &ScriptAnswer)) { @@ -2377,14 +1988,15 @@ bool CPythonNetworkStream::SendScriptAnswerPacket(int iAnswer) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendScriptButtonPacket(unsigned int iIndex) { TPacketCGScriptButton ScriptButton; - ScriptButton.header = HEADER_CG_SCRIPT_BUTTON; + ScriptButton.header = CG::SCRIPT_BUTTON; + ScriptButton.length = sizeof(ScriptButton); ScriptButton.idx = iIndex; if (!Send(sizeof(TPacketCGScriptButton), &ScriptButton)) { @@ -2392,14 +2004,15 @@ bool CPythonNetworkStream::SendScriptButtonPacket(unsigned int iIndex) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendAnswerMakeGuildPacket(const char * c_szName) { TPacketCGAnswerMakeGuild Packet; - Packet.header = HEADER_CG_ANSWER_MAKE_GUILD; + Packet.header = CG::ANSWER_MAKE_GUILD; + Packet.length = sizeof(Packet); strncpy(Packet.guild_name, c_szName, GUILD_NAME_MAX_LEN); Packet.guild_name[GUILD_NAME_MAX_LEN] = '\0'; @@ -2410,13 +2023,14 @@ bool CPythonNetworkStream::SendAnswerMakeGuildPacket(const char * c_szName) } // Tracef(" SendAnswerMakeGuildPacket : %s", c_szName); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendQuestInputStringPacket(const char * c_szString) { TPacketCGQuestInputString Packet; - Packet.bHeader = HEADER_CG_QUEST_INPUT_STRING; + Packet.header = CG::QUEST_INPUT_STRING; + Packet.length = sizeof(Packet); strncpy(Packet.szString, c_szString, QUEST_INPUT_STRING_MAX_NUM); if (!Send(sizeof(Packet), &Packet)) @@ -2425,13 +2039,14 @@ bool CPythonNetworkStream::SendQuestInputStringPacket(const char * c_szString) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendQuestConfirmPacket(BYTE byAnswer, DWORD dwPID) { TPacketCGQuestConfirm kPacket; - kPacket.header = HEADER_CG_QUEST_CONFIRM; + kPacket.header = CG::QUEST_CONFIRM; + kPacket.length = sizeof(kPacket); kPacket.answer = byAnswer; kPacket.requestPID = dwPID; @@ -2442,13 +2057,14 @@ bool CPythonNetworkStream::SendQuestConfirmPacket(BYTE byAnswer, DWORD dwPID) } Tracenf(" SendQuestConfirmPacket : %d, %d", byAnswer, dwPID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendQuestCancelPacket() { TPacketCGQuestCancel Packet; - Packet.header = HEADER_CG_QUEST_CANCEL; + Packet.header = CG::QUEST_CANCEL; + Packet.length = sizeof(Packet); if (!Send(sizeof(Packet), &Packet)) { @@ -2457,7 +2073,7 @@ bool CPythonNetworkStream::SendQuestCancelPacket() } Tracenf(" SendQuestCancelPacket"); - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvSkillCoolTimeEnd() @@ -2548,7 +2164,7 @@ bool CPythonNetworkStream::RecvDamageInfoPacket() Tracen("Recv Target Packet Error"); return false; } - + CInstanceBase * pInstTarget = CPythonCharacterManager::Instance().GetInstancePtr(DamageInfoPacket.dwVID); bool bSelf = (pInstTarget == CPythonCharacterManager::Instance().GetMainInstancePtr()); bool bTarget = (pInstTarget==m_pInstTarget); @@ -2556,8 +2172,6 @@ bool CPythonNetworkStream::RecvDamageInfoPacket() { if(DamageInfoPacket.damage >= 0) pInstTarget->AddDamageEffect(DamageInfoPacket.damage,DamageInfoPacket.flag,bSelf,bTarget); - else - TraceError("Damage is equal or below 0."); } return true; @@ -2585,7 +2199,7 @@ bool CPythonNetworkStream::RecvTargetPacket() PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetHPTargetBoard", Py_BuildValue("(ii)", TargetPacket.dwVID, TargetPacket.bHPPercent)); else PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "CloseTargetBoard", Py_BuildValue("()")); - + m_pInstTarget = pInstTarget; } } @@ -2668,7 +2282,8 @@ bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim) TPacketCGAttack kPacketAtk; - kPacketAtk.header = HEADER_CG_ATTACK; + kPacketAtk.header = CG::ATTACK; + kPacketAtk.length = sizeof(kPacketAtk); kPacketAtk.bType = uMotAttack; kPacketAtk.dwVictimVID = dwVIDVictim; @@ -2678,16 +2293,16 @@ bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendSpecial(int nLen, void * pvBuf) { - BYTE bHeader = *(BYTE *) pvBuf; + uint16_t wHeader = *(uint16_t *) pvBuf; - switch (bHeader) + switch (wHeader) { - case HEADER_CG_ATTACK: + case CG::ATTACK: { TPacketCGAttack * pkPacketAtk = (TPacketCGAttack *) pvBuf; pkPacketAtk->bCRCMagicCubeProcPiece = GetProcessCRCMagicCubePiece(); @@ -2779,7 +2394,8 @@ bool CPythonNetworkStream::RecvFlyTargetingPacket() bool CPythonNetworkStream::SendShootPacket(UINT uSkill) { TPacketCGShoot kPacketShoot; - kPacketShoot.bHeader=HEADER_CG_SHOOT; + kPacketShoot.header=CG::SHOOT; + kPacketShoot.length = sizeof(kPacketShoot); kPacketShoot.bType=uSkill; if (!Send(sizeof(kPacketShoot), &kPacketShoot)) @@ -2788,7 +2404,7 @@ bool CPythonNetworkStream::SendShootPacket(UINT uSkill) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendAddFlyTargetingPacket(DWORD dwTargetVID, const TPixelPosition & kPPosTarget) @@ -2797,7 +2413,8 @@ bool CPythonNetworkStream::SendAddFlyTargetingPacket(DWORD dwTargetVID, const TP //CPythonCharacterManager & rpcm = CPythonCharacterManager::Instance(); - packet.bHeader = HEADER_CG_ADD_FLY_TARGETING; + packet.header = CG::ADD_FLY_TARGETING; + packet.length = sizeof(packet); packet.dwTargetVID = dwTargetVID; packet.lX = kPPosTarget.x; packet.lY = kPPosTarget.y; @@ -2810,7 +2427,7 @@ bool CPythonNetworkStream::SendAddFlyTargetingPacket(DWORD dwTargetVID, const TP return false; } - return SendSequence(); + return true; } @@ -2820,7 +2437,8 @@ bool CPythonNetworkStream::SendFlyTargetingPacket(DWORD dwTargetVID, const TPixe //CPythonCharacterManager & rpcm = CPythonCharacterManager::Instance(); - packet.bHeader = HEADER_CG_FLY_TARGETING; + packet.header = CG::FLY_TARGETING; + packet.length = sizeof(packet); packet.dwTargetVID = dwTargetVID; packet.lX = kPPosTarget.x; packet.lY = kPPosTarget.y; @@ -2833,7 +2451,7 @@ bool CPythonNetworkStream::SendFlyTargetingPacket(DWORD dwTargetVID, const TPixe return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvCreateFlyPacket() @@ -2858,7 +2476,8 @@ bool CPythonNetworkStream::RecvCreateFlyPacket() bool CPythonNetworkStream::SendTargetPacket(DWORD dwVID) { TPacketCGTarget packet; - packet.header = HEADER_CG_TARGET; + packet.header = CG::TARGET; + packet.length = sizeof(packet); packet.dwVID = dwVID; if (!Send(sizeof(packet), &packet)) @@ -2867,7 +2486,7 @@ bool CPythonNetworkStream::SendTargetPacket(DWORD dwVID) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendSyncPositionElementPacket(DWORD dwVictimVID, DWORD dwVictimX, DWORD dwVictimY) @@ -2894,12 +2513,12 @@ bool CPythonNetworkStream::RecvMessenger() if (!Recv(sizeof(p), &p)) return false; - int iSize = p.size - sizeof(p); + int iSize = p.length - sizeof(p); char char_name[24+1]; switch (p.subheader) { - case MESSENGER_SUBHEADER_GC_LIST: + case MessengerSub::GC::LIST: { TPacketGCMessengerListOnline on; while(iSize) @@ -2917,16 +2536,13 @@ bool CPythonNetworkStream::RecvMessenger() else CPythonMessenger::Instance().OnFriendLogout(char_name); - if (on.connected & MESSENGER_CONNECTED_STATE_MOBILE) - CPythonMessenger::Instance().SetMobile(char_name, TRUE); - iSize -= sizeof(TPacketGCMessengerListOffline); iSize -= on.length; } break; } - case MESSENGER_SUBHEADER_GC_LOGIN: + case MessengerSub::GC::LOGIN: { TPacketGCMessengerLogin p; if (!Recv(sizeof(p),&p)) @@ -2939,7 +2555,7 @@ bool CPythonNetworkStream::RecvMessenger() break; } - case MESSENGER_SUBHEADER_GC_LOGOUT: + case MessengerSub::GC::LOGOUT: { TPacketGCMessengerLogout logout; if (!Recv(sizeof(logout),&logout)) @@ -2951,22 +2567,7 @@ bool CPythonNetworkStream::RecvMessenger() break; } - case MESSENGER_SUBHEADER_GC_MOBILE: - { - BYTE byState; // 모바일 번호가 없어졌는지 플래그 - BYTE byLength; - if (!Recv(sizeof(byState), &byState)) - return false; - if (!Recv(sizeof(byLength), &byLength)) - return false; - if (!Recv(byLength, char_name)) - return false; - char_name[byLength] = 0; - CPythonMessenger::Instance().SetMobile(char_name, byState); - break; - } - - case MESSENGER_SUBHEADER_GC_REMOVE_FRIEND: + case MessengerSub::GC::REMOVE_FRIEND: { BYTE bLength; @@ -2983,6 +2584,10 @@ bool CPythonNetworkStream::RecvMessenger() break; } + + default: + TraceError("RecvMessenger: unknown subheader %d", p.subheader); + break; } return true; } @@ -2993,7 +2598,8 @@ bool CPythonNetworkStream::RecvMessenger() bool CPythonNetworkStream::SendPartyInvitePacket(DWORD dwVID) { TPacketCGPartyInvite kPartyInvitePacket; - kPartyInvitePacket.header = HEADER_CG_PARTY_INVITE; + kPartyInvitePacket.header = CG::PARTY_INVITE; + kPartyInvitePacket.length = sizeof(kPartyInvitePacket); kPartyInvitePacket.vid = dwVID; if (!Send(sizeof(kPartyInvitePacket), &kPartyInvitePacket)) @@ -3003,13 +2609,14 @@ bool CPythonNetworkStream::SendPartyInvitePacket(DWORD dwVID) } Tracef(" << SendPartyInvitePacket : %d\n", dwVID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendPartyInviteAnswerPacket(DWORD dwLeaderVID, BYTE byAnswer) { TPacketCGPartyInviteAnswer kPartyInviteAnswerPacket; - kPartyInviteAnswerPacket.header = HEADER_CG_PARTY_INVITE_ANSWER; + kPartyInviteAnswerPacket.header = CG::PARTY_INVITE_ANSWER; + kPartyInviteAnswerPacket.length = sizeof(kPartyInviteAnswerPacket); kPartyInviteAnswerPacket.leader_pid = dwLeaderVID; kPartyInviteAnswerPacket.accept = byAnswer; @@ -3020,13 +2627,14 @@ bool CPythonNetworkStream::SendPartyInviteAnswerPacket(DWORD dwLeaderVID, BYTE b } Tracef(" << SendPartyInviteAnswerPacket : %d, %d\n", dwLeaderVID, byAnswer); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendPartyRemovePacket(DWORD dwPID) { TPacketCGPartyRemove kPartyInviteRemove; - kPartyInviteRemove.header = HEADER_CG_PARTY_REMOVE; + kPartyInviteRemove.header = CG::PARTY_REMOVE; + kPartyInviteRemove.length = sizeof(kPartyInviteRemove); kPartyInviteRemove.pid = dwPID; if (!Send(sizeof(kPartyInviteRemove), &kPartyInviteRemove)) @@ -3036,13 +2644,14 @@ bool CPythonNetworkStream::SendPartyRemovePacket(DWORD dwPID) } Tracef(" << SendPartyRemovePacket : %d\n", dwPID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendPartySetStatePacket(DWORD dwVID, BYTE byState, BYTE byFlag) { TPacketCGPartySetState kPartySetState; - kPartySetState.byHeader = HEADER_CG_PARTY_SET_STATE; + kPartySetState.header = CG::PARTY_SET_STATE; + kPartySetState.length = sizeof(kPartySetState); kPartySetState.dwVID = dwVID; kPartySetState.byState = byState; kPartySetState.byFlag = byFlag; @@ -3054,13 +2663,14 @@ bool CPythonNetworkStream::SendPartySetStatePacket(DWORD dwVID, BYTE byState, BY } Tracef(" << SendPartySetStatePacket : %d, %d, %d\n", dwVID, byState, byFlag); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendPartyUseSkillPacket(BYTE bySkillIndex, DWORD dwVID) { TPacketCGPartyUseSkill kPartyUseSkill; - kPartyUseSkill.byHeader = HEADER_CG_PARTY_USE_SKILL; + kPartyUseSkill.header = CG::PARTY_USE_SKILL; + kPartyUseSkill.length = sizeof(kPartyUseSkill); kPartyUseSkill.bySkillIndex = bySkillIndex; kPartyUseSkill.dwTargetVID = dwVID; @@ -3071,13 +2681,14 @@ bool CPythonNetworkStream::SendPartyUseSkillPacket(BYTE bySkillIndex, DWORD dwVI } Tracef(" << SendPartyUseSkillPacket : %d, %d\n", bySkillIndex, dwVID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendPartyParameterPacket(BYTE byDistributeMode) { TPacketCGPartyParameter kPartyParameter; - kPartyParameter.bHeader = HEADER_CG_PARTY_PARAMETER; + kPartyParameter.header = CG::PARTY_PARAMETER; + kPartyParameter.length = sizeof(kPartyParameter); kPartyParameter.bDistributeMode = byDistributeMode; if (!Send(sizeof(kPartyParameter), &kPartyParameter)) @@ -3087,7 +2698,7 @@ bool CPythonNetworkStream::SendPartyParameterPacket(BYTE byDistributeMode) } Tracef(" << SendPartyParameterPacket : %d\n", byDistributeMode); - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvPartyInvite() @@ -3224,36 +2835,39 @@ bool CPythonNetworkStream::RecvPartyParameter() bool CPythonNetworkStream::SendGuildAddMemberPacket(DWORD dwVID) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_ADD_MEMBER; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwVID); + GuildPacket.bySubHeader = GuildSub::CG::ADD_MEMBER; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; if (!Send(sizeof(dwVID), &dwVID)) return false; Tracef(" SendGuildAddMemberPacket\n", dwVID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildRemoveMemberPacket(DWORD dwPID) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_REMOVE_MEMBER; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwPID); + GuildPacket.bySubHeader = GuildSub::CG::REMOVE_MEMBER; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; if (!Send(sizeof(dwPID), &dwPID)) return false; Tracef(" SendGuildRemoveMemberPacket %d\n", dwPID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildChangeGradeNamePacket(BYTE byGradeNumber, const char * c_szName) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_GRADE_NAME; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(BYTE) + (GUILD_GRADE_NAME_MAX_LEN + 1); + GuildPacket.bySubHeader = GuildSub::CG::CHANGE_GRADE_NAME; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; if (!Send(sizeof(byGradeNumber), &byGradeNumber)) @@ -3267,14 +2881,15 @@ bool CPythonNetworkStream::SendGuildChangeGradeNamePacket(BYTE byGradeNumber, co return false; Tracef(" SendGuildChangeGradeNamePacket %d, %s\n", byGradeNumber, c_szName); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildChangeGradeAuthorityPacket(BYTE byGradeNumber, BYTE byAuthority) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_GRADE_AUTHORITY; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(BYTE) + sizeof(BYTE); + GuildPacket.bySubHeader = GuildSub::CG::CHANGE_GRADE_AUTHORITY; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; if (!Send(sizeof(byGradeNumber), &byGradeNumber)) @@ -3283,46 +2898,49 @@ bool CPythonNetworkStream::SendGuildChangeGradeAuthorityPacket(BYTE byGradeNumbe return false; Tracef(" SendGuildChangeGradeAuthorityPacket %d, %d\n", byGradeNumber, byAuthority); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildOfferPacket(DWORD dwExperience) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_OFFER; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwExperience); + GuildPacket.bySubHeader = GuildSub::CG::OFFER; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; if (!Send(sizeof(dwExperience), &dwExperience)) return false; Tracef(" SendGuildOfferPacket %d\n", dwExperience); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildPostCommentPacket(const char * c_szMessage) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_POST_COMMENT; + BYTE bySize = BYTE(strlen(c_szMessage)) + 1; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(BYTE) + bySize; + GuildPacket.bySubHeader = GuildSub::CG::POST_COMMENT; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; - BYTE bySize = BYTE(strlen(c_szMessage)) + 1; if (!Send(sizeof(bySize), &bySize)) return false; if (!Send(bySize, c_szMessage)) return false; Tracef(" SendGuildPostCommentPacket %d, %s\n", bySize, c_szMessage); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildDeleteCommentPacket(DWORD dwIndex) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_DELETE_COMMENT; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwIndex); + GuildPacket.bySubHeader = GuildSub::CG::DELETE_COMMENT; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; @@ -3330,7 +2948,7 @@ bool CPythonNetworkStream::SendGuildDeleteCommentPacket(DWORD dwIndex) return false; Tracef(" SendGuildDeleteCommentPacket %d\n", dwIndex); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildRefreshCommentsPacket(DWORD dwHighestIndex) @@ -3342,20 +2960,22 @@ bool CPythonNetworkStream::SendGuildRefreshCommentsPacket(DWORD dwHighestIndex) s_LastTime = timeGetTime(); TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_REFRESH_COMMENT; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket); + GuildPacket.bySubHeader = GuildSub::CG::REFRESH_COMMENT; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; Tracef(" SendGuildRefreshCommentPacket %d\n", dwHighestIndex); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildChangeMemberGradePacket(DWORD dwPID, BYTE byGrade) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_MEMBER_GRADE; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwPID) + sizeof(byGrade); + GuildPacket.bySubHeader = GuildSub::CG::CHANGE_MEMBER_GRADE; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; @@ -3365,14 +2985,15 @@ bool CPythonNetworkStream::SendGuildChangeMemberGradePacket(DWORD dwPID, BYTE by return false; Tracef(" SendGuildChangeMemberGradePacket %d, %d\n", dwPID, byGrade); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildUseSkillPacket(DWORD dwSkillID, DWORD dwTargetVID) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_USE_SKILL; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket); + GuildPacket.bySubHeader = GuildSub::CG::USE_SKILL; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; @@ -3382,14 +3003,15 @@ bool CPythonNetworkStream::SendGuildUseSkillPacket(DWORD dwSkillID, DWORD dwTarg return false; Tracef(" SendGuildUseSkillPacket %d, %d\n", dwSkillID, dwTargetVID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildChangeMemberGeneralPacket(DWORD dwPID, BYTE byFlag) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_MEMBER_GENERAL; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket); + GuildPacket.bySubHeader = GuildSub::CG::CHANGE_MEMBER_GENERAL; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; @@ -3399,14 +3021,15 @@ bool CPythonNetworkStream::SendGuildChangeMemberGeneralPacket(DWORD dwPID, BYTE return false; Tracef(" SendGuildChangeMemberGeneralFlagPacket %d, %d\n", dwPID, byFlag); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildInviteAnswerPacket(DWORD dwGuildID, BYTE byAnswer) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_GUILD_INVITE_ANSWER; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket); + GuildPacket.bySubHeader = GuildSub::CG::GUILD_INVITE_ANSWER; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; @@ -3416,14 +3039,15 @@ bool CPythonNetworkStream::SendGuildInviteAnswerPacket(DWORD dwGuildID, BYTE byA return false; Tracef(" SendGuildInviteAnswerPacket %d, %d\n", dwGuildID, byAnswer); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildChargeGSPPacket(DWORD dwMoney) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHARGE_GSP; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwMoney); + GuildPacket.bySubHeader = GuildSub::CG::CHARGE_GSP; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; @@ -3431,494 +3055,541 @@ bool CPythonNetworkStream::SendGuildChargeGSPPacket(DWORD dwMoney) return false; Tracef(" SendGuildChargeGSPPacket %d\n", dwMoney); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildDepositMoneyPacket(DWORD dwMoney) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_DEPOSIT_MONEY; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwMoney); + GuildPacket.bySubHeader = GuildSub::CG::DEPOSIT_MONEY; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; if (!Send(sizeof(dwMoney), &dwMoney)) return false; Tracef(" SendGuildDepositMoneyPacket %d\n", dwMoney); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGuildWithdrawMoneyPacket(DWORD dwMoney) { TPacketCGGuild GuildPacket; - GuildPacket.byHeader = HEADER_CG_GUILD; - GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_WITHDRAW_MONEY; + GuildPacket.header = CG::GUILD; + GuildPacket.length = sizeof(GuildPacket) + sizeof(dwMoney); + GuildPacket.bySubHeader = GuildSub::CG::WITHDRAW_MONEY; if (!Send(sizeof(GuildPacket), &GuildPacket)) return false; if (!Send(sizeof(dwMoney), &dwMoney)) return false; Tracef(" SendGuildWithdrawMoneyPacket %d\n", dwMoney); - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvGuild() { - TPacketGCGuild GuildPacket; + TPacketGCGuild GuildPacket; if (!Recv(sizeof(GuildPacket), &GuildPacket)) return false; - switch(GuildPacket.subheader) + static const std::unordered_map handlers = { + { GuildSub::GC::LOGIN, &CPythonNetworkStream::RecvGuildSub_Login }, + { GuildSub::GC::LOGOUT, &CPythonNetworkStream::RecvGuildSub_Logout }, + { GuildSub::GC::REMOVE, &CPythonNetworkStream::RecvGuildSub_Remove }, + { GuildSub::GC::LIST, &CPythonNetworkStream::RecvGuildSub_List }, + { GuildSub::GC::GRADE, &CPythonNetworkStream::RecvGuildSub_Grade }, + { GuildSub::GC::GRADE_NAME, &CPythonNetworkStream::RecvGuildSub_GradeName }, + { GuildSub::GC::GRADE_AUTH, &CPythonNetworkStream::RecvGuildSub_GradeAuth }, + { GuildSub::GC::INFO, &CPythonNetworkStream::RecvGuildSub_Info }, + { GuildSub::GC::COMMENTS, &CPythonNetworkStream::RecvGuildSub_Comments }, + { GuildSub::GC::CHANGE_EXP, &CPythonNetworkStream::RecvGuildSub_ChangeExp }, + { GuildSub::GC::CHANGE_MEMBER_GRADE, &CPythonNetworkStream::RecvGuildSub_ChangeMemberGrade }, + { GuildSub::GC::SKILL_INFO, &CPythonNetworkStream::RecvGuildSub_SkillInfo }, + { GuildSub::GC::CHANGE_MEMBER_GENERAL, &CPythonNetworkStream::RecvGuildSub_ChangeMemberGeneral }, + { GuildSub::GC::GUILD_INVITE, &CPythonNetworkStream::RecvGuildSub_Invite }, + { GuildSub::GC::WAR, &CPythonNetworkStream::RecvGuildSub_War }, + { GuildSub::GC::GUILD_NAME, &CPythonNetworkStream::RecvGuildSub_Name }, + { GuildSub::GC::GUILD_WAR_LIST, &CPythonNetworkStream::RecvGuildSub_WarList }, + { GuildSub::GC::GUILD_WAR_END_LIST, &CPythonNetworkStream::RecvGuildSub_WarEndList }, + { GuildSub::GC::WAR_POINT, &CPythonNetworkStream::RecvGuildSub_WarPoint }, + { GuildSub::GC::MONEY_CHANGE, &CPythonNetworkStream::RecvGuildSub_MoneyChange }, + }; + + auto it = handlers.find(GuildPacket.subheader); + if (it == handlers.end()) { - case GUILD_SUBHEADER_GC_LOGIN: + TraceError("RecvGuild: unknown subheader %d", GuildPacket.subheader); + return true; + } + return (this->*(it->second))(GuildPacket); +} + +bool CPythonNetworkStream::RecvGuildSub_Login(const TPacketGCGuild& pack) +{ + uint32_t dwPID; + if (!Recv(sizeof(uint32_t), &dwPID)) + return false; + + // Messenger + CPythonGuild::TGuildMemberData * pGuildMemberData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) + if (0 != pGuildMemberData->strName.compare(CPythonPlayer::Instance().GetName())) + CPythonMessenger::Instance().LoginGuildMember(pGuildMemberData->strName.c_str()); + + //Tracef(" %d\n", dwPID); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_Logout(const TPacketGCGuild& pack) +{ + uint32_t dwPID; + if (!Recv(sizeof(uint32_t), &dwPID)) + return false; + + // Messenger + CPythonGuild::TGuildMemberData * pGuildMemberData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) + if (0 != pGuildMemberData->strName.compare(CPythonPlayer::Instance().GetName())) + CPythonMessenger::Instance().LogoutGuildMember(pGuildMemberData->strName.c_str()); + + //Tracef(" %d\n", dwPID); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_Remove(const TPacketGCGuild& pack) +{ + uint32_t dwPID; + if (!Recv(sizeof(dwPID), &dwPID)) + return false; + + // Main Player 일 경우 DeleteGuild + if (CPythonGuild::Instance().IsMainPlayer(dwPID)) + { + CPythonGuild::Instance().Destroy(); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "DeleteGuild", Py_BuildValue("()")); + CPythonMessenger::Instance().RemoveAllGuildMember(); + __SetGuildID(0); + __RefreshMessengerWindow(); + __RefreshTargetBoard(); + __RefreshCharacterWindow(); + } + else + { + // Get Member Name + std::string strMemberName = ""; + CPythonGuild::TGuildMemberData * pData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pData)) { - uint32_t dwPID; - if (!Recv(sizeof(uint32_t), &dwPID)) - return false; - - // Messenger - CPythonGuild::TGuildMemberData * pGuildMemberData; - if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) - if (0 != pGuildMemberData->strName.compare(CPythonPlayer::Instance().GetName())) - CPythonMessenger::Instance().LoginGuildMember(pGuildMemberData->strName.c_str()); - - //Tracef(" %d\n", dwPID); - break; + strMemberName = pData->strName; + CPythonMessenger::Instance().RemoveGuildMember(pData->strName.c_str()); } - case GUILD_SUBHEADER_GC_LOGOUT: - { - uint32_t dwPID; - if (!Recv(sizeof(uint32_t), &dwPID)) - return false; - // Messenger - CPythonGuild::TGuildMemberData * pGuildMemberData; - if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) - if (0 != pGuildMemberData->strName.compare(CPythonPlayer::Instance().GetName())) - CPythonMessenger::Instance().LogoutGuildMember(pGuildMemberData->strName.c_str()); + CPythonGuild::Instance().RemoveMember(dwPID); - //Tracef(" %d\n", dwPID); - break; - } - case GUILD_SUBHEADER_GC_REMOVE: - { - uint32_t dwPID; - if (!Recv(sizeof(dwPID), &dwPID)) - return false; - - // Main Player 일 경우 DeleteGuild - if (CPythonGuild::Instance().IsMainPlayer(dwPID)) - { - CPythonGuild::Instance().Destroy(); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "DeleteGuild", Py_BuildValue("()")); - CPythonMessenger::Instance().RemoveAllGuildMember(); - __SetGuildID(0); - __RefreshMessengerWindow(); - __RefreshTargetBoard(); - __RefreshCharacterWindow(); - } - else - { - // Get Member Name - std::string strMemberName = ""; - CPythonGuild::TGuildMemberData * pData; - if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pData)) - { - strMemberName = pData->strName; - CPythonMessenger::Instance().RemoveGuildMember(pData->strName.c_str()); - } - - CPythonGuild::Instance().RemoveMember(dwPID); - - // Refresh - __RefreshTargetBoardByName(strMemberName.c_str()); - __RefreshGuildWindowMemberPage(); - } - - Tracef(" %d\n", dwPID); - break; - } - case GUILD_SUBHEADER_GC_LIST: - { - int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); - - for (; iPacketSize > 0;) - { - TPacketGCGuildSubMember memberPacket; - if (!Recv(sizeof(memberPacket), &memberPacket)) - return false; - - char szName[CHARACTER_NAME_MAX_LEN+1] = ""; - if (memberPacket.byNameFlag) - { - if (!Recv(sizeof(szName), &szName)) - return false; - - iPacketSize -= CHARACTER_NAME_MAX_LEN+1; - } - else - { - CPythonGuild::TGuildMemberData * pMemberData; - if (CPythonGuild::Instance().GetMemberDataPtrByPID(memberPacket.pid, &pMemberData)) - { - strncpy(szName, pMemberData->strName.c_str(), CHARACTER_NAME_MAX_LEN); - } - } - - //Tracef(" %d : %s, %d (%d, %d, %d)\n", memberPacket.pid, szName, memberPacket.byGrade, memberPacket.byJob, memberPacket.byLevel, memberPacket.dwOffer); - - CPythonGuild::SGuildMemberData GuildMemberData; - GuildMemberData.dwPID = memberPacket.pid; - GuildMemberData.byGrade = memberPacket.byGrade; - GuildMemberData.strName = szName; - GuildMemberData.byJob = memberPacket.byJob; - GuildMemberData.byLevel = memberPacket.byLevel; - GuildMemberData.dwOffer = memberPacket.dwOffer; - GuildMemberData.byGeneralFlag = memberPacket.byIsGeneral; - CPythonGuild::Instance().RegisterMember(GuildMemberData); - - // Messenger - if (strcmp(szName, CPythonPlayer::Instance().GetName())) - CPythonMessenger::Instance().AppendGuildMember(szName); - - __RefreshTargetBoardByName(szName); - - iPacketSize -= sizeof(memberPacket); - } - - __RefreshGuildWindowInfoPage(); - __RefreshGuildWindowMemberPage(); - __RefreshMessengerWindow(); - __RefreshCharacterWindow(); - break; - } - case GUILD_SUBHEADER_GC_GRADE: - { - BYTE byCount; - if (!Recv(sizeof(byCount), &byCount)) - return false; - - for (BYTE i = 0; i < byCount; ++ i) - { - BYTE byIndex; - if (!Recv(sizeof(byCount), &byIndex)) - return false; - TPacketGCGuildSubGrade GradePacket; - if (!Recv(sizeof(GradePacket), &GradePacket)) - return false; - - auto data = CPythonGuild::SGuildGradeData(GradePacket.auth_flag, GradePacket.grade_name); - CPythonGuild::Instance().SetGradeData(byIndex, data); - //Tracef(" [%d/%d] : %s, %d\n", byIndex, byCount, GradePacket.grade_name, GradePacket.auth_flag); - } - __RefreshGuildWindowGradePage(); - __RefreshGuildWindowMemberPageGradeComboBox(); - break; - } - case GUILD_SUBHEADER_GC_GRADE_NAME: - { - BYTE byGradeNumber; - if (!Recv(sizeof(byGradeNumber), &byGradeNumber)) - return false; - - char szGradeName[GUILD_GRADE_NAME_MAX_LEN+1] = ""; - if (!Recv(sizeof(szGradeName), &szGradeName)) - return false; - - CPythonGuild::Instance().SetGradeName(byGradeNumber, szGradeName); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildGrade", Py_BuildValue("()")); - - Tracef(" %d, %s\n", byGradeNumber, szGradeName); - __RefreshGuildWindowGradePage(); - __RefreshGuildWindowMemberPageGradeComboBox(); - break; - } - case GUILD_SUBHEADER_GC_GRADE_AUTH: - { - BYTE byGradeNumber; - if (!Recv(sizeof(byGradeNumber), &byGradeNumber)) - return false; - BYTE byAuthorityFlag; - if (!Recv(sizeof(byAuthorityFlag), &byAuthorityFlag)) - return false; - - CPythonGuild::Instance().SetGradeAuthority(byGradeNumber, byAuthorityFlag); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildGrade", Py_BuildValue("()")); - - Tracef(" %d, %d\n", byGradeNumber, byAuthorityFlag); - __RefreshGuildWindowGradePage(); - break; - } - case GUILD_SUBHEADER_GC_INFO: - { - TPacketGCGuildInfo GuildInfo; - if (!Recv(sizeof(GuildInfo), &GuildInfo)) - return false; - - CPythonGuild::Instance().EnableGuild(); - CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); - strncpy(rGuildInfo.szGuildName, GuildInfo.name, GUILD_NAME_MAX_LEN); - rGuildInfo.szGuildName[GUILD_NAME_MAX_LEN] = '\0'; - - rGuildInfo.dwGuildID = GuildInfo.guild_id; - rGuildInfo.dwMasterPID = GuildInfo.master_pid; - rGuildInfo.dwGuildLevel = GuildInfo.level; - rGuildInfo.dwCurrentExperience = GuildInfo.exp; - rGuildInfo.dwCurrentMemberCount = GuildInfo.member_count; - rGuildInfo.dwMaxMemberCount = GuildInfo.max_member_count; - rGuildInfo.dwGuildMoney = GuildInfo.gold; - rGuildInfo.bHasLand = GuildInfo.hasLand; - - //Tracef(" %s, %d, %d : %d\n", GuildInfo.name, GuildInfo.master_pid, GuildInfo.level, rGuildInfo.bHasLand); - __RefreshGuildWindowInfoPage(); - break; - } - case GUILD_SUBHEADER_GC_COMMENTS: - { - BYTE byCount; - if (!Recv(sizeof(byCount), &byCount)) - return false; - - CPythonGuild::Instance().ClearComment(); - //Tracef(" >>> Comments Count : %d\n", byCount); - - for (BYTE i = 0; i < byCount; ++i) - { - DWORD dwCommentID; - if (!Recv(sizeof(dwCommentID), &dwCommentID)) - return false; - - char szName[CHARACTER_NAME_MAX_LEN+1] = ""; - if (!Recv(sizeof(szName), &szName)) - return false; - - char szComment[GULID_COMMENT_MAX_LEN+1] = ""; - if (!Recv(sizeof(szComment), &szComment)) - return false; - - //Tracef(" [Comment-%d] : %s, %s\n", dwCommentID, szName, szComment); - CPythonGuild::Instance().RegisterComment(dwCommentID, szName, szComment); - } - - __RefreshGuildWindowBoardPage(); - break; - } - case GUILD_SUBHEADER_GC_CHANGE_EXP: - { - BYTE byLevel; - if (!Recv(sizeof(byLevel), &byLevel)) - return false; - uint32_t dwEXP; - if (!Recv(sizeof(dwEXP), &dwEXP)) - return false; - CPythonGuild::Instance().SetGuildEXP(byLevel, dwEXP); - Tracef(" %d, %d\n", byLevel, dwEXP); - __RefreshGuildWindowInfoPage(); - break; - } - case GUILD_SUBHEADER_GC_CHANGE_MEMBER_GRADE: - { - uint32_t dwPID; - if (!Recv(sizeof(dwPID), &dwPID)) - return false; - BYTE byGrade; - if (!Recv(sizeof(byGrade), &byGrade)) - return false; - CPythonGuild::Instance().ChangeGuildMemberGrade(dwPID, byGrade); - Tracef(" %d, %d\n", dwPID, byGrade); - __RefreshGuildWindowMemberPage(); - break; - } - case GUILD_SUBHEADER_GC_SKILL_INFO: - { - CPythonGuild::TGuildSkillData & rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); - if (!Recv(sizeof(rSkillData.bySkillPoint), &rSkillData.bySkillPoint)) - return false; - if (!Recv(sizeof(rSkillData.bySkillLevel), rSkillData.bySkillLevel)) - return false; - if (!Recv(sizeof(rSkillData.wGuildPoint), &rSkillData.wGuildPoint)) - return false; - if (!Recv(sizeof(rSkillData.wMaxGuildPoint), &rSkillData.wMaxGuildPoint)) - return false; - - Tracef(" %d / %d, %d\n", rSkillData.bySkillPoint, rSkillData.wGuildPoint, rSkillData.wMaxGuildPoint); - __RefreshGuildWindowSkillPage(); - break; - } - case GUILD_SUBHEADER_GC_CHANGE_MEMBER_GENERAL: - { - uint32_t dwPID; - if (!Recv(sizeof(dwPID), &dwPID)) - return false; - BYTE byFlag; - if (!Recv(sizeof(byFlag), &byFlag)) - return false; - - CPythonGuild::Instance().ChangeGuildMemberGeneralFlag(dwPID, byFlag); - Tracef(" %d, %d\n", dwPID, byFlag); - __RefreshGuildWindowMemberPage(); - break; - } - case GUILD_SUBHEADER_GC_GUILD_INVITE: - { - uint32_t dwGuildID; - if (!Recv(sizeof(dwGuildID), &dwGuildID)) - return false; - char szGuildName[GUILD_NAME_MAX_LEN+1]; - if (!Recv(GUILD_NAME_MAX_LEN, &szGuildName)) - return false; - - szGuildName[GUILD_NAME_MAX_LEN] = 0; - - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RecvGuildInviteQuestion", Py_BuildValue("(is)", dwGuildID, szGuildName)); - Tracef(" %d, %s\n", dwGuildID, szGuildName); - break; - } - case GUILD_SUBHEADER_GC_WAR: - { - TPacketGCGuildWar kGuildWar; - if (!Recv(sizeof(kGuildWar), &kGuildWar)) - return false; - - switch (kGuildWar.bWarState) - { - case GUILD_WAR_SEND_DECLARE: - Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_SEND_DECLARE\n"); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], - "BINARY_GuildWar_OnSendDeclare", - Py_BuildValue("(i)", kGuildWar.dwGuildOpp) - ); - break; - case GUILD_WAR_RECV_DECLARE: - Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_RECV_DECLARE\n"); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], - "BINARY_GuildWar_OnRecvDeclare", - Py_BuildValue("(ii)", kGuildWar.dwGuildOpp, kGuildWar.bType) - ); - break; - case GUILD_WAR_ON_WAR: - Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_ON_WAR : %d, %d\n", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], - "BINARY_GuildWar_OnStart", - Py_BuildValue("(ii)", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp) - ); - CPythonGuild::Instance().StartGuildWar(kGuildWar.dwGuildOpp); - break; - case GUILD_WAR_END: - Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_END\n"); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], - "BINARY_GuildWar_OnEnd", - Py_BuildValue("(ii)", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp) - ); - CPythonGuild::Instance().EndGuildWar(kGuildWar.dwGuildOpp); - break; - } - break; - } - case GUILD_SUBHEADER_GC_GUILD_NAME: - { - uint32_t dwID; - char szGuildName[GUILD_NAME_MAX_LEN+1]; - - int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); - - int nItemSize = sizeof(dwID) + GUILD_NAME_MAX_LEN; - - assert(iPacketSize%nItemSize==0 && "GUILD_SUBHEADER_GC_GUILD_NAME"); - - for (; iPacketSize > 0;) - { - if (!Recv(sizeof(dwID), &dwID)) - return false; - - if (!Recv(GUILD_NAME_MAX_LEN, &szGuildName)) - return false; - - szGuildName[GUILD_NAME_MAX_LEN] = 0; - - //Tracef(" >> GulidName [%d : %s]\n", dwID, szGuildName); - CPythonGuild::Instance().RegisterGuildName(dwID, szGuildName); - iPacketSize -= nItemSize; - } - break; - } - case GUILD_SUBHEADER_GC_GUILD_WAR_LIST: - { - uint32_t dwSrcGuildID; - uint32_t dwDstGuildID; - - int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); - int nItemSize = sizeof(dwSrcGuildID) + sizeof(dwDstGuildID); - - assert(iPacketSize%nItemSize==0 && "GUILD_SUBHEADER_GC_GUILD_WAR_LIST"); - - for (; iPacketSize > 0;) - { - if (!Recv(sizeof(dwSrcGuildID), &dwSrcGuildID)) - return false; - - if (!Recv(sizeof(dwDstGuildID), &dwDstGuildID)) - return false; - - Tracef(" >> GulidWarList [%d vs %d]\n", dwSrcGuildID, dwDstGuildID); - CInstanceBase::InsertGVGKey(dwSrcGuildID, dwDstGuildID); - CPythonCharacterManager::Instance().ChangeGVG(dwSrcGuildID, dwDstGuildID); - iPacketSize -= nItemSize; - } - break; - } - case GUILD_SUBHEADER_GC_GUILD_WAR_END_LIST: - { - uint32_t dwSrcGuildID; - uint32_t dwDstGuildID; - - int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); - int nItemSize = sizeof(dwSrcGuildID) + sizeof(dwDstGuildID); - - assert(iPacketSize%nItemSize==0 && "GUILD_SUBHEADER_GC_GUILD_WAR_END_LIST"); - - for (; iPacketSize > 0;) - { - - if (!Recv(sizeof(dwSrcGuildID), &dwSrcGuildID)) - return false; - - if (!Recv(sizeof(dwDstGuildID), &dwDstGuildID)) - return false; - - Tracef(" >> GulidWarEndList [%d vs %d]\n", dwSrcGuildID, dwDstGuildID); - CInstanceBase::RemoveGVGKey(dwSrcGuildID, dwDstGuildID); - CPythonCharacterManager::Instance().ChangeGVG(dwSrcGuildID, dwDstGuildID); - iPacketSize -= nItemSize; - } - break; - } - case GUILD_SUBHEADER_GC_WAR_POINT: - { - TPacketGuildWarPoint GuildWarPoint; - if (!Recv(sizeof(GuildWarPoint), &GuildWarPoint)) - return false; - - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], - "BINARY_GuildWar_OnRecvPoint", - Py_BuildValue("(iii)", GuildWarPoint.dwGainGuildID, GuildWarPoint.dwOpponentGuildID, GuildWarPoint.lPoint) - ); - break; - } - case GUILD_SUBHEADER_GC_MONEY_CHANGE: - { - uint32_t dwMoney; - if (!Recv(sizeof(dwMoney), &dwMoney)) - return false; - - CPythonGuild::Instance().SetGuildMoney(dwMoney); - - __RefreshGuildWindowInfoPage(); - Tracef(" >> Guild Money Change : %d\n", dwMoney); - break; - } + // Refresh + __RefreshTargetBoardByName(strMemberName.c_str()); + __RefreshGuildWindowMemberPage(); } + Tracef(" %d\n", dwPID); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_List(const TPacketGCGuild& pack) +{ + int iPacketSize = int(pack.length) - sizeof(pack); + + for (; iPacketSize > 0;) + { + TPacketGCGuildSubMember memberPacket; + if (!Recv(sizeof(memberPacket), &memberPacket)) + return false; + + char szName[CHARACTER_NAME_MAX_LEN+1] = ""; + if (memberPacket.byNameFlag) + { + if (!Recv(sizeof(szName), &szName)) + return false; + + iPacketSize -= CHARACTER_NAME_MAX_LEN+1; + } + else + { + CPythonGuild::TGuildMemberData * pMemberData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(memberPacket.pid, &pMemberData)) + { + strncpy(szName, pMemberData->strName.c_str(), CHARACTER_NAME_MAX_LEN); + } + } + + //Tracef(" %d : %s, %d (%d, %d, %d)\n", memberPacket.pid, szName, memberPacket.byGrade, memberPacket.byJob, memberPacket.byLevel, memberPacket.dwOffer); + + CPythonGuild::SGuildMemberData GuildMemberData; + GuildMemberData.dwPID = memberPacket.pid; + GuildMemberData.byGrade = memberPacket.byGrade; + GuildMemberData.strName = szName; + GuildMemberData.byJob = memberPacket.byJob; + GuildMemberData.byLevel = memberPacket.byLevel; + GuildMemberData.dwOffer = memberPacket.dwOffer; + GuildMemberData.byGeneralFlag = memberPacket.byIsGeneral; + CPythonGuild::Instance().RegisterMember(GuildMemberData); + + // Messenger + if (strcmp(szName, CPythonPlayer::Instance().GetName())) + CPythonMessenger::Instance().AppendGuildMember(szName); + + __RefreshTargetBoardByName(szName); + + iPacketSize -= sizeof(memberPacket); + } + + __RefreshGuildWindowInfoPage(); + __RefreshGuildWindowMemberPage(); + __RefreshMessengerWindow(); + __RefreshCharacterWindow(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_Grade(const TPacketGCGuild& pack) +{ + BYTE byCount; + if (!Recv(sizeof(byCount), &byCount)) + return false; + + for (BYTE i = 0; i < byCount; ++ i) + { + BYTE byIndex; + if (!Recv(sizeof(byCount), &byIndex)) + return false; + TPacketGCGuildSubGrade GradePacket; + if (!Recv(sizeof(GradePacket), &GradePacket)) + return false; + + auto data = CPythonGuild::SGuildGradeData(GradePacket.auth_flag, GradePacket.grade_name); + CPythonGuild::Instance().SetGradeData(byIndex, data); + //Tracef(" [%d/%d] : %s, %d\n", byIndex, byCount, GradePacket.grade_name, GradePacket.auth_flag); + } + __RefreshGuildWindowGradePage(); + __RefreshGuildWindowMemberPageGradeComboBox(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_GradeName(const TPacketGCGuild& pack) +{ + BYTE byGradeNumber; + if (!Recv(sizeof(byGradeNumber), &byGradeNumber)) + return false; + + char szGradeName[GUILD_GRADE_NAME_MAX_LEN+1] = ""; + if (!Recv(sizeof(szGradeName), &szGradeName)) + return false; + + CPythonGuild::Instance().SetGradeName(byGradeNumber, szGradeName); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildGrade", Py_BuildValue("()")); + + Tracef(" %d, %s\n", byGradeNumber, szGradeName); + __RefreshGuildWindowGradePage(); + __RefreshGuildWindowMemberPageGradeComboBox(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_GradeAuth(const TPacketGCGuild& pack) +{ + BYTE byGradeNumber; + if (!Recv(sizeof(byGradeNumber), &byGradeNumber)) + return false; + BYTE byAuthorityFlag; + if (!Recv(sizeof(byAuthorityFlag), &byAuthorityFlag)) + return false; + + CPythonGuild::Instance().SetGradeAuthority(byGradeNumber, byAuthorityFlag); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildGrade", Py_BuildValue("()")); + + Tracef(" %d, %d\n", byGradeNumber, byAuthorityFlag); + __RefreshGuildWindowGradePage(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_Info(const TPacketGCGuild& pack) +{ + TPacketGCGuildInfo GuildInfo; + if (!Recv(sizeof(GuildInfo), &GuildInfo)) + return false; + + CPythonGuild::Instance().EnableGuild(); + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + strncpy(rGuildInfo.szGuildName, GuildInfo.name, GUILD_NAME_MAX_LEN); + rGuildInfo.szGuildName[GUILD_NAME_MAX_LEN] = '\0'; + + rGuildInfo.dwGuildID = GuildInfo.guild_id; + rGuildInfo.dwMasterPID = GuildInfo.master_pid; + rGuildInfo.dwGuildLevel = GuildInfo.level; + rGuildInfo.dwCurrentExperience = GuildInfo.exp; + rGuildInfo.dwCurrentMemberCount = GuildInfo.member_count; + rGuildInfo.dwMaxMemberCount = GuildInfo.max_member_count; + rGuildInfo.dwGuildMoney = GuildInfo.gold; + rGuildInfo.bHasLand = GuildInfo.hasLand; + + //Tracef(" %s, %d, %d : %d\n", GuildInfo.name, GuildInfo.master_pid, GuildInfo.level, rGuildInfo.bHasLand); + __RefreshGuildWindowInfoPage(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_Comments(const TPacketGCGuild& pack) +{ + BYTE byCount; + if (!Recv(sizeof(byCount), &byCount)) + return false; + + CPythonGuild::Instance().ClearComment(); + //Tracef(" >>> Comments Count : %d\n", byCount); + + for (BYTE i = 0; i < byCount; ++i) + { + DWORD dwCommentID; + if (!Recv(sizeof(dwCommentID), &dwCommentID)) + return false; + + char szName[CHARACTER_NAME_MAX_LEN+1] = ""; + if (!Recv(sizeof(szName), &szName)) + return false; + + char szComment[GULID_COMMENT_MAX_LEN+1] = ""; + if (!Recv(sizeof(szComment), &szComment)) + return false; + + //Tracef(" [Comment-%d] : %s, %s\n", dwCommentID, szName, szComment); + CPythonGuild::Instance().RegisterComment(dwCommentID, szName, szComment); + } + + __RefreshGuildWindowBoardPage(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_ChangeExp(const TPacketGCGuild& pack) +{ + BYTE byLevel; + if (!Recv(sizeof(byLevel), &byLevel)) + return false; + uint32_t dwEXP; + if (!Recv(sizeof(dwEXP), &dwEXP)) + return false; + CPythonGuild::Instance().SetGuildEXP(byLevel, dwEXP); + Tracef(" %d, %d\n", byLevel, dwEXP); + __RefreshGuildWindowInfoPage(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_ChangeMemberGrade(const TPacketGCGuild& pack) +{ + uint32_t dwPID; + if (!Recv(sizeof(dwPID), &dwPID)) + return false; + BYTE byGrade; + if (!Recv(sizeof(byGrade), &byGrade)) + return false; + CPythonGuild::Instance().ChangeGuildMemberGrade(dwPID, byGrade); + Tracef(" %d, %d\n", dwPID, byGrade); + __RefreshGuildWindowMemberPage(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_SkillInfo(const TPacketGCGuild& pack) +{ + CPythonGuild::TGuildSkillData & rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); + if (!Recv(sizeof(rSkillData.bySkillPoint), &rSkillData.bySkillPoint)) + return false; + if (!Recv(sizeof(rSkillData.bySkillLevel), rSkillData.bySkillLevel)) + return false; + if (!Recv(sizeof(rSkillData.wGuildPoint), &rSkillData.wGuildPoint)) + return false; + if (!Recv(sizeof(rSkillData.wMaxGuildPoint), &rSkillData.wMaxGuildPoint)) + return false; + + Tracef(" %d / %d, %d\n", rSkillData.bySkillPoint, rSkillData.wGuildPoint, rSkillData.wMaxGuildPoint); + __RefreshGuildWindowSkillPage(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_ChangeMemberGeneral(const TPacketGCGuild& pack) +{ + uint32_t dwPID; + if (!Recv(sizeof(dwPID), &dwPID)) + return false; + BYTE byFlag; + if (!Recv(sizeof(byFlag), &byFlag)) + return false; + + CPythonGuild::Instance().ChangeGuildMemberGeneralFlag(dwPID, byFlag); + Tracef(" %d, %d\n", dwPID, byFlag); + __RefreshGuildWindowMemberPage(); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_Invite(const TPacketGCGuild& pack) +{ + uint32_t dwGuildID; + if (!Recv(sizeof(dwGuildID), &dwGuildID)) + return false; + char szGuildName[GUILD_NAME_MAX_LEN+1]; + if (!Recv(GUILD_NAME_MAX_LEN, &szGuildName)) + return false; + + szGuildName[GUILD_NAME_MAX_LEN] = 0; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RecvGuildInviteQuestion", Py_BuildValue("(is)", dwGuildID, szGuildName)); + Tracef(" %d, %s\n", dwGuildID, szGuildName); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_War(const TPacketGCGuild& pack) +{ + TPacketGCGuildWar kGuildWar; + if (!Recv(sizeof(kGuildWar), &kGuildWar)) + return false; + + switch (kGuildWar.bWarState) + { + case GUILD_WAR_SEND_DECLARE: + Tracef(" >> GuildSub::GC::WAR : GUILD_WAR_SEND_DECLARE\n"); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnSendDeclare", + Py_BuildValue("(i)", kGuildWar.dwGuildOpp) + ); + break; + case GUILD_WAR_RECV_DECLARE: + Tracef(" >> GuildSub::GC::WAR : GUILD_WAR_RECV_DECLARE\n"); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnRecvDeclare", + Py_BuildValue("(ii)", kGuildWar.dwGuildOpp, kGuildWar.bType) + ); + break; + case GUILD_WAR_ON_WAR: + Tracef(" >> GuildSub::GC::WAR : GUILD_WAR_ON_WAR : %d, %d\n", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnStart", + Py_BuildValue("(ii)", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp) + ); + CPythonGuild::Instance().StartGuildWar(kGuildWar.dwGuildOpp); + break; + case GUILD_WAR_END: + Tracef(" >> GuildSub::GC::WAR : GUILD_WAR_END\n"); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnEnd", + Py_BuildValue("(ii)", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp) + ); + CPythonGuild::Instance().EndGuildWar(kGuildWar.dwGuildOpp); + break; + } + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_Name(const TPacketGCGuild& pack) +{ + uint32_t dwID; + char szGuildName[GUILD_NAME_MAX_LEN+1]; + + int iPacketSize = int(pack.length) - sizeof(pack); + + int nItemSize = sizeof(dwID) + GUILD_NAME_MAX_LEN; + + assert(iPacketSize%nItemSize==0 && "GuildSub::GC::GUILD_NAME"); + + for (; iPacketSize > 0;) + { + if (!Recv(sizeof(dwID), &dwID)) + return false; + + if (!Recv(GUILD_NAME_MAX_LEN, &szGuildName)) + return false; + + szGuildName[GUILD_NAME_MAX_LEN] = 0; + + //Tracef(" >> GulidName [%d : %s]\n", dwID, szGuildName); + CPythonGuild::Instance().RegisterGuildName(dwID, szGuildName); + iPacketSize -= nItemSize; + } + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_WarList(const TPacketGCGuild& pack) +{ + uint32_t dwSrcGuildID; + uint32_t dwDstGuildID; + + int iPacketSize = int(pack.length) - sizeof(pack); + int nItemSize = sizeof(dwSrcGuildID) + sizeof(dwDstGuildID); + + assert(iPacketSize%nItemSize==0 && "GuildSub::GC::GUILD_WAR_LIST"); + + for (; iPacketSize > 0;) + { + if (!Recv(sizeof(dwSrcGuildID), &dwSrcGuildID)) + return false; + + if (!Recv(sizeof(dwDstGuildID), &dwDstGuildID)) + return false; + + Tracef(" >> GulidWarList [%d vs %d]\n", dwSrcGuildID, dwDstGuildID); + CInstanceBase::InsertGVGKey(dwSrcGuildID, dwDstGuildID); + CPythonCharacterManager::Instance().ChangeGVG(dwSrcGuildID, dwDstGuildID); + iPacketSize -= nItemSize; + } + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_WarEndList(const TPacketGCGuild& pack) +{ + uint32_t dwSrcGuildID; + uint32_t dwDstGuildID; + + int iPacketSize = int(pack.length) - sizeof(pack); + int nItemSize = sizeof(dwSrcGuildID) + sizeof(dwDstGuildID); + + assert(iPacketSize%nItemSize==0 && "GuildSub::GC::GUILD_WAR_END_LIST"); + + for (; iPacketSize > 0;) + { + + if (!Recv(sizeof(dwSrcGuildID), &dwSrcGuildID)) + return false; + + if (!Recv(sizeof(dwDstGuildID), &dwDstGuildID)) + return false; + + Tracef(" >> GulidWarEndList [%d vs %d]\n", dwSrcGuildID, dwDstGuildID); + CInstanceBase::RemoveGVGKey(dwSrcGuildID, dwDstGuildID); + CPythonCharacterManager::Instance().ChangeGVG(dwSrcGuildID, dwDstGuildID); + iPacketSize -= nItemSize; + } + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_WarPoint(const TPacketGCGuild& pack) +{ + TPacketGuildWarPoint GuildWarPoint; + if (!Recv(sizeof(GuildWarPoint), &GuildWarPoint)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnRecvPoint", + Py_BuildValue("(iii)", GuildWarPoint.dwGainGuildID, GuildWarPoint.dwOpponentGuildID, GuildWarPoint.lPoint) + ); + return true; +} + +bool CPythonNetworkStream::RecvGuildSub_MoneyChange(const TPacketGCGuild& pack) +{ + uint32_t dwMoney; + if (!Recv(sizeof(dwMoney), &dwMoney)) + return false; + + CPythonGuild::Instance().SetGuildMoney(dwMoney); + + __RefreshGuildWindowInfoPage(); + Tracef(" >> Guild Money Change : %d\n", dwMoney); return true; } @@ -3955,20 +3626,22 @@ bool CPythonNetworkStream::RecvMarkUpdate() bool CPythonNetworkStream::SendFishingPacket(int iRotation) { - BYTE byHeader = HEADER_CG_FISHING; - if (!Send(sizeof(byHeader), &byHeader)) - return false; - BYTE byPacketRotation = iRotation / 5; - if (!Send(sizeof(BYTE), &byPacketRotation)) + TPacketCGFishing pack; + pack.header = CG::FISHING; + pack.length = sizeof(pack); + pack.dir = iRotation / 5; + + if (!Send(sizeof(pack), &pack)) return false; - return SendSequence(); + return true; } bool CPythonNetworkStream::SendGiveItemPacket(DWORD dwTargetVID, TItemPos ItemPos, int iItemCount) { TPacketCGGiveItem GiveItemPacket; - GiveItemPacket.byHeader = HEADER_CG_GIVE_ITEM; + GiveItemPacket.header = CG::ITEM_GIVE; + GiveItemPacket.length = sizeof(GiveItemPacket); GiveItemPacket.dwTargetVID = dwTargetVID; GiveItemPacket.ItemPos = ItemPos; GiveItemPacket.byItemCount = iItemCount; @@ -3976,7 +3649,7 @@ bool CPythonNetworkStream::SendGiveItemPacket(DWORD dwTargetVID, TItemPos ItemPo if (!Send(sizeof(GiveItemPacket), &GiveItemPacket)) return false; - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvFishing() @@ -3986,7 +3659,7 @@ bool CPythonNetworkStream::RecvFishing() return false; CInstanceBase * pFishingInstance = NULL; - if (FISHING_SUBHEADER_GC_FISH != FishingPacket.subheader) + if (FishingSub::GC::FISH != FishingPacket.subheader) { pFishingInstance = CPythonCharacterManager::Instance().GetInstancePtr(FishingPacket.info); if (!pFishingInstance) @@ -3995,31 +3668,31 @@ bool CPythonNetworkStream::RecvFishing() switch (FishingPacket.subheader) { - case FISHING_SUBHEADER_GC_START: + case FishingSub::GC::START: pFishingInstance->StartFishing(float(FishingPacket.dir) * 5.0f); break; - case FISHING_SUBHEADER_GC_STOP: + case FishingSub::GC::STOP: if (pFishingInstance->IsFishing()) pFishingInstance->StopFishing(); break; - case FISHING_SUBHEADER_GC_REACT: + case FishingSub::GC::REACT: if (pFishingInstance->IsFishing()) { pFishingInstance->SetFishEmoticon(); // Fish Emoticon pFishingInstance->ReactFishing(); } break; - case FISHING_SUBHEADER_GC_SUCCESS: + case FishingSub::GC::SUCCESS: pFishingInstance->CatchSuccess(); break; - case FISHING_SUBHEADER_GC_FAIL: + case FishingSub::GC::FAIL: pFishingInstance->CatchFail(); if (pFishingInstance == CPythonCharacterManager::Instance().GetMainInstancePtr()) { PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnFishingFailure", Py_BuildValue("()")); } break; - case FISHING_SUBHEADER_GC_FISH: + case FishingSub::GC::FISH: { DWORD dwFishID = FishingPacket.info; @@ -4047,6 +3720,10 @@ bool CPythonNetworkStream::RecvFishing() } break; } + + default: + TraceError("RecvFishing: unknown subheader %d", FishingPacket.subheader); + break; } return true; @@ -4064,11 +3741,11 @@ bool CPythonNetworkStream::RecvDungeon() switch (DungeonPacket.subheader) { - case DUNGEON_SUBHEADER_GC_TIME_ATTACK_START: + case DungeonSub::GC::TIME_ATTACK_START: { break; } - case DUNGEON_SUBHEADER_GC_DESTINATION_POSITION: + case DungeonSub::GC::DESTINATION_POSITION: { unsigned long ulx, uly; if (!Recv(sizeof(ulx), &ulx)) @@ -4079,6 +3756,10 @@ bool CPythonNetworkStream::RecvDungeon() CPythonPlayer::Instance().SetDungeonDestinationPosition(ulx, uly); break; } + + default: + TraceError("RecvDungeon: unknown subheader %d", DungeonPacket.subheader); + break; } return true; @@ -4091,7 +3772,8 @@ bool CPythonNetworkStream::RecvDungeon() bool CPythonNetworkStream::SendBuildPrivateShopPacket(const char * c_szName, const std::vector & c_rSellingItemStock) { TPacketCGMyShop packet; - packet.bHeader = HEADER_CG_MYSHOP; + packet.header = CG::MYSHOP; + packet.length = sizeof(packet) + sizeof(TShopItemTable) * c_rSellingItemStock.size(); strncpy(packet.szSign, c_szName, SHOP_SIGN_MAX_LEN); packet.bCount = static_cast(c_rSellingItemStock.size()); if (!Send(sizeof(packet), &packet)) @@ -4104,7 +3786,7 @@ bool CPythonNetworkStream::SendBuildPrivateShopPacket(const char * c_szName, con return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvShopSignPacket() @@ -4198,26 +3880,28 @@ void CPythonNetworkStream::__TEST_SetSkillGroupFake(int iIndex) bool CPythonNetworkStream::SendRefinePacket(BYTE byPos, BYTE byType) { TPacketCGRefine kRefinePacket; - kRefinePacket.header = HEADER_CG_REFINE; + kRefinePacket.header = CG::REFINE; + kRefinePacket.length = sizeof(kRefinePacket); kRefinePacket.pos = byPos; kRefinePacket.type = byType; if (!Send(sizeof(kRefinePacket), &kRefinePacket)) return false; - return SendSequence(); + return true; } bool CPythonNetworkStream::SendSelectItemPacket(DWORD dwItemPos) { TPacketCGScriptSelectItem kScriptSelectItem; - kScriptSelectItem.header = HEADER_CG_SCRIPT_SELECT_ITEM; + kScriptSelectItem.header = CG::SCRIPT_SELECT_ITEM; + kScriptSelectItem.length = sizeof(kScriptSelectItem); kScriptSelectItem.selection = dwItemPos; if (!Send(sizeof(kScriptSelectItem), &kScriptSelectItem)) return false; - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvRefineInformationPacket() @@ -4291,7 +3975,7 @@ bool CPythonNetworkStream::RecvNPCList() if (!Recv(sizeof(kNPCPosition), &kNPCPosition)) return false; - assert(int(kNPCPosition.size)-sizeof(kNPCPosition) == kNPCPosition.count*sizeof(TNPCPosition) && "HEADER_GC_NPC_POSITION"); + assert(int(kNPCPosition.length)-sizeof(kNPCPosition) == kNPCPosition.count*sizeof(TNPCPosition) && "GC::NPC_POSITION"); CPythonMiniMap::Instance().ClearAtlasMarkInfo(); @@ -4330,7 +4014,8 @@ bool CPythonNetworkStream::SendClientVersionPacket() CFileNameHelper::ChangeDosPath(filename); TPacketCGClientVersion kVersionPacket{}; - kVersionPacket.header = HEADER_CG_CLIENT_VERSION; + kVersionPacket.header = CG::CLIENT_VERSION; + kVersionPacket.length = sizeof(kVersionPacket); strncpy(kVersionPacket.filename, filename.c_str(), sizeof(kVersionPacket.filename) - 1); kVersionPacket.filename[sizeof(kVersionPacket.filename) - 1] = '\0'; @@ -4340,7 +4025,7 @@ bool CPythonNetworkStream::SendClientVersionPacket() if (!Send(sizeof(kVersionPacket), &kVersionPacket)) Tracef("SendClientReportPacket Error"); - return SendSequence(); + return true; } bool CPythonNetworkStream::RecvAffectAddPacket() @@ -4420,7 +4105,7 @@ bool CPythonNetworkStream::RecvLandPacket() rkMiniMap.ClearGuildArea(); rkBG.ClearGuildArea(); - int iPacketSize = (kLandList.size - sizeof(TPacketGCLandList)); + int iPacketSize = (kLandList.length - sizeof(TPacketGCLandList)); for (; iPacketSize > 0; iPacketSize-=sizeof(TLandPacketElement)) { TLandPacketElement kElement; @@ -4598,7 +4283,8 @@ bool CPythonNetworkStream::RecvDigMotionPacket() bool CPythonNetworkStream::SendDragonSoulRefinePacket(BYTE bRefineType, TItemPos* pos) { TPacketCGDragonSoulRefine pk; - pk.header = HEADER_CG_DRAGON_SOUL_REFINE; + pk.header = CG::DRAGON_SOUL_REFINE; + pk.length = sizeof(pk); pk.bSubType = bRefineType; memcpy (pk.ItemGrid, pos, sizeof (TItemPos) * DS_REFINE_WINDOW_MAX_NUM); if (!Send(sizeof (pk), &pk)) diff --git a/src/UserInterface/PythonNetworkStreamPhaseGameActor.cpp b/src/UserInterface/PythonNetworkStreamPhaseGameActor.cpp index 296b65e..b3fdec4 100644 --- a/src/UserInterface/PythonNetworkStreamPhaseGameActor.cpp +++ b/src/UserInterface/PythonNetworkStreamPhaseGameActor.cpp @@ -414,7 +414,7 @@ bool CPythonNetworkStream::RecvSyncPositionPacket() TPacketGCSyncPositionElement kSyncPos; - UINT uSyncPosCount=(kPacketSyncPos.wSize-sizeof(kPacketSyncPos))/sizeof(kSyncPos); + UINT uSyncPosCount=(kPacketSyncPos.length-sizeof(kPacketSyncPos))/sizeof(kSyncPos); for (UINT iSyncPos=0; iSyncPosSetMainActorVID(m_dwMainActorVID); - CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); - rkPlayer.SetName(MainChrPacket.szName); + CPythonPlayer& rkPlayer = CPythonPlayer::Instance(); + rkPlayer.SetName(pack.szName); rkPlayer.SetMainCharacterIndex(GetMainActorVID()); - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", MainChrPacket.lX, MainChrPacket.lY)); + if (pack.szBGMName[0] != '\0') + { + if (pack.fBGMVol > 0.0f) + __SetFieldMusicFileInfo(pack.szBGMName, pack.fBGMVol); + else + __SetFieldMusicFileName(pack.szBGMName); + } - //Tracef(" >> RecvMainCharacter\n"); - - SendClientVersionPacket(); - return true; -} - -// SUPPORT_BGM -bool CPythonNetworkStream::RecvMainCharacter2_EMPIRE() -{ - TPacketGCMainCharacter2_EMPIRE mainChrPacket; - if (!Recv(sizeof(mainChrPacket), &mainChrPacket)) - return false; - - m_dwMainActorVID = mainChrPacket.dwVID; - m_dwMainActorRace = mainChrPacket.wRaceNum; - m_dwMainActorEmpire = mainChrPacket.byEmpire; - m_dwMainActorSkillGroup = mainChrPacket.bySkillGroup; - - m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID); - - CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); - rkPlayer.SetName(mainChrPacket.szName); - rkPlayer.SetMainCharacterIndex(GetMainActorVID()); - - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", mainChrPacket.lX, mainChrPacket.lY)); - - //Tracef(" >> RecvMainCharacterNew : %d\n", m_dwMainActorEmpire); - - SendClientVersionPacket(); - return true; -} - -bool CPythonNetworkStream::RecvMainCharacter3_BGM() -{ - TPacketGCMainCharacter3_BGM mainChrPacket; - if (!Recv(sizeof(mainChrPacket), &mainChrPacket)) - return false; - - m_dwMainActorVID = mainChrPacket.dwVID; - m_dwMainActorRace = mainChrPacket.wRaceNum; - m_dwMainActorEmpire = mainChrPacket.byEmpire; - m_dwMainActorSkillGroup = mainChrPacket.bySkillGroup; - - m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID); - - CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); - rkPlayer.SetName(mainChrPacket.szUserName); - rkPlayer.SetMainCharacterIndex(GetMainActorVID()); - - __SetFieldMusicFileName(mainChrPacket.szBGMName); - - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", mainChrPacket.lX, mainChrPacket.lY)); - - //Tracef(" >> RecvMainCharacterNew : %d\n", m_dwMainActorEmpire); - - SendClientVersionPacket(); - return true; -} - -bool CPythonNetworkStream::RecvMainCharacter4_BGM_VOL() -{ - TPacketGCMainCharacter4_BGM_VOL mainChrPacket; - if (!Recv(sizeof(mainChrPacket), &mainChrPacket)) - return false; - - m_dwMainActorVID = mainChrPacket.dwVID; - m_dwMainActorRace = mainChrPacket.wRaceNum; - m_dwMainActorEmpire = mainChrPacket.byEmpire; - m_dwMainActorSkillGroup = mainChrPacket.bySkillGroup; - - m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID); - - CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); - rkPlayer.SetName(mainChrPacket.szUserName); - rkPlayer.SetMainCharacterIndex(GetMainActorVID()); - - __SetFieldMusicFileInfo(mainChrPacket.szBGMName, mainChrPacket.fBGMVol); - - PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", mainChrPacket.lX, mainChrPacket.lY)); - - //Tracef(" >> RecvMainCharacterNew : %d\n", m_dwMainActorEmpire); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", pack.lX, pack.lY)); SendClientVersionPacket(); return true; @@ -348,20 +195,15 @@ void CPythonNetworkStream::StartGame() { m_isStartGame=TRUE; } - + bool CPythonNetworkStream::SendEnterGame() { TPacketCGEnterFrontGame EnterFrontGamePacket; - EnterFrontGamePacket.header = HEADER_CG_ENTERGAME; + EnterFrontGamePacket.header = CG::ENTERGAME; + EnterFrontGamePacket.length = sizeof(EnterFrontGamePacket); if (!Send(sizeof(EnterFrontGamePacket), &EnterFrontGamePacket)) - { - Tracen("Send EnterFrontGamePacket"); - return false; - } - - if (!SendSequence()) return false; __SendInternalBuffer(); diff --git a/src/UserInterface/PythonNetworkStreamPhaseLogin.cpp b/src/UserInterface/PythonNetworkStreamPhaseLogin.cpp index 1d3957b..9a876ed 100644 --- a/src/UserInterface/PythonNetworkStreamPhaseLogin.cpp +++ b/src/UserInterface/PythonNetworkStreamPhaseLogin.cpp @@ -6,64 +6,7 @@ // Login --------------------------------------------------------------------------- void CPythonNetworkStream::LoginPhase() { - TPacketHeader header; - if (!CheckPacket(&header)) - return; - - switch (header) - { - case HEADER_GC_PHASE: - if (RecvPhasePacket()) - return; - break; - - case HEADER_GC_LOGIN_SUCCESS3: - if (__RecvLoginSuccessPacket3()) - return; - break; - case HEADER_GC_LOGIN_SUCCESS4: - if (__RecvLoginSuccessPacket4()) - return; - break; - - - case HEADER_GC_LOGIN_FAILURE: - if (__RecvLoginFailurePacket()) - return; - break; - - case HEADER_GC_EMPIRE: - if (__RecvEmpirePacket()) - return; - break; - - case HEADER_GC_LOGIN_KEY: - if (__RecvLoginKeyPacket()) - return; - break; - - case HEADER_GC_PING: - if (RecvPingPacket()) - return; - break; - - case HEADER_GC_KEY_CHALLENGE: - RecvKeyChallenge(); - return; - break; - - case HEADER_GC_KEY_COMPLETE: - RecvKeyComplete(); - return; - break; - - default: - if (RecvDefaultPacket(header)) - return; - break; - } - - RecvErrorPacket(header); + DispatchPacket(m_loginHandlers); } void CPythonNetworkStream::SetLoginPhase() @@ -71,6 +14,7 @@ void CPythonNetworkStream::SetLoginPhase() if ("Login" != m_strPhase) m_phaseLeaveFunc.Run(); + Tracef("[PHASE] Entering phase: Login\n"); Tracen(""); Tracen("## Network - Login Phase ##"); Tracen(""); @@ -84,7 +28,6 @@ void CPythonNetworkStream::SetLoginPhase() if (0 == m_dwLoginKey) { - TraceError("SetLoginPhase: no login key - cannot login without auth server"); ClearLoginInfo(); return; } @@ -166,10 +109,7 @@ bool CPythonNetworkStream::__RecvLoginSuccessPacket4() m_kMarkAuth.m_dwHandle=kPacketLoginSuccess.handle; m_kMarkAuth.m_dwRandomKey=kPacketLoginSuccess.random_key; - if (__DirectEnterMode_IsSet()) - { - } - else + if (!__DirectEnterMode_IsSet()) { PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "Refresh", Py_BuildValue("()")); } @@ -205,7 +145,8 @@ bool CPythonNetworkStream::__RecvLoginFailurePacket() bool CPythonNetworkStream::SendLoginPacketNew(const char * c_szName, const char * c_szPassword) { TPacketCGLogin2 LoginPacket; - LoginPacket.header = HEADER_CG_LOGIN2; + LoginPacket.header = CG::LOGIN2; + LoginPacket.length = sizeof(LoginPacket); LoginPacket.login_key = m_dwLoginKey; strncpy(LoginPacket.name, c_szName, sizeof(LoginPacket.name)-1); @@ -217,12 +158,6 @@ bool CPythonNetworkStream::SendLoginPacketNew(const char * c_szName, const char return false; } - if (!SendSequence()) - { - Tracen("SendLogin Error"); - return false; - } - __SendInternalBuffer(); return true; diff --git a/src/UserInterface/PythonNetworkStreamPhaseOffline.cpp b/src/UserInterface/PythonNetworkStreamPhaseOffline.cpp index 754fce8..85c928b 100644 --- a/src/UserInterface/PythonNetworkStreamPhaseOffline.cpp +++ b/src/UserInterface/PythonNetworkStreamPhaseOffline.cpp @@ -5,18 +5,5 @@ void CPythonNetworkStream::OffLinePhase() { - TPacketHeader header; - - if (!CheckPacket(&header)) - return; - - switch (header) - { - case HEADER_GC_PHASE: - if (RecvPhasePacket()) - return; - break; - } - - RecvErrorPacket(header); + DispatchPacket(m_offlineHandlers); } \ No newline at end of file diff --git a/src/UserInterface/PythonNetworkStreamPhaseSelect.cpp b/src/UserInterface/PythonNetworkStreamPhaseSelect.cpp index ca6a7c4..00ddec5 100644 --- a/src/UserInterface/PythonNetworkStreamPhaseSelect.cpp +++ b/src/UserInterface/PythonNetworkStreamPhaseSelect.cpp @@ -8,10 +8,6 @@ void CPythonNetworkStream::SetSelectPhase() if ("Select" != m_strPhase) m_phaseLeaveFunc.Run(); - Tracen(""); - Tracen("## Network - Select Phase ##"); - Tracen(""); - m_strPhase = "Select"; m_dwChangingPhaseTime = ELTimer_GetMSec(); @@ -20,7 +16,7 @@ void CPythonNetworkStream::SetSelectPhase() if (__DirectEnterMode_IsSet()) { - PyCallClassMemberFunc(m_poHandler, "SetLoadingPhase", Py_BuildValue("()")); + PyCallClassMemberFunc(m_poHandler, "SetLoadingPhase", Py_BuildValue("()")); } else { @@ -33,99 +29,14 @@ void CPythonNetworkStream::SetSelectPhase() void CPythonNetworkStream::SelectPhase() { - TPacketHeader header; - - if (!CheckPacket(&header)) - return; - - switch (header) - { - case HEADER_GC_PHASE: - if (RecvPhasePacket()) - return; - break; - - case HEADER_GC_EMPIRE: - if (__RecvEmpirePacket()) - return; - break; - - case HEADER_GC_LOGIN_SUCCESS3: - if (__RecvLoginSuccessPacket3()) - return; - break; - - case HEADER_GC_LOGIN_SUCCESS4: - if (__RecvLoginSuccessPacket4()) - return; - break; - - - case HEADER_GC_PLAYER_CREATE_SUCCESS: - if (__RecvPlayerCreateSuccessPacket()) - return; - break; - - case HEADER_GC_PLAYER_CREATE_FAILURE: - if (__RecvPlayerCreateFailurePacket()) - return; - break; - - case HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID: - if (__RecvPlayerDestroyFailurePacket()) - return; - break; - - case HEADER_GC_PLAYER_DELETE_SUCCESS: - if (__RecvPlayerDestroySuccessPacket()) - return; - break; - - case HEADER_GC_CHANGE_NAME: - if (__RecvChangeName()) - return; - break; - - case HEADER_GC_HANDSHAKE: - RecvHandshakePacket(); - return; - break; - - case HEADER_GC_HANDSHAKE_OK: - RecvHandshakeOKPacket(); - return; - break; - - case HEADER_GC_KEY_CHALLENGE: - RecvKeyChallenge(); - return; - break; - - case HEADER_GC_KEY_COMPLETE: - RecvKeyComplete(); - return; - break; - - case HEADER_GC_PLAYER_POINT_CHANGE: - TPacketGCPointChange PointChange; - Recv(sizeof(TPacketGCPointChange), &PointChange); - return; - break; - - /////////////////////////////////////////////////////////////////////////////////////////// - case HEADER_GC_PING: - if (RecvPingPacket()) - return; - break; - } - - RecvErrorPacket(header); + DispatchPacket(m_selectHandlers); } bool CPythonNetworkStream::SendSelectEmpirePacket(DWORD dwEmpireID) { TPacketCGEmpire kPacketEmpire; - kPacketEmpire.bHeader=HEADER_CG_EMPIRE; + kPacketEmpire.header=CG::EMPIRE; + kPacketEmpire.length = sizeof(kPacketEmpire); kPacketEmpire.bEmpire=dwEmpireID; if (!Send(sizeof(kPacketEmpire), &kPacketEmpire)) @@ -135,14 +46,15 @@ bool CPythonNetworkStream::SendSelectEmpirePacket(DWORD dwEmpireID) } SetEmpireID(dwEmpireID); - return SendSequence(); + return true; } bool CPythonNetworkStream::SendSelectCharacterPacket(BYTE Index) { TPacketCGSelectCharacter SelectCharacterPacket; - SelectCharacterPacket.header = HEADER_CG_PLAYER_SELECT; + SelectCharacterPacket.header = CG::CHARACTER_SELECT; + SelectCharacterPacket.length = sizeof(SelectCharacterPacket); SelectCharacterPacket.player_index = Index; if (!Send(sizeof(TPacketCGSelectCharacter), &SelectCharacterPacket)) @@ -151,14 +63,15 @@ bool CPythonNetworkStream::SendSelectCharacterPacket(BYTE Index) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendDestroyCharacterPacket(BYTE index, const char * szPrivateCode) { TPacketCGDestroyCharacter DestroyCharacterPacket; - DestroyCharacterPacket.header = HEADER_CG_PLAYER_DESTROY; + DestroyCharacterPacket.header = CG::CHARACTER_DELETE; + DestroyCharacterPacket.length = sizeof(DestroyCharacterPacket); DestroyCharacterPacket.index = index; strncpy(DestroyCharacterPacket.szPrivateCode, szPrivateCode, PRIVATE_CODE_LENGTH-1); @@ -168,14 +81,15 @@ bool CPythonNetworkStream::SendDestroyCharacterPacket(BYTE index, const char * s return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendCreateCharacterPacket(BYTE index, const char *name, BYTE job, BYTE shape, BYTE byCON, BYTE byINT, BYTE bySTR, BYTE byDEX) { TPacketCGCreateCharacter createCharacterPacket; - createCharacterPacket.header = HEADER_CG_PLAYER_CREATE; + createCharacterPacket.header = CG::CHARACTER_CREATE; + createCharacterPacket.length = sizeof(createCharacterPacket); createCharacterPacket.index = index; strncpy(createCharacterPacket.name, name, CHARACTER_NAME_MAX_LEN); createCharacterPacket.job = job; @@ -191,13 +105,14 @@ bool CPythonNetworkStream::SendCreateCharacterPacket(BYTE index, const char *nam return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::SendChangeNamePacket(BYTE index, const char *name) { TPacketCGChangeName ChangeNamePacket; - ChangeNamePacket.header = HEADER_CG_CHANGE_NAME; + ChangeNamePacket.header = CG::CHANGE_NAME; + ChangeNamePacket.length = sizeof(ChangeNamePacket); ChangeNamePacket.index = index; strncpy(ChangeNamePacket.name, name, CHARACTER_NAME_MAX_LEN); @@ -207,7 +122,7 @@ bool CPythonNetworkStream::SendChangeNamePacket(BYTE index, const char *name) return false; } - return SendSequence(); + return true; } bool CPythonNetworkStream::__RecvPlayerCreateSuccessPacket() diff --git a/src/UserInterface/PythonPlayer.cpp b/src/UserInterface/PythonPlayer.cpp index 16654e5..7e527c5 100644 --- a/src/UserInterface/PythonPlayer.cpp +++ b/src/UserInterface/PythonPlayer.cpp @@ -1598,17 +1598,6 @@ DWORD CPythonPlayer::GetPKMode() return pInstance->GetPKMode(); } -void CPythonPlayer::SetMobileFlag(BOOL bFlag) -{ - m_bMobileFlag = bFlag; - PyCallClassMemberFunc(m_ppyGameWindow, "RefreshMobile", Py_BuildValue("()")); -} - -BOOL CPythonPlayer::HasMobilePhoneNumber() -{ - return m_bMobileFlag; -} - void CPythonPlayer::SetGameWindow(PyObject * ppyObject) { m_ppyGameWindow = ppyObject; @@ -1692,8 +1681,6 @@ void CPythonPlayer::ClearSkillDict() m_fConsumeStaminaPerSec = 0.0f; m_fCurrentStamina = 0.0f; - m_bMobileFlag = FALSE; - __ClearAutoAttackTargetActorID(); } @@ -1765,8 +1752,6 @@ void CPythonPlayer::Clear() m_inGuildAreaID = 0xffffffff; - m_bMobileFlag = FALSE; - __ClearAutoAttackTargetActorID(); } diff --git a/src/UserInterface/PythonPlayer.h b/src/UserInterface/PythonPlayer.h index 9c7d9ee..bda358c 100644 --- a/src/UserInterface/PythonPlayer.h +++ b/src/UserInterface/PythonPlayer.h @@ -403,11 +403,6 @@ class CPythonPlayer : public CSingleton, public IAbstractPlayer DWORD GetPKMode(); - // Mobile - void SetMobileFlag(BOOL bFlag); - BOOL HasMobilePhoneNumber(); - - // Combo void SetComboSkillFlag(BOOL bFlag); @@ -651,9 +646,6 @@ class CPythonPlayer : public CSingleton, public IAbstractPlayer // Guild DWORD m_inGuildAreaID; - // Mobile - BOOL m_bMobileFlag; - // System BOOL m_sysIsCoolTime; BOOL m_sysIsLevelLimit; diff --git a/src/UserInterface/PythonPlayerEventHandler.cpp b/src/UserInterface/PythonPlayerEventHandler.cpp index 676caad..bb78cc5 100644 --- a/src/UserInterface/PythonPlayerEventHandler.cpp +++ b/src/UserInterface/PythonPlayerEventHandler.cpp @@ -203,8 +203,8 @@ void CPythonPlayerEventHandler::FlushVictimList() CPythonNetworkStream& rkStream=CPythonNetworkStream::Instance(); TPacketCGSyncPosition kPacketSyncPos; - kPacketSyncPos.bHeader=HEADER_CG_SYNC_POSITION; - kPacketSyncPos.wSize=sizeof(kPacketSyncPos)+sizeof(TPacketCGSyncPositionElement) * uiVictimCount; + kPacketSyncPos.header=CG::SYNC_POSITION; + kPacketSyncPos.length=sizeof(kPacketSyncPos)+sizeof(TPacketCGSyncPositionElement) * uiVictimCount; rkStream.Send(sizeof(kPacketSyncPos), &kPacketSyncPos); @@ -214,7 +214,6 @@ void CPythonPlayerEventHandler::FlushVictimList() rkStream.SendSyncPositionElementPacket(rkVictim.m_dwVID, rkVictim.m_lPixelX, rkVictim.m_lPixelY); } - rkStream.SendSequence(); m_kVctkVictim.clear(); } diff --git a/src/UserInterface/PythonPlayerInput.cpp b/src/UserInterface/PythonPlayerInput.cpp index 0b30311..cd7a207 100644 --- a/src/UserInterface/PythonPlayerInput.cpp +++ b/src/UserInterface/PythonPlayerInput.cpp @@ -706,33 +706,6 @@ bool CPythonPlayer::__CanMove() return true; } -/* -bool CPythonPlayer::__OLD_CanMove() -{ - if (__IsProcessingEmotion()) - { - return false; - } - - CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); - if (!pkInstMain) - return false; - - if (pkInstMain->IsDead()) - return false; - - if (pkInstMain->IsStun()) - return false; - - if (pkInstMain->isLock()) - return false; - - if (pkInstMain->IsParalysis()) - return false; - - return true; -} -*/ bool CPythonPlayer::__CanAttack() { @@ -947,65 +920,3 @@ void CPythonPlayer::__ReserveProcess_ClickActor() pkInstMain->NEW_AttackToDestInstanceDirection(*pkInstReserved); __ClearReservedAction(); } -/* -CInstanceBase* pkInstReserved=NEW_FindActorPtr(m_dwVIDReserved); -if (pkInstReserved) -{ - if (pkInstMain->NEW_IsClickableDistanceDestInstance(*pkInstReserved)) - { - if (pkInstMain->IsAttackableInstance(*pkInstReserved) ) - { - if (!pkInstReserved->IsDead()) - { - if (pkInstMain->IsInSafe()) - { - PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotAttack", Py_BuildValue("(is)", GetMainCharacterIndex(), "IN_SAFE")); - pkInstMain->NEW_Stop(); - } - else if (pkInstReserved->IsInSafe()) - { - PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotAttack", Py_BuildValue("(is)", GetMainCharacterIndex(), "DEST_IN_SAFE")); - pkInstMain->NEW_Stop(); - } - else - { - if (pkInstMain->IsBowMode()) - { - if (!__HasEnoughArrow()) - { - PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShot", Py_BuildValue("(is)", GetMainCharacterIndex(), "EMPTY_ARROW")); - pkInstMain->NEW_Stop(); - __ClearReservedAction(); - break; - } - } - - if (pkInstReserved->GetVirtualID() != GetTargetVID()) - { - SetTarget(pkInstReserved->GetVirtualID()); - } - - pkInstMain->NEW_AttackToDestInstanceDirection(*pkInstReserved); - } - } - } - else - { - __SendClickActorPacket(*pkInstReserved); - - pkInstMain->NEW_Stop(); - } - - __ClearReservedAction(); - } - else - { - //Tracen("ReservedMode: MOVE"); - pkInstMain->NEW_MoveToDestInstanceDirection(*pkInstReserved); - } -} -else -{ - __ClearReservedAction(); -} -*/ diff --git a/src/UserInterface/PythonPlayerModule.cpp b/src/UserInterface/PythonPlayerModule.cpp index 6905fdb..5f94502 100644 --- a/src/UserInterface/PythonPlayerModule.cpp +++ b/src/UserInterface/PythonPlayerModule.cpp @@ -1882,11 +1882,6 @@ PyObject * playerGetPKMode(PyObject* poSelf, PyObject* poArgs) return Py_BuildValue("i", CPythonPlayer::Instance().GetPKMode()); } -PyObject * playerHasMobilePhoneNumber(PyObject* poSelf, PyObject* poArgs) -{ - return Py_BuildValue("i", CPythonPlayer::Instance().HasMobilePhoneNumber()); -} - PyObject * playerSetWeaponAttackBonusFlag(PyObject* poSelf, PyObject* poArgs) { int iFlag; @@ -2138,11 +2133,11 @@ PyObject* playerSendDragonSoulRefine(PyObject* poSelf, PyObject* poArgs) return Py_BuildException(); switch (bSubHeader) { - case DS_SUB_HEADER_CLOSE: + case DragonSoulSub::CLOSE: break; - case DS_SUB_HEADER_DO_UPGRADE: - case DS_SUB_HEADER_DO_IMPROVEMENT: - case DS_SUB_HEADER_DO_REFINE: + case DragonSoulSub::DO_UPGRADE: + case DragonSoulSub::DO_IMPROVEMENT: + case DragonSoulSub::DO_REFINE: { if (!PyTuple_GetObject(poArgs, 1, &pDic)) return Py_BuildException(); @@ -2317,9 +2312,6 @@ void initPlayer() // PK Mode { "GetPKMode", playerGetPKMode, METH_VARARGS }, - // Mobile - { "HasMobilePhoneNumber", playerHasMobilePhoneNumber, METH_VARARGS }, - // Emotion { "RegisterEmotionIcon", playerRegisterEmotionIcon, METH_VARARGS }, { "GetEmotionIconImage", playerGetEmotionIconImage, METH_VARARGS }, @@ -2568,9 +2560,9 @@ void initPlayer() PyModule_AddIntConstant(poModule, "DRAGON_SOUL_EQUIPMENT_FIRST_SIZE", c_DragonSoul_Equip_Slot_Max); // 용혼석 개량창 - PyModule_AddIntConstant(poModule, "DRAGON_SOUL_REFINE_CLOSE", DS_SUB_HEADER_CLOSE); - PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_UPGRADE", DS_SUB_HEADER_DO_UPGRADE); - PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_IMPROVEMENT", DS_SUB_HEADER_DO_IMPROVEMENT); - PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_REFINE", DS_SUB_HEADER_DO_REFINE); + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_REFINE_CLOSE", DragonSoulSub::CLOSE); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_UPGRADE", DragonSoulSub::DO_UPGRADE); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_IMPROVEMENT", DragonSoulSub::DO_IMPROVEMENT); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_REFINE", DragonSoulSub::DO_REFINE); } diff --git a/src/UserInterface/ServerStateChecker.cpp b/src/UserInterface/ServerStateChecker.cpp index c959837..62e36c1 100644 --- a/src/UserInterface/ServerStateChecker.cpp +++ b/src/UserInterface/ServerStateChecker.cpp @@ -57,8 +57,10 @@ void CServerStateChecker::Request() m_kStream.SetSendBufferSize(1024); m_kStream.SetRecvBufferSize(1024); - BYTE bHeader = HEADER_CG_STATE_CHECKER; - if (!m_kStream.Send(sizeof(bHeader), &bHeader)) + TPacketGCBlank pack; + pack.header = CG::STATE_CHECKER; + pack.length = sizeof(pack); + if (!m_kStream.Send(sizeof(pack), &pack)) { for (std::list::const_iterator it = m_lstChannel.begin(); it != m_lstChannel.end(); ++it) { PyCallClassMemberFunc(m_poWnd, "NotifyChannelState", Py_BuildValue("(ii)", it->uServerIndex, 0)); @@ -72,13 +74,31 @@ void CServerStateChecker::Update() { m_kStream.Process(); - BYTE bHeader; - if (!m_kStream.Recv(sizeof(bHeader), &bHeader)) { - return; - } - if (HEADER_GC_RESPOND_CHANNELSTATUS != bHeader) { - return; + // Skip packets until we find GC::RESPOND_CHANNELSTATUS. + // The server may send other packets first, which we need to discard. + while (true) + { + TDynamicSizePacketHeader packHeader; + if (!m_kStream.Peek(sizeof(packHeader), &packHeader)) + return; + + if (packHeader.header == GC::RESPOND_CHANNELSTATUS) + { + // Consume the header we peeked + m_kStream.Recv(sizeof(packHeader)); + break; + } + + // Not our packet — skip it using its length field + if (packHeader.length < sizeof(packHeader)) + return; + + if (!m_kStream.Peek(packHeader.length)) + return; // Not enough data yet + + m_kStream.Recv(packHeader.length); } + int nSize; if (!m_kStream.Recv(sizeof(nSize), &nSize)) { return; diff --git a/src/UserInterface/StdAfx.h b/src/UserInterface/StdAfx.h index c11f6bb..ec2c2f1 100644 --- a/src/UserInterface/StdAfx.h +++ b/src/UserInterface/StdAfx.h @@ -35,7 +35,6 @@ enum PLAYER_NAME_MAX_LEN = 12, }; -void initudp(); void initapp(); void initime(); void initsystem(); diff --git a/src/UserInterface/UserInterface.cpp b/src/UserInterface/UserInterface.cpp index ca540ed..df27bb9 100644 --- a/src/UserInterface/UserInterface.cpp +++ b/src/UserInterface/UserInterface.cpp @@ -225,7 +225,6 @@ bool RunMainScript(CPythonLauncher& pyLauncher, const char* lpCmdLine) initgrpText(); initwndMgr(); - initudp(); initapp(); initsystem(); initchr();