Fix 40250 classic login and world loading
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
// ClassicSession — MT_PROTOCOL=classic: drives ClassicStream through
|
||||
// HANDSHAKE -> LOGIN -> SELECT -> LOADING -> GAME and parses GC packets into a
|
||||
// shared EntityStore. See docs/CLIENT-40250-PORT.md §4 / §8.
|
||||
// ClassicSession — MT_PROTOCOL=classic: drives ClassicStream through the
|
||||
// 40250 auth-server -> game-server flow and parses GC packets into a shared
|
||||
// EntityStore. See docs/CLIENT-40250-PORT.md §4 / §8.
|
||||
//
|
||||
// The stock 40250 server uses _IMPROVED_PACKET_ENCRYPTION_; ClassicStream
|
||||
// negotiates that DH2 + CTR session before the first login packet.
|
||||
@@ -27,6 +27,13 @@ public:
|
||||
// --- INetSession ---
|
||||
bool connect(const std::string &game_host, uint16_t game_port, const std::string &id,
|
||||
const std::string &pw) override;
|
||||
// Full 40250 flow: auth CG_LOGIN3 -> ticket, then game CG_LOGIN2 -> chars.
|
||||
bool connect(const std::string &auth_host, uint16_t auth_port,
|
||||
const std::string &game_host, uint16_t game_port, const std::string &id,
|
||||
const std::string &pw);
|
||||
// Reconnect directly to a game channel using a previously issued auth ticket.
|
||||
bool connect_with_login_key(const std::string &game_host, uint16_t game_port,
|
||||
const std::string &id, uint32_t login_key);
|
||||
void disconnect() override;
|
||||
bool select_char(int slot) override;
|
||||
bool enter_game() override;
|
||||
@@ -133,36 +140,57 @@ public:
|
||||
// --- accessors ---
|
||||
const std::vector<CharSlot> &char_slots() const { return m_parser.char_slots(); }
|
||||
ClassicStream &stream() { return m_stream; } // for tests / trace
|
||||
ClassicStream &auth_stream() { return m_auth_stream; } // auth-flow tests / trace
|
||||
ClassicParser &parser() { return m_parser; }
|
||||
uint32_t login_key() const { return m_auth_login_key; }
|
||||
uint32_t now_ms() const { return m_now; }
|
||||
void set_now(uint32_t ms) {
|
||||
m_now = ms;
|
||||
m_world.set_now(ms);
|
||||
}
|
||||
// auto-send CG_ENTERGAME this many ms after entering PHASE_LOADING (0 = never,
|
||||
// caller drives enter_game()). Default mirrors the m2dev client's ~1.5s.
|
||||
// caller drives enter_game()). The 40250 test account sends a large map-load
|
||||
// burst; waiting for that burst to drain avoids racing the server's spawn data.
|
||||
void set_auto_entergame_delay(uint32_t ms) { m_entergame_delay = ms; }
|
||||
void set_wire_trace(bool on) { m_stream.set_wire_trace(on); }
|
||||
void set_wire_trace(bool on) {
|
||||
m_stream.set_wire_trace(on);
|
||||
m_auth_stream.set_wire_trace(on);
|
||||
}
|
||||
|
||||
private:
|
||||
void set_stage(Stage s);
|
||||
void on_phase(uint8_t phase);
|
||||
void on_auth_phase(uint8_t phase);
|
||||
bool on_packet(uint8_t header, const uint8_t *body, uint32_t len);
|
||||
bool on_auth_packet(uint8_t header, const uint8_t *body, uint32_t len);
|
||||
void send_login();
|
||||
void send_auth_login();
|
||||
void send_login_by_key();
|
||||
bool send_client_version();
|
||||
|
||||
EntityStore m_world;
|
||||
ClassicStream m_stream;
|
||||
ClassicStream m_auth_stream;
|
||||
ClassicParser m_parser;
|
||||
|
||||
Stage m_stage = Stage::Offline;
|
||||
std::string m_last_error;
|
||||
std::string m_id, m_pw;
|
||||
std::string m_auth_host, m_game_host;
|
||||
uint16_t m_auth_port = 0;
|
||||
uint16_t m_game_port = 0;
|
||||
uint32_t m_auth_login_key = 0;
|
||||
uint32_t m_now = 0;
|
||||
uint32_t m_loading_since = 0;
|
||||
uint32_t m_entergame_delay = 1500;
|
||||
uint32_t m_entergame_delay = 8000;
|
||||
bool m_entergame_sent = false;
|
||||
bool m_login_sent = false;
|
||||
bool m_auth_login_sent = false;
|
||||
bool m_use_auth = false;
|
||||
bool m_auth_succeeded = false;
|
||||
bool m_game_started = false;
|
||||
bool m_authenticated_game = false;
|
||||
bool m_auth_transition = false;
|
||||
bool m_version_sent = false;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user