mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix movement/warden packet noise and party kill opcode mapping
This commit is contained in:
parent
e3bb2d6744
commit
c6256b1631
9 changed files with 54 additions and 17 deletions
|
|
@ -101,6 +101,7 @@
|
|||
"SMSG_ATTACKSTART": "0x143",
|
||||
"SMSG_ATTACKSTOP": "0x144",
|
||||
"SMSG_ATTACKERSTATEUPDATE": "0x14A",
|
||||
"SMSG_PARTYKILLLOG": "0x1F5",
|
||||
"SMSG_SPELLNONMELEEDAMAGELOG": "0x250",
|
||||
"SMSG_SPELLHEALLOG": "0x150",
|
||||
"SMSG_SPELLENERGIZELOG": "0x151",
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@
|
|||
"SMSG_ATTACKSTART": "0x143",
|
||||
"SMSG_ATTACKSTOP": "0x144",
|
||||
"SMSG_ATTACKERSTATEUPDATE": "0x14A",
|
||||
"SMSG_PARTYKILLLOG": "0x1F5",
|
||||
"SMSG_SPELLNONMELEEDAMAGELOG": "0x250",
|
||||
"SMSG_SPELLHEALLOG": "0x150",
|
||||
"SMSG_SPELLENERGIZELOG": "0x151",
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
"SMSG_ACCOUNT_DATA_TIMES": "0x209",
|
||||
"SMSG_UPDATE_OBJECT": "0x0A9",
|
||||
"SMSG_COMPRESSED_UPDATE_OBJECT": "0x1F6",
|
||||
"SMSG_UNKNOWN_1F5": "0x1F5",
|
||||
"SMSG_PARTYKILLLOG": "0x1F5",
|
||||
"SMSG_MONSTER_MOVE_TRANSPORT": "0x2AE",
|
||||
"SMSG_SPLINE_MOVE_SET_WALK_MODE": "0x30E",
|
||||
"SMSG_SPLINE_MOVE_SET_RUN_MODE": "0x30D",
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@
|
|||
"SMSG_ATTACKSTART": "0x143",
|
||||
"SMSG_ATTACKSTOP": "0x144",
|
||||
"SMSG_ATTACKERSTATEUPDATE": "0x14A",
|
||||
"SMSG_PARTYKILLLOG": "0x1F5",
|
||||
"SMSG_SPELLNONMELEEDAMAGELOG": "0x250",
|
||||
"SMSG_SPELLHEALLOG": "0x150",
|
||||
"SMSG_SPELLENERGIZELOG": "0x151",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <map>
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
namespace wowee::game {
|
||||
class TransportManager;
|
||||
|
|
@ -1237,6 +1238,8 @@ private:
|
|||
// Movement
|
||||
MovementInfo movementInfo; // Current player movement state
|
||||
uint32_t movementTime = 0; // Movement timestamp counter
|
||||
std::chrono::steady_clock::time_point movementClockStart_ = std::chrono::steady_clock::now();
|
||||
uint32_t lastMovementTimestampMs_ = 0;
|
||||
bool serverMovementAllowed_ = true;
|
||||
|
||||
// Inventory
|
||||
|
|
@ -1518,6 +1521,7 @@ private:
|
|||
std::unordered_map<uint32_t, uint32_t> taxiCostMap_; // destNodeId -> total cost in copper
|
||||
void buildTaxiCostMap();
|
||||
void applyTaxiMountForCurrentNode();
|
||||
uint32_t nextMovementTimestampMs();
|
||||
void sanitizeMovementForTaxi();
|
||||
void startClientTaxiPath(const std::vector<uint32_t>& pathNodes);
|
||||
void updateClientTaxi(float deltaTime);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ enum class LogicalOpcode : uint16_t {
|
|||
// ---- Entity/Object updates ----
|
||||
SMSG_UPDATE_OBJECT,
|
||||
SMSG_COMPRESSED_UPDATE_OBJECT,
|
||||
SMSG_UNKNOWN_1F5,
|
||||
SMSG_MONSTER_MOVE_TRANSPORT,
|
||||
SMSG_SPLINE_MOVE_SET_WALK_MODE,
|
||||
SMSG_SPLINE_MOVE_SET_RUN_MODE,
|
||||
|
|
@ -226,6 +225,7 @@ enum class LogicalOpcode : uint16_t {
|
|||
CMSG_GROUP_DISBAND,
|
||||
SMSG_GROUP_LIST,
|
||||
SMSG_PARTY_COMMAND_RESULT,
|
||||
SMSG_PARTYKILLLOG,
|
||||
MSG_RAID_TARGET_UPDATE,
|
||||
CMSG_REQUEST_RAID_INFO,
|
||||
SMSG_RAID_INSTANCE_INFO,
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ void AuthHandler::handleRealmListResponse(network::Packet& packet) {
|
|||
|
||||
void AuthHandler::handlePacket(network::Packet& packet) {
|
||||
if (packet.getSize() < 1) {
|
||||
LOG_WARNING("Received empty packet");
|
||||
LOG_DEBUG("Received empty auth packet (ignored)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1004,7 +1004,7 @@ void GameHandler::update(float deltaTime) {
|
|||
|
||||
void GameHandler::handlePacket(network::Packet& packet) {
|
||||
if (packet.getSize() < 1) {
|
||||
LOG_WARNING("Received empty packet");
|
||||
LOG_DEBUG("Received empty world packet (ignored)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1249,11 +1249,6 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
handleCompressedUpdateObject(packet);
|
||||
}
|
||||
break;
|
||||
case Opcode::SMSG_UNKNOWN_1F5:
|
||||
// Observed custom server packet (16 bytes). Consume safely for stream alignment.
|
||||
packet.setReadPos(packet.getSize());
|
||||
break;
|
||||
|
||||
case Opcode::SMSG_DESTROY_OBJECT:
|
||||
// Can be received after entering world
|
||||
if (state == WorldState::IN_WORLD) {
|
||||
|
|
@ -1565,6 +1560,11 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
case Opcode::SMSG_PARTY_COMMAND_RESULT:
|
||||
handlePartyCommandResult(packet);
|
||||
break;
|
||||
case Opcode::SMSG_PARTYKILLLOG:
|
||||
// Classic-era packet: killer GUID + victim GUID.
|
||||
// XP and combat state are handled by other packets; consume to avoid warning spam.
|
||||
packet.setReadPos(packet.getSize());
|
||||
break;
|
||||
|
||||
// ---- Guild ----
|
||||
case Opcode::SMSG_GUILD_INFO:
|
||||
|
|
@ -2986,7 +2986,9 @@ void GameHandler::handleLoginVerifyWorld(network::Packet& packet) {
|
|||
movementInfo.orientation = core::coords::serverToCanonicalYaw(data.orientation);
|
||||
movementInfo.flags = 0;
|
||||
movementInfo.flags2 = 0;
|
||||
movementInfo.time = 0;
|
||||
movementClockStart_ = std::chrono::steady_clock::now();
|
||||
lastMovementTimestampMs_ = 0;
|
||||
movementInfo.time = nextMovementTimestampMs();
|
||||
resurrectPending_ = false;
|
||||
resurrectRequestPending_ = false;
|
||||
onTaxiFlight_ = false;
|
||||
|
|
@ -3991,6 +3993,28 @@ void GameHandler::handlePong(network::Packet& packet) {
|
|||
LOG_DEBUG("Heartbeat acknowledged (sequence: ", data.sequence, ")");
|
||||
}
|
||||
|
||||
uint32_t GameHandler::nextMovementTimestampMs() {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
uint64_t elapsed = static_cast<uint64_t>(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now - movementClockStart_).count()) + 1ULL;
|
||||
if (elapsed > std::numeric_limits<uint32_t>::max()) {
|
||||
movementClockStart_ = now;
|
||||
elapsed = 1ULL;
|
||||
}
|
||||
|
||||
uint32_t candidate = static_cast<uint32_t>(elapsed);
|
||||
if (candidate <= lastMovementTimestampMs_) {
|
||||
candidate = lastMovementTimestampMs_ + 1U;
|
||||
if (candidate == 0) {
|
||||
movementClockStart_ = now;
|
||||
candidate = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
lastMovementTimestampMs_ = candidate;
|
||||
return candidate;
|
||||
}
|
||||
|
||||
void GameHandler::sendMovement(Opcode opcode) {
|
||||
if (state != WorldState::IN_WORLD) {
|
||||
LOG_WARNING("Cannot send movement in state: ", (int)state);
|
||||
|
|
@ -4009,11 +4033,8 @@ void GameHandler::sendMovement(Opcode opcode) {
|
|||
if ((onTaxiFlight_ || taxiMountActive_) && !taxiAllowed) return;
|
||||
if (resurrectPending_ && !taxiAllowed) return;
|
||||
|
||||
// Use real millisecond timestamp (server validates for anti-cheat)
|
||||
static auto startTime = std::chrono::steady_clock::now();
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
movementInfo.time = static_cast<uint32_t>(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now - startTime).count());
|
||||
// Always send a strictly increasing non-zero client movement clock value.
|
||||
movementInfo.time = nextMovementTimestampMs();
|
||||
|
||||
// Update movement flags based on opcode
|
||||
switch (opcode) {
|
||||
|
|
@ -7831,6 +7852,11 @@ void GameHandler::handleForceRunSpeedChange(network::Packet& packet) {
|
|||
ack.writeUInt32(counter);
|
||||
|
||||
MovementInfo wire = movementInfo;
|
||||
wire.time = nextMovementTimestampMs();
|
||||
if (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
||||
wire.transportTime = wire.time;
|
||||
wire.transportTime2 = wire.time;
|
||||
}
|
||||
glm::vec3 serverPos = core::coords::canonicalToServer(glm::vec3(wire.x, wire.y, wire.z));
|
||||
wire.x = serverPos.x;
|
||||
wire.y = serverPos.y;
|
||||
|
|
@ -7842,7 +7868,11 @@ void GameHandler::handleForceRunSpeedChange(network::Packet& packet) {
|
|||
wire.transportY = serverTransport.y;
|
||||
wire.transportZ = serverTransport.z;
|
||||
}
|
||||
MovementPacket::writeMovementPayload(ack, wire);
|
||||
if (packetParsers_) {
|
||||
packetParsers_->writeMovementPayload(ack, wire);
|
||||
} else {
|
||||
MovementPacket::writeMovementPayload(ack, wire);
|
||||
}
|
||||
|
||||
ack.writeFloat(newSpeed);
|
||||
socket->send(ack);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ static const OpcodeNameEntry kOpcodeNames[] = {
|
|||
{"SMSG_NOTIFICATION", LogicalOpcode::SMSG_NOTIFICATION},
|
||||
{"SMSG_UPDATE_OBJECT", LogicalOpcode::SMSG_UPDATE_OBJECT},
|
||||
{"SMSG_COMPRESSED_UPDATE_OBJECT", LogicalOpcode::SMSG_COMPRESSED_UPDATE_OBJECT},
|
||||
{"SMSG_UNKNOWN_1F5", LogicalOpcode::SMSG_UNKNOWN_1F5},
|
||||
{"SMSG_MONSTER_MOVE_TRANSPORT", LogicalOpcode::SMSG_MONSTER_MOVE_TRANSPORT},
|
||||
{"SMSG_SPLINE_MOVE_SET_WALK_MODE", LogicalOpcode::SMSG_SPLINE_MOVE_SET_WALK_MODE},
|
||||
{"SMSG_SPLINE_MOVE_SET_RUN_MODE", LogicalOpcode::SMSG_SPLINE_MOVE_SET_RUN_MODE},
|
||||
|
|
@ -185,6 +184,7 @@ static const OpcodeNameEntry kOpcodeNames[] = {
|
|||
{"CMSG_GROUP_DISBAND", LogicalOpcode::CMSG_GROUP_DISBAND},
|
||||
{"SMSG_GROUP_LIST", LogicalOpcode::SMSG_GROUP_LIST},
|
||||
{"SMSG_PARTY_COMMAND_RESULT", LogicalOpcode::SMSG_PARTY_COMMAND_RESULT},
|
||||
{"SMSG_PARTYKILLLOG", LogicalOpcode::SMSG_PARTYKILLLOG},
|
||||
{"MSG_RAID_TARGET_UPDATE", LogicalOpcode::MSG_RAID_TARGET_UPDATE},
|
||||
{"CMSG_REQUEST_RAID_INFO", LogicalOpcode::CMSG_REQUEST_RAID_INFO},
|
||||
{"SMSG_RAID_INSTANCE_INFO", LogicalOpcode::SMSG_RAID_INSTANCE_INFO},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue