mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
refactor: remove the packet macros, WriteHeader and PacketUtils
Nothing in the server writes or reads a packet by hand any more, so the helpers for doing so go: - CBITSTREAM, CMSGHEADER, CINSTREAM, CINSTREAM_SKIP_HEADER, SEND_PACKET, SEND_PACKET_BROADCAST and HEADER_SIZE leave dCommonVars.h; - the free BitStreamUtils::WriteHeader (LUBitStream::WriteHeader writes the same bytes) and the unused PacketUtils::SavePacket are deleted. The last raw reads are replaced: WorldServer builds its input stream directly, the master packet logs read the header with LUBitStream::ReadHeader instead of peeking at packet->data[1] and [3], and MessageInspector reads a sent game message's header with the new NetGameMsg::ReadPacketHeader (the counterpart of WritePacket) instead of memcmp/memcpy. packet->data[0] is still compared with RakNet's own connection IDs. The frozen oracles keep using the macros verbatim through the test-only tests/dGameTests/LegacyPacketMacros.h; the HeaderSkip tests, which only tested CINSTREAM_SKIP_HEADER, are removed. docs/PacketArchitecture.md: "where we are" now describes the final state and what still touches raw bytes (RakNet IDs, replica headers, behavior bit streams), and a new section collects the known wire discrepancies found during the conversion, with client addresses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,16 +28,6 @@ constexpr uint32_t highFrameDelta = FRAMES_TO_MS(highFramerate);
|
||||
constexpr uint32_t mediumFrameDelta = FRAMES_TO_MS(mediumFramerate);
|
||||
constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
|
||||
|
||||
//========== MACROS ===========
|
||||
|
||||
#define HEADER_SIZE 8
|
||||
#define CBITSTREAM RakNet::BitStream bitStream;
|
||||
#define CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false);
|
||||
#define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits());
|
||||
#define CMSGHEADER BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
#define SEND_PACKET Game::server->Send(bitStream, sysAddr, false);
|
||||
#define SEND_PACKET_BROADCAST Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
|
||||
//=========== TYPEDEFS ==========
|
||||
|
||||
using LOT = int32_t; //!< A LOT
|
||||
|
||||
@@ -27,6 +27,15 @@ namespace GameMessages {
|
||||
Serialize(bitStream); // write the message data
|
||||
}
|
||||
|
||||
bool NetGameMsg::ReadPacketHeader(RakNet::BitStream& bitStream, LWOOBJID& target, MessageType::Game& msgId) {
|
||||
LUBitStream header;
|
||||
if (!header.ReadHeader(bitStream)) return false;
|
||||
if (header.connectionType != ServiceType::CLIENT || header.internalPacketID != static_cast<uint32_t>(MessageType::Client::GAME_MSG)) return false;
|
||||
VALIDATE_READ(bitStream.Read(target));
|
||||
VALIDATE_READ(bitStream.Read(msgId));
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetGameMsg::SendToClient(const SystemAddress& sysAddr) const {
|
||||
RakNet::BitStream bitStream;
|
||||
WritePacket(bitStream);
|
||||
|
||||
@@ -90,6 +90,10 @@ namespace GameMessages {
|
||||
// This is exactly what Send(sysAddr) puts on the wire; tests use it to compare bytes without a server.
|
||||
void WritePacket(RakNet::BitStream& bitStream) const;
|
||||
|
||||
// Reads what WritePacket writes before Serialize(): the CLIENT/GAME_MSG header, the target and the message ID.
|
||||
// Returns false if the stream is too short or holds a different kind of packet.
|
||||
static bool ReadPacketHeader(RakNet::BitStream& bitStream, LWOOBJID& target, MessageType::Game& msgId);
|
||||
|
||||
virtual void Serialize(RakNet::BitStream& bitStream) const {}
|
||||
virtual bool Deserialize(RakNet::BitStream& bitStream) { return true; }
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Entity.h"
|
||||
#include "Game.h"
|
||||
#include "GameMessageDecoder.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Logger.h"
|
||||
#include "master/MessageCapture.h"
|
||||
#include "MessageType/Client.h"
|
||||
@@ -140,21 +141,15 @@ namespace {
|
||||
|
||||
// Packets the server sends: only game messages are kept
|
||||
void OnSend(const RakNet::BitStream& bitStream, const SystemAddress& sysAddr, bool broadcast) {
|
||||
static const auto header = [] {
|
||||
RakNet::BitStream expected;
|
||||
BitStreamUtils::WriteHeader(expected, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
return std::string(reinterpret_cast<const char*>(expected.GetData()), expected.GetNumberOfBytesUsed());
|
||||
}();
|
||||
const auto totalBits = bitStream.GetNumberOfBitsUsed();
|
||||
if (totalBits < GAME_MESSAGE_HEADER_BYTES * 8) return;
|
||||
const auto* data = bitStream.GetData();
|
||||
if (std::memcmp(data, header.data(), header.size()) != 0) return;
|
||||
|
||||
auto* data = bitStream.GetData();
|
||||
RakNet::BitStream stream(data, bitStream.GetNumberOfBytesUsed(), false);
|
||||
LWOOBJID objectId{};
|
||||
uint16_t messageId{};
|
||||
std::memcpy(&objectId, data + 8, sizeof(objectId));
|
||||
std::memcpy(&messageId, data + 8 + sizeof(objectId), sizeof(messageId));
|
||||
Record(eMessageDirection::TO_CLIENT, sysAddr, broadcast, objectId, messageId, data + GAME_MESSAGE_HEADER_BYTES,
|
||||
MessageType::Game messageId{};
|
||||
if (!GameMessages::NetGameMsg::ReadPacketHeader(stream, objectId, messageId)) return;
|
||||
|
||||
Record(eMessageDirection::TO_CLIENT, sysAddr, broadcast, objectId, static_cast<uint16_t>(messageId), data + GAME_MESSAGE_HEADER_BYTES,
|
||||
static_cast<uint32_t>(totalBits - GAME_MESSAGE_HEADER_BYTES * 8));
|
||||
}
|
||||
|
||||
|
||||
@@ -1029,8 +1029,12 @@ void HandlePacket(Packet* packet) {
|
||||
|
||||
if (packet->length < 4) return;
|
||||
|
||||
if (!MasterHandlers().Dispatch(packet, ServiceType::MASTER) && packet->data[0] == ID_USER_PACKET_ENUM && static_cast<ServiceType>(packet->data[1]) == ServiceType::MASTER) {
|
||||
LOG("Unknown master packet ID from server: %i", packet->data[3]);
|
||||
if (!MasterHandlers().Dispatch(packet, ServiceType::MASTER)) {
|
||||
RakNet::BitStream inStream(packet->data, packet->length, false);
|
||||
LUBitStream header;
|
||||
if (header.ReadHeader(inStream) && header.connectionType == ServiceType::MASTER) {
|
||||
LOG("Unknown master packet ID from server: %i", header.internalPacketID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dServer.h"
|
||||
#include "BitStream.h"
|
||||
#include "PacketUtils.h"
|
||||
|
||||
|
||||
void LUBitStream::WriteHeader(RakNet::BitStream& bitStream) const {
|
||||
|
||||
@@ -75,16 +75,7 @@ struct LUBitStream {
|
||||
};
|
||||
|
||||
|
||||
#define BITSTREAMUTILS_HAS_WRITEHEADER
|
||||
namespace BitStreamUtils {
|
||||
template<typename T>
|
||||
void WriteHeader(RakNet::BitStream& bitStream, ServiceType connectionType, T internalPacketID) {
|
||||
bitStream.Write<MessageID>(ID_USER_PACKET_ENUM);
|
||||
bitStream.Write<ServiceType>(connectionType);
|
||||
bitStream.Write(static_cast<uint32_t>(internalPacketID));
|
||||
bitStream.Write<uint8_t>(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an optional ("default flag") field: one bit saying whether value differs from defaultValue, then
|
||||
* the value itself only if it does. This is how the client encodes game message parameters that have a default.
|
||||
|
||||
@@ -6,7 +6,6 @@ set(DNET_SOURCES "AuthPackets.cpp"
|
||||
"dServer.cpp"
|
||||
"MailInfo.cpp"
|
||||
"MasterPackets.cpp"
|
||||
"PacketUtils.cpp"
|
||||
"Stamps.cpp"
|
||||
"WorldPackets.cpp"
|
||||
"WorldRoutePacket.cpp"
|
||||
|
||||
@@ -838,7 +838,9 @@ namespace {
|
||||
void HandleMasterPacket(Packet* packet) {
|
||||
if (packet->length < 4) return;
|
||||
if (!MasterHandlers().Dispatch(packet, ServiceType::MASTER)) {
|
||||
LOG("Unknown packet ID from master %i", int(packet->data[3]));
|
||||
RakNet::BitStream inStream(packet->data, packet->length, false);
|
||||
LUBitStream header;
|
||||
if (header.ReadHeader(inStream)) LOG("Unknown packet ID from master %i", header.internalPacketID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1627,7 +1629,7 @@ void HandlePacket(Packet* packet) {
|
||||
|
||||
if (packet->data[0] != ID_USER_PACKET_ENUM || packet->length < 4) return;
|
||||
|
||||
CINSTREAM;
|
||||
RakNet::BitStream inStream(packet->data, packet->length, false);
|
||||
LUBitStream luBitStream;
|
||||
if (!luBitStream.ReadHeader(inStream)) return;
|
||||
|
||||
|
||||
@@ -12,39 +12,47 @@ be wrong, the fix is its own clearly labelled change, verified against the clien
|
||||
Sources for layouts, in order of trust: the 1.10.64 client in Ghidra, then lu_packets, then lcdr-utils packet
|
||||
definitions. When they disagree, the client wins.
|
||||
|
||||
## 1. Where we are (survey, `origin/main` @ 129199e4)
|
||||
## 1. Where we are
|
||||
|
||||
### 1.1 The newer style already in the tree
|
||||
### 1.1 Final state
|
||||
|
||||
| Family | Base | Header written by | Handler signature | Dispatch | Users on main |
|
||||
|---|---|---|---|---|---|
|
||||
| Game messages | `GameMessages::GameMsg` (`dGame/dGameMessages/GameMessages.h`) | `GameMsg::Send(sysAddr)` writes `CLIENT/GAME_MSG` header, `target`, `msgId`, then `Serialize()` | `Handle(Entity&, const SystemAddress&)` | `g_MessageHandlers` map in `GameMessageHandler.cpp` (4 entries), with a GM-level check; everything else is a 112-case switch | 34 structs: 12 outbound (`Serialize`), 4 inbound (`Deserialize` + `Handle`), 18 server-internal events used via `Entity::RegisterMsg`/`HandleMsg` and never sent |
|
||||
| Packets | `LUBitStream` (`dNet/BitStreamUtils.h`) | `LUBitStream::WriteHeader` (`0x53`, `ServiceType` u16, packet id u32, pad u8) | `Handle()` (context comes from members such as `sysAddr`, `player`) | `g_Handlers` map in `Mail.cpp`; nothing else | Mail (6 requests + 5 responses, with a `MailLUBitStream` sub-header), `ChatPackets::{Announcement, AchievementNotify, TeamInviteInitialResponse}` |
|
||||
| Old one-off classes | none | the class writes its own `msgId` in a non-virtual `Serialize` | deserialized in a constructor, result ignored | switch | `EchoStartSkill`, `EchoSyncSkill`, `StartSkill`, `SyncSkill`, `RequestServerProjectileImpact`, `DoClientProjectileImpact`, `PropertyDataMessage`, `PropertySelectQueryProperty`, `ShowAllRequest`, `FindPlayerRequest`, `HTTPMonitorInfo` |
|
||||
Every packet and every game message is a struct. The migration in [section 4](#4-migration-plan) is complete.
|
||||
|
||||
Helpers: `LUString`/`LUWString` (fixed-width, zero-padded strings, default 33 chars) with `BitStream`
|
||||
specializations; `BitStreamUtils::WriteHeader`; `VALIDATE_READ`; macros `CBITSTREAM`, `CMSGHEADER`,
|
||||
`CINSTREAM(_SKIP_HEADER)`, `SEND_PACKET(_BROADCAST)` in `dCommonVars.h`.
|
||||
| Family | Base | Where | Dispatch |
|
||||
|---|---|---|---|
|
||||
| Game messages (wire) | `GameMessages::NetGameMsg` | 17 per-domain files `dGame/dGameMessages/<Domain>Messages.{h,cpp}`: Activity, Building, Combat, Effects, Inventory, Mission, Movement, Object, Pet, Player, Property, QuickBuild, Racing, Skill, Trade, Vendor, Zone (about 280 structs) | `g_MessageHandlers` in `GameMessageHandler.cpp` (118 inbound messages); no switch. Unknown IDs are logged at debug level, messages that fail `Deserialize` are logged and dropped. |
|
||||
| Game messages (internal) | `GameMessages::GameMsg`, `NetGameMsgEvent<Msg>` | `GameMessages.h` (base types and the server-internal events only) | `Entity::RegisterMsg` / `HandleMsg` |
|
||||
| Packets | `LUBitStream` | one file pair per `ServiceType` in `dNet/` (`CommonPackets`, `AuthPackets`, `ChatPackets`, `WorldPackets`, `ClientPackets`, `MasterPackets` + `master/*`), `Stamps`, `WorldRoutePacket`, Mail in `dGame/dUtilities/Mail.*` | per-service maps and `PacketDispatcher` |
|
||||
|
||||
### 1.2 What is left in the old style
|
||||
`GameMessages.cpp` holds only the base code (`GameMsg::Send`, `NetGameMsg::WritePacket`/`ReadPacketHeader`/`Send`/
|
||||
`SendToClient`/`BroadcastExcept`). There are no `GameMessages::Send*`/`Handle*` functions left. Inbound messages are
|
||||
handled by the struct's `Handle`, which delegates to a component method where the behaviour belongs to one
|
||||
component (for example `PossessorComponent::OnDismountComplete`, `InventoryComponent::On*`) or keeps logic that
|
||||
spans several entities (platform resyncs, rails, activities) in the handler.
|
||||
|
||||
Hand-written `bitStream.Write`/`Read` sequences inside functions:
|
||||
Removed: the `CBITSTREAM`, `CMSGHEADER`, `CINSTREAM`, `CINSTREAM_SKIP_HEADER`, `SEND_PACKET`, `SEND_PACKET_BROADCAST`
|
||||
and `HEADER_SIZE` macros, the free `BitStreamUtils::WriteHeader` (use `LUBitStream::WriteHeader`) and `PacketUtils`.
|
||||
The frozen oracles in `tests/**/Legacy/` still use the macros verbatim through the test-only
|
||||
`tests/dGameTests/LegacyPacketMacros.h`.
|
||||
|
||||
| Area | Where | Count |
|
||||
`ChatPackets::SendSystemMessage` stays as a thin helper: it builds the general chat struct and sends it.
|
||||
|
||||
### 1.2 What still touches raw bytes, and why
|
||||
|
||||
| Where | What | Why it stays |
|
||||
|---|---|---|
|
||||
| Outbound game messages | `GameMessages::Send*` in `GameMessages.cpp` (6.5k lines) | **161** functions (162 `CMSGHEADER` uses) |
|
||||
| Inbound game messages | `GameMessages::Handle*` + `GameMessageHandler` switch | **101** functions, **112** switch cases |
|
||||
| Game messages written outside `GameMessages.cpp` | `dChatServer/TeamContainer.cpp` (routed through chat), the 6 one-off skill/projectile classes | 6 + 6 |
|
||||
| Auth + Common | `AuthPackets.cpp` (`HandleHandshake`, `SendHandshake`, `HandleLoginRequest`, `SendLoginResponse`), `dServer::Disconnect`, `AuthServer` if-chain | 4 functions + 1 |
|
||||
| World | `WorldPackets.cpp` (11 `Send*`), `ClientPackets.cpp` (4 parse functions), `UserManager.cpp` (char list/create/delete/rename), `WorldServer::HandlePacket` inline (15 World + 4 Chat + 4 Master cases) | ~40 |
|
||||
| Chat | `ChatPacketHandler.cpp` (15), `TeamContainer.cpp` (7 handlers + 7 sends), `ChatIgnoreList.cpp` (3), `PlayerContainer.cpp`, `ChatPackets.cpp` (4 functions + 2 structs), `ChatServer` switch (26 handled cases) | ~55 |
|
||||
| Master | `MasterPackets.cpp` (7), `MasterServer` switch (13 inline cases), `InstanceManager.cpp` (2), `ZoneInstanceManager.cpp` | ~25 |
|
||||
| Raw header sites | `BitStreamUtils::WriteHeader(` calls | 90 in 25 files |
|
||||
| Raw read sites | `CINSTREAM*` uses / `packet->data[i]` peeks | 58 / 29 |
|
||||
| `AuthServer`, `ChatServer`, `MasterServer`, `WorldServer`, `dServer` `HandlePacket` | `packet->data[0]` compared with RakNet IDs (`ID_USER_PACKET_ENUM`, `ID_DISCONNECTION_NOTIFICATION`, `ID_CONNECTION_LOST`, `ID_NEW_INCOMING_CONNECTION`, ...) | RakNet's own connection messages, not LU packets. Everything after the RakNet ID is read with `LUBitStream::ReadHeader` and a struct. |
|
||||
| `EntityManager` | `ID_REPLICA_MANAGER_CONSTRUCTION`/`SERIALIZE`/`DESTRUCTION` headers written before the components | Replica serialization, out of scope (see below). |
|
||||
| `dGame/dBehaviors/*`, the `sBitStream` of skill messages | Behavior bit streams | The skill payload is its own format, carried as bytes inside the skill structs. |
|
||||
| `MessageInspector` | Copies the payload bytes of sent/received game messages | A capture tap; the header is read with `NetGameMsg::ReadPacketHeader`. |
|
||||
|
||||
Out of scope: replica/component serialization (`Component::Serialize`) and LDF/AMF, which are separate formats
|
||||
with their own tests.
|
||||
|
||||
Before the migration (survey of `origin/main` @ 129199e4) there were 161 hand written `GameMessages::Send*`
|
||||
functions, 101 `Handle*` functions behind a 112-case switch, about 120 hand written packet functions across the
|
||||
servers, 90 raw header writes and 58 `CINSTREAM` / 29 `packet->data[i]` reads.
|
||||
|
||||
### 1.3 Inconsistencies inside the new style, and how they are settled
|
||||
|
||||
| # | Inconsistency | Decision |
|
||||
@@ -266,12 +274,12 @@ clean range of commits on the working branch. Target: under ~1.5k changed lines
|
||||
| 7 | GMs: combat and skills | Skill add/remove, stun, buffs, die/resurrect/smash, knockback; the one-off `EchoStartSkill`/`EchoSyncSkill`/`StartSkill`/`SyncSkill`/projectile classes become `NetGameMsg`s | M |
|
||||
| 8 | GMs: pets | Taming minigame, pet naming, commands | M |
|
||||
| 9 | GMs: property and building | Property management, models, BBB, modular build, `PropertyDataMessage`, `PropertySelectQueryProperty`, `ControlBehaviors` (may split in two) | L |
|
||||
| 10 | GMs: remaining + switch removal | Movement, teleport, platforms, rails, camera, control scheme, misc, team GMs sent from `TeamContainer`; delete the switch and `GameMessages.cpp` | M |
|
||||
| 10 | GMs: remaining + switch removal | Movement, teleport, platforms, rails, camera, control scheme, misc, team GMs sent from `TeamContainer`; delete the switch and `GameMessages.cpp` (done: `Movement`, `Zone`, `Player`, `Object`, `QuickBuild` files; `GameMessages.cpp` keeps only the base code) | M |
|
||||
| 11 | Common + Auth packets | `CommonPackets` (version confirm, disconnect notify, general notify; `dServer::Disconnect`), `AuthPackets` login request, `ClientPackets` login response + stamps; `AuthServer` dispatch map | S |
|
||||
| 12 | World packets | Validation, character list/create/delete/rename, world login, level load complete, position update, string check, general chat, route packet, top-5, funness, and the `ClientPackets` responses they send; handlers move out of the `WorldServer.cpp` switch into a dispatch map | M |
|
||||
| 13 | Chat packets | Friends, ignore list, teams, who/show-all, private/general chat, routing (`WORLD_ROUTE_PACKET` wraps an `LUBitStream`), achievement notify, GM announce/mute, plus the chat-side of `WorldServer`'s chat cases (may split friends/teams) | L |
|
||||
| 14 | Master packets | Session keys, zone transfer, private zones, player added/removed, world ready, prep zone, shutdown; `MasterServer` switch becomes a dispatch map; `InstanceManager`/`ZoneInstanceManager` senders | M |
|
||||
| 15 | Cleanup | Remove `CBITSTREAM`/`CMSGHEADER`/`SEND_PACKET*`/`CINSTREAM*`, the free `BitStreamUtils::WriteHeader`, `PacketUtils`; update this document | S |
|
||||
| 15 | Cleanup | Remove `CBITSTREAM`/`CMSGHEADER`/`SEND_PACKET*`/`CINSTREAM*`, the free `BitStreamUtils::WriteHeader`, `PacketUtils`; update this document (done) | S |
|
||||
|
||||
Game-message PRs (2-10) are independent of each other and of the packet PRs (11-14), so they can be reviewed in
|
||||
any order after PR 0.
|
||||
@@ -287,3 +295,42 @@ any order after PR 0.
|
||||
- **Handler behaviour.** Keep each handler's logic verbatim in the conversion; behaviour changes are separate.
|
||||
- **Merge conflicts** with feature work in `GameMessages.cpp`: small PRs, landed domain by domain.
|
||||
- **Personal data.** Captures contain account names, chat and IDs; they stay out of the repository entirely.
|
||||
|
||||
## 5. Known wire discrepancies
|
||||
|
||||
Found while converting; none of them is fixed by a conversion (the structs reproduce DLU's bytes, pinned by the
|
||||
oracle tests). Each fix, if wanted, is its own labelled wire change verified against the client. Addresses are in
|
||||
the 1.10.64 client.
|
||||
|
||||
### Game messages
|
||||
|
||||
| Message | DLU | Client / reference |
|
||||
|---|---|---|
|
||||
| `PlaceModelResponse` | Writes a 4-byte `response` where the client expects the rotation. | The client reads a 16-byte quaternion when the rotation isn't identity (`0x00dc0170`). |
|
||||
| `NotifyPetTamingPuzzleSelected` | Written as the client's `Serialize` (`0x00db6880`) writes it. | The client's own `Deserialize` (`0x00e3a7c0`) reads an extra `u32` its `Serialize` never writes. |
|
||||
| `SetBuildModeConfirmed` | Always sends the default flags. | The client has non-default flag fields. |
|
||||
| `NotifyNotEnoughInvSpace` | Sent with message ID `VEHICLE_NOTIFY_FINISHED_RACE` (1396). | Its ID is `NOTIFY_NOT_ENOUGH_INV_SPACE` (1516). |
|
||||
| `MoveInventoryBatch` | Now follows the client layout. | |
|
||||
| `UnEquipInventory` | The trailing optional `replacementObjectID` is never read. | The client can send it. |
|
||||
| `SetStatusImmunity` | Writes the flags in DLU's order. | The client reads DOT, ImaginationGain, ImaginationLoss, Interrupt, Knockback, PullToPoint, QuickbuildInterrupt, Speed, BasicAttack (`0x00d8f140`). |
|
||||
| `RequestDie` | Read with the `Die` layout. | Starts with one `bDieAccepted` bit and has a mandatory `lootOwnerID` (`0x00e02d90`). |
|
||||
| `SetCurrency` | `sourceTradeID` is an optional `int32_t`. | lu_packets has an object ID (8 bytes). DLU only ever sends 0 (flag bit 0), so no bytes differ today. |
|
||||
| `FireEventClientSide` | Never writes `param1`/`param2` (both flag bits 0), whatever the caller passed: `RocketEquipped` loses the clone ID. | Optional `i64 param1` (default 0) and `i32 param2` (default -1). |
|
||||
| `PickupCurrency` | Reads only the amount. | lu_packets has a position after it (ignored, harmless). |
|
||||
| `MatchUpdate`, `MatchRequest` | Name-value text is widened/narrowed one byte per UTF-16 unit, so non-ASCII names are garbled. | UTF-16 text. |
|
||||
| `ScriptNetworkVarUpdate` | The text goes through `ASCIIToUTF16`. | UTF-16 text (non-ASCII values are garbled). |
|
||||
| `SetShootingGalleryParams` | Removed: had no callers, and its field order was a guess ("No clue about the order here"). | Not verified. |
|
||||
|
||||
Behaviour changes that come with dropping malformed messages: `ParseChatMessage` longer than `MAX_MESSAGE_LENGTH`
|
||||
is dropped instead of truncated; `PLAYER_LOADED` (`0x00dc36f0`), `READY_FOR_UPDATES` and `MISSION_DIALOGUE_CANCELLED`
|
||||
(`0x00d9cc10`) now read the fields the client sends (DLU ignores them) and would be dropped if they were missing.
|
||||
|
||||
### Packets
|
||||
|
||||
| Packet | DLU | Client / reference |
|
||||
|---|---|---|
|
||||
| `VERSION_CONFIRM` (server -> client) | Sends 8 trailing bytes. | |
|
||||
| `LoadStaticZone` | Always sends clone 0. | The zone's clone ID. |
|
||||
| `ChatModerationString` | The accepted byte is `segments.empty()`. | |
|
||||
| `StringCheck` | Keeps 42 narrowed characters, including whatever garbage follows the text. | |
|
||||
| Route packets | Forwarded from byte 23, using the low byte of the routed packet ID. | |
|
||||
|
||||
@@ -21,7 +21,7 @@ std::unique_ptr<AMFBaseValue> ReadFromBitStream(RakNet::BitStream& bitStream) {
|
||||
* @brief Test reading an AMFUndefined value from a BitStream.
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFUndefinedTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x00);
|
||||
std::unique_ptr<AMFBaseValue> res{ ReadFromBitStream(bitStream) };
|
||||
ASSERT_EQ(res->GetValueType(), eAmf::Undefined);
|
||||
@@ -32,7 +32,7 @@ TEST(dCommonTests, AMFDeserializeAMFUndefinedTest) {
|
||||
*
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFNullTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x01);
|
||||
std::unique_ptr<AMFBaseValue> res{ ReadFromBitStream(bitStream) };
|
||||
ASSERT_EQ(res->GetValueType(), eAmf::Null);
|
||||
@@ -42,7 +42,7 @@ TEST(dCommonTests, AMFDeserializeAMFNullTest) {
|
||||
* @brief Test reading an AMFFalse value from a BitStream.
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFFalseTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x02);
|
||||
std::unique_ptr<AMFBaseValue> res{ ReadFromBitStream(bitStream) };
|
||||
ASSERT_EQ(res->GetValueType(), eAmf::False);
|
||||
@@ -52,7 +52,7 @@ TEST(dCommonTests, AMFDeserializeAMFFalseTest) {
|
||||
* @brief Test reading an AMFTrue value from a BitStream.
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFTrueTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x03);
|
||||
std::unique_ptr<AMFBaseValue> res{ ReadFromBitStream(bitStream) };
|
||||
ASSERT_EQ(res->GetValueType(), eAmf::True);
|
||||
@@ -62,7 +62,7 @@ TEST(dCommonTests, AMFDeserializeAMFTrueTest) {
|
||||
* @brief Test reading an AMFInteger value from a BitStream.
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFIntegerTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
{
|
||||
bitStream.Write<uint8_t>(0x04);
|
||||
// 127 == 01111111
|
||||
@@ -113,7 +113,7 @@ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) {
|
||||
* @brief Test reading an AMFDouble value from a BitStream.
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFDoubleTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x05);
|
||||
bitStream.Write<double>(25346.4f);
|
||||
std::unique_ptr<AMFBaseValue> res{ ReadFromBitStream(bitStream) };
|
||||
@@ -125,7 +125,7 @@ TEST(dCommonTests, AMFDeserializeAMFDoubleTest) {
|
||||
* @brief Test reading an AMFString value from a BitStream.
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFStringTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x06);
|
||||
bitStream.Write<uint8_t>(0x0F);
|
||||
std::string toWrite = "stateID";
|
||||
@@ -139,7 +139,7 @@ TEST(dCommonTests, AMFDeserializeAMFStringTest) {
|
||||
* @brief Test reading an AMFArray value from a BitStream.
|
||||
*/
|
||||
TEST(dCommonTests, AMFDeserializeAMFArrayTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
// Test empty AMFArray
|
||||
bitStream.Write<uint8_t>(0x09);
|
||||
bitStream.Write<uint8_t>(0x01);
|
||||
@@ -490,20 +490,20 @@ TEST_F(AMFDeserializeLimitsTest, NestingLimitTest) {
|
||||
};
|
||||
|
||||
{
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
writeNested(bitStream, AMFDeserialize::MaxDepth);
|
||||
std::unique_ptr<AMFBaseValue> res;
|
||||
ASSERT_NO_THROW(res = ReadFromBitStream(bitStream));
|
||||
ASSERT_EQ(res->GetValueType(), eAmf::Array);
|
||||
}
|
||||
{
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
writeNested(bitStream, AMFDeserialize::MaxDepth + 1);
|
||||
ASSERT_THROW(ReadFromBitStream(bitStream), std::invalid_argument);
|
||||
}
|
||||
{
|
||||
// Far past the limit, what a malicious client would send to overflow the stack.
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
writeNested(bitStream, 100'000);
|
||||
ASSERT_THROW(ReadFromBitStream(bitStream), std::invalid_argument);
|
||||
}
|
||||
@@ -524,14 +524,14 @@ TEST_F(AMFDeserializeLimitsTest, AssociativeLimitTest) {
|
||||
};
|
||||
|
||||
{
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
writeArray(bitStream, AMFDeserialize::MaxArraySize);
|
||||
std::unique_ptr<AMFBaseValue> res;
|
||||
ASSERT_NO_THROW(res = ReadFromBitStream(bitStream));
|
||||
ASSERT_EQ(static_cast<AMFArrayValue*>(res.get())->GetAssociative().size(), AMFDeserialize::MaxArraySize);
|
||||
}
|
||||
{
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
writeArray(bitStream, AMFDeserialize::MaxArraySize + 1);
|
||||
ASSERT_THROW(ReadFromBitStream(bitStream), std::invalid_argument);
|
||||
}
|
||||
@@ -541,7 +541,7 @@ TEST_F(AMFDeserializeLimitsTest, AssociativeLimitTest) {
|
||||
* @brief The dense size is checked before any of the associative part is read.
|
||||
*/
|
||||
TEST_F(AMFDeserializeLimitsTest, DenseLimitTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x09);
|
||||
WriteU29(bitStream, ((AMFDeserialize::MaxArraySize + 1) << 1) | 1);
|
||||
bitStream.Write<uint8_t>(0x01);
|
||||
@@ -552,7 +552,7 @@ TEST_F(AMFDeserializeLimitsTest, DenseLimitTest) {
|
||||
* @brief Many small arrays that are each within limits still count toward one total budget.
|
||||
*/
|
||||
TEST_F(AMFDeserializeLimitsTest, TotalValueLimitTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
// An outer array of 20 arrays with 10,000 values each is 200,000 values.
|
||||
bitStream.Write<uint8_t>(0x09);
|
||||
WriteU29(bitStream, (20 << 1) | 1);
|
||||
@@ -570,7 +570,7 @@ TEST_F(AMFDeserializeLimitsTest, TotalValueLimitTest) {
|
||||
* @brief Sending a key twice keeps the last value, and the returned reference is to a live value.
|
||||
*/
|
||||
TEST_F(AMFDeserializeLimitsTest, DuplicateKeyTest) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write<uint8_t>(0x09);
|
||||
bitStream.Write<uint8_t>(0x01);
|
||||
WriteShortAmfString(bitStream, "key");
|
||||
|
||||
@@ -3,7 +3,6 @@ set(DCOMMONTEST_SOURCES
|
||||
"Amf3Tests.cpp"
|
||||
"ToUnderlyingTests.cpp"
|
||||
"InstanceMigrationTests.cpp"
|
||||
"HeaderSkipTest.cpp"
|
||||
"TestCDFeatureGatingTable.cpp"
|
||||
"TestLDFFormat.cpp"
|
||||
"TestNiPoint3.cpp"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "dCommonVars.h"
|
||||
|
||||
TEST(LUString33Test, SerializeWriteTestOld) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 33; i++) testString += "a";
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -14,7 +14,7 @@ TEST(LUString33Test, SerializeWriteTestOld) {
|
||||
}
|
||||
|
||||
TEST(LUString33Test, SerializeWriteTestOldPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 15; i++) testString += "a";
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -34,7 +34,7 @@ TEST(LUString33Test, SerializeWriteTestOldPartial) {
|
||||
}
|
||||
|
||||
TEST(LUString33Test, SerializeWriteTestNew) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 33; i++) testString += "a";
|
||||
bitStream.Write(LUString(testString, 33));
|
||||
@@ -45,7 +45,7 @@ TEST(LUString33Test, SerializeWriteTestNew) {
|
||||
}
|
||||
|
||||
TEST(LUString33Test, SerializeWriteTestNewPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 15; i++) testString += "a";
|
||||
bitStream.Write(LUString(testString, 33));
|
||||
@@ -64,7 +64,7 @@ TEST(LUString33Test, SerializeWriteTestNewPartial) {
|
||||
}
|
||||
|
||||
TEST(LUString33Test, SerializeReadTestOld) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 33; i++) testString += "a";
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -76,7 +76,7 @@ TEST(LUString33Test, SerializeReadTestOld) {
|
||||
}
|
||||
|
||||
TEST(LUString33Test, SerializeReadTestOldPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 15; i++) testString += "a";
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -97,7 +97,7 @@ TEST(LUString33Test, SerializeReadTestOldPartial) {
|
||||
}
|
||||
|
||||
TEST(LUString33Test, SerializeReadTestNew) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 33; i++) testString += "a";
|
||||
bitStream.Write(LUString(testString, 33));
|
||||
@@ -109,7 +109,7 @@ TEST(LUString33Test, SerializeReadTestNew) {
|
||||
}
|
||||
|
||||
TEST(LUString33Test, SerializeReadTestNewPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::string testString;
|
||||
for (int i = 0; i < 15; i++) testString += "a";
|
||||
bitStream.Write(LUString(testString, 33));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "dCommonVars.h"
|
||||
|
||||
TEST(LUWString33Test, SerializeWriteTestOld) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 33; i++) testString += u'ü';
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -14,7 +14,7 @@ TEST(LUWString33Test, SerializeWriteTestOld) {
|
||||
}
|
||||
|
||||
TEST(LUWString33Test, SerializeWriteTestOldPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 15; i++) testString += u'ü';
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -34,7 +34,7 @@ TEST(LUWString33Test, SerializeWriteTestOldPartial) {
|
||||
}
|
||||
|
||||
TEST(LUWString33Test, SerializeWriteTestNew) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 33; i++) testString += u'ü';
|
||||
bitStream.Write(LUWString(testString, 33));
|
||||
@@ -45,7 +45,7 @@ TEST(LUWString33Test, SerializeWriteTestNew) {
|
||||
}
|
||||
|
||||
TEST(LUWString33Test, SerializeWriteTestNewPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 15; i++) testString += u'ü';
|
||||
bitStream.Write(LUWString(testString, 33));
|
||||
@@ -64,7 +64,7 @@ TEST(LUWString33Test, SerializeWriteTestNewPartial) {
|
||||
}
|
||||
|
||||
TEST(LUWString33Test, SerializeReadTestOld) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 33; i++) testString += u'ü';
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -76,7 +76,7 @@ TEST(LUWString33Test, SerializeReadTestOld) {
|
||||
}
|
||||
|
||||
TEST(LUWString33Test, SerializeReadTestOldPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 15; i++) testString += u'ü';
|
||||
for (const auto& c : testString) bitStream.Write(c);
|
||||
@@ -97,7 +97,7 @@ TEST(LUWString33Test, SerializeReadTestOldPartial) {
|
||||
}
|
||||
|
||||
TEST(LUWString33Test, SerializeReadTestNew) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 33; i++) testString += u'ü';
|
||||
bitStream.Write(LUWString(testString, 33));
|
||||
@@ -109,7 +109,7 @@ TEST(LUWString33Test, SerializeReadTestNew) {
|
||||
}
|
||||
|
||||
TEST(LUWString33Test, SerializeReadTestNewPartial) {
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
std::u16string testString;
|
||||
for (int i = 0; i < 15; i++) testString += u'ü';
|
||||
bitStream.Write(LUWString(testString, 33));
|
||||
|
||||
@@ -11,7 +11,7 @@ class DestroyableTest : public GameDependenciesTest {
|
||||
protected:
|
||||
Entity* baseEntity;
|
||||
DestroyableComponent* destroyableComponent;
|
||||
CBITSTREAM
|
||||
RakNet::BitStream bitStream;
|
||||
uint32_t flags = 0;
|
||||
void SetUp() override {
|
||||
SetUpDependencies();
|
||||
|
||||
@@ -12,7 +12,7 @@ class PetTest : public GameDependenciesTest {
|
||||
protected:
|
||||
Entity* baseEntity;
|
||||
PetComponent* petComponent;
|
||||
CBITSTREAM
|
||||
RakNet::BitStream bitStream;
|
||||
|
||||
void SetUp() override {
|
||||
SetUpDependencies();
|
||||
|
||||
@@ -11,7 +11,7 @@ class SimplePhysicsTest : public GameDependenciesTest {
|
||||
protected:
|
||||
std::unique_ptr<Entity> baseEntity;
|
||||
SimplePhysicsComponent* simplePhysicsComponent;
|
||||
CBITSTREAM;
|
||||
RakNet::BitStream bitStream;
|
||||
void SetUp() override {
|
||||
SetUpDependencies();
|
||||
baseEntity = std::make_unique<Entity>(15, GameDependenciesTest::info);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// The byte-equality tests send the same inputs through these and through the new structs and require
|
||||
// identical bytes, so the wire format is pinned even after the production code is deleted.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// were inline in HandleUnUseModel, HandleBBBSaveRequest and WorldServer's level load, wrapped in a function; the
|
||||
// Read* functions are the read sequences of the replaced GameMessages::Handle* functions.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// The Read* functions are the read sequences of the replaced GameMessages::Handle* functions, verbatim up to
|
||||
// the point where the handler starts using what it read.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// (dGame/dGameMessages/GameMessages.cpp, branched from origin/main 129199e4). Only the namespace changed.
|
||||
// The Read* functions are the read sequences of the replaced GameMessages::Handle* functions.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "Amf3.h"
|
||||
#include "AmfSerialize.h"
|
||||
#include "BitStreamUtils.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// The Read* functions are the read sequences of the replaced GameMessages::Handle* functions.
|
||||
// SendMoveInventoryBatch is not here: nothing called it, and MoveInventoryBatch follows the client's layout.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// (dGame/dGameMessages/GameMessages.cpp, branched from origin/main 129199e4). Only the namespace changed.
|
||||
// The Read* functions are the read sequences of the replaced GameMessages::Handle* functions.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// (dGame/dGameMessages/GameMessages.cpp, branched from origin/main 129199e4). Only the namespace changed.
|
||||
// The Read* functions are the read sequences of the replaced GameMessages::Handle* functions.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "Brick.h"
|
||||
#include "dCommonVars.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// news screen's hot properties). Only the namespace changed. The Read* functions are the read sequences of the
|
||||
// replaced GameMessages::Handle* functions (and PlayerReports' report readers).
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "CDClientManager.h"
|
||||
#include "CDPropertyTemplateTable.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// The Read* functions are the read sequences of the replaced GameMessages::Handle* functions, verbatim up to
|
||||
// the point where the handler starts using what it read.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
// Each class's Serialize writes the message ID and then the payload; the old senders wrote the CLIENT/GAME_MSG
|
||||
// header and the target object ID before it. The Read* function is the read sequence of the replaced switch case.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BehaviorSlot.h"
|
||||
#include "BitStream.h"
|
||||
#include "BitStreamUtils.h"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
// The Read* functions are the read sequences of the replaced GameMessages::Handle* functions, verbatim up to
|
||||
// the point where the handler starts using what it read.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace {
|
||||
template<typename Legacy>
|
||||
PacketBytes LegacyPacket(LWOOBJID target, Legacy& legacy) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
LUBitStream(ServiceType::CLIENT, MessageType::Client::GAME_MSG).WriteHeader(bitStream);
|
||||
bitStream.Write(target);
|
||||
legacy.Serialize(bitStream);
|
||||
return FromBitStream(bitStream);
|
||||
@@ -262,7 +262,7 @@ TEST_F(SkillMessagesTests, EchoesBroadcastExceptTheCaster) {
|
||||
const auto caster = ClientAddress();
|
||||
const auto legacy = Capture([&] {
|
||||
RakNet::BitStream bitStreamLocal;
|
||||
BitStreamUtils::WriteHeader(bitStreamLocal, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
LUBitStream(ServiceType::CLIENT, MessageType::Client::GAME_MSG).WriteHeader(bitStreamLocal);
|
||||
bitStreamLocal.Write(echo.target);
|
||||
LegacyGameMessages::EchoSyncSkill legacyEcho("ab", 0, 0, true);
|
||||
legacyEcho.Serialize(bitStreamLocal);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
// The byte-equality tests send the same inputs through these and through the new structs and require identical
|
||||
// bytes, so the wire format is pinned even after the production code is deleted.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// The byte-equality tests run the same inputs through these and through the new structs and require
|
||||
// identical bytes, so the wire format is pinned even after the production code is deleted.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "AuthPackets.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "ClientPackets.h"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
// These messages never reach a client, but master, worlds, auth, chat and the dashboard can run different builds
|
||||
// during an update, so their bytes are pinned too.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
// returns what was read, or the packet that was built, instead of acting on it).
|
||||
// Only the namespace changed. The byte-equality tests run the same inputs through these and the new structs.
|
||||
|
||||
#include "LegacyPacketMacros.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace {
|
||||
template<typename T>
|
||||
void ExpectHeaderThenSerialize(const T& msg, MessageType::Master id) {
|
||||
RakNet::BitStream old;
|
||||
BitStreamUtils::WriteHeader(old, ServiceType::MASTER, id);
|
||||
LUBitStream(ServiceType::MASTER, id).WriteHeader(old);
|
||||
msg.Serialize(old);
|
||||
EXPECT_PACKET_EQ(FromBitStream(old), StructPacket(msg));
|
||||
RoundTrip(msg);
|
||||
|
||||
Reference in New Issue
Block a user