完善客户端功能并同步差距文档
This commit is contained in:
@@ -271,6 +271,9 @@ bool ClassicParser::on_gc(uint8_t header, const uint8_t *body, uint32_t len) {
|
||||
(float)p.z, p.angle, p.moving_speed, p.attack_speed);
|
||||
m_world.mut_char_info(p.vid, {}, p.parts, p.empire, (int32_t)p.guild, 0,
|
||||
p.alignment, p.pk_mode, p.mount_vnum);
|
||||
// §2.5 (W1↔W2 G1 wiring): affect flags travel in their own two-word
|
||||
// segment, not through mut_char_info.
|
||||
m_world.mut_affect_flags(p.vid, p.affect_flag[0], p.affect_flag[1]);
|
||||
return true;
|
||||
}
|
||||
case HDR_GC_CHARACTER_DEL: { // 2
|
||||
@@ -286,9 +289,11 @@ bool ClassicParser::on_gc(uint8_t header, const uint8_t *body, uint32_t len) {
|
||||
if (!fill(p, header, body, len)) {
|
||||
return false;
|
||||
}
|
||||
// classic wire heading: deg = bRot * 5 (client NetStream Send/Recv Move)
|
||||
// classic wire heading: deg = bRot * 5 (client NetStream Send/Recv Move).
|
||||
// §3.2: p.arg is the motion index, p.time the server command time that
|
||||
// gates when the queued state command is released.
|
||||
m_world.mut_move(p.vid, (float)p.rot * 5.0f, p.func, (float)p.x, (float)p.y,
|
||||
p.duration);
|
||||
p.duration, p.arg, p.time);
|
||||
return true;
|
||||
}
|
||||
case HDR_GC_CHARACTER_POINTS: { // 16
|
||||
@@ -367,6 +372,8 @@ bool ClassicParser::on_gc(uint8_t header, const uint8_t *body, uint32_t len) {
|
||||
}
|
||||
m_world.mut_char_update(p.vid, p.parts, p.moving_speed, p.attack_speed,
|
||||
(int32_t)p.guild_id, p.alignment, p.pk_mode, p.mount_vnum);
|
||||
// §2.5 (W1↔W2 G1 wiring): mut_char_update carries no affect segment.
|
||||
m_world.mut_affect_flags(p.vid, p.affect_flag[0], p.affect_flag[1]);
|
||||
return true;
|
||||
}
|
||||
case HDR_GC_CHARACTER_POSITION: { // 43
|
||||
@@ -687,9 +694,16 @@ bool ClassicParser::on_gc(uint8_t header, const uint8_t *body, uint32_t len) {
|
||||
m_world.mut_exchange_start(p.arg1);
|
||||
break;
|
||||
case EXCHANGE_GC_ITEM_ADD:
|
||||
{
|
||||
ItemAttr attrs[ITEM_ATTRIBUTE_MAX_NUM]{};
|
||||
for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i) {
|
||||
attrs[i].type = p.attrs[i].type;
|
||||
attrs[i].value = p.attrs[i].value;
|
||||
}
|
||||
m_world.mut_exchange_item(self, static_cast<uint8_t>(p.arg2.cell), p.arg1,
|
||||
static_cast<uint8_t>(p.arg3));
|
||||
static_cast<uint8_t>(p.arg3), p.sockets, attrs);
|
||||
break;
|
||||
}
|
||||
case EXCHANGE_GC_ITEM_DEL:
|
||||
m_world.mut_exchange_item_del(self, static_cast<uint8_t>(p.arg1));
|
||||
break;
|
||||
|
||||
@@ -301,6 +301,10 @@ void ClassicSession::pump() {
|
||||
set_stage(Stage::Failed);
|
||||
}
|
||||
}
|
||||
// §3.2 — feed the server frame clock (from the GC_HANDSHAKE lDelta exchange)
|
||||
// so EntityStore::drain_state_queue() gates queued StateCmds on server time
|
||||
// instead of releasing immediately. 0 until the first handshake lands.
|
||||
m_world.set_server_frame_ms(m_stream.server_frame_ms());
|
||||
m_world.tick();
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,16 @@ void ClassicStream::set_state(State s) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ClassicStream::server_frame_ms() const {
|
||||
// §3.2 — mirror EterLib ELTimer_GetServerFrameMSec(): the handshake stored
|
||||
// (m_server_time_base, m_client_time_base); the server clock advances with
|
||||
// local wall time from there. 0 until the first handshake lands.
|
||||
if (m_client_time_base == 0) {
|
||||
return 0;
|
||||
}
|
||||
return now_ms() - m_client_time_base + m_server_time_base;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------- socket
|
||||
bool ClassicStream::connect(const std::string &host, uint16_t port) {
|
||||
disconnect();
|
||||
|
||||
@@ -99,6 +99,14 @@ public:
|
||||
bool cipher_active() const { return m_cipher.activated(); }
|
||||
void set_polarity(bool client) { m_polarity = client; }
|
||||
|
||||
// §3.2 — ELTimer_GetServerFrameMSec() equivalent. The GC_HANDSHAKE exchange
|
||||
// (handle_control HDR_HANDSHAKE) stores m_server_time_base = hs.time + lDelta
|
||||
// and m_client_time_base = local now; the server frame clock is then
|
||||
// local_now - m_client_time_base + m_server_time_base. Returns 0 until the
|
||||
// first handshake has landed (EntityStore treats 0 as "release immediately").
|
||||
uint32_t server_frame_ms() const;
|
||||
bool has_server_clock() const { return m_client_time_base != 0; }
|
||||
|
||||
private:
|
||||
void set_state(State s);
|
||||
bool recv_into_buffer();
|
||||
|
||||
Reference in New Issue
Block a user