diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index ab1589d53..9aaa9b8e7 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -2222,7 +2222,8 @@ void Entity::RegisterMsg(const MessageType::Game msgId, std::function struct NetGameMsgEvent; struct ActivityNotify; struct ShootingGalleryFire; struct ChildLoaded; @@ -182,11 +183,11 @@ public: void AddComponent(eReplicaComponentType componentId, Component* component); - bool MsgRequestServerObjectInfo(GameMessages::RequestServerObjectInfo& msg); - bool MsgDropClientLoot(GameMessages::DropClientLoot& msg); + bool MsgRequestServerObjectInfo(GameMessages::NetGameMsgEvent& event); + bool MsgDropClientLoot(GameMessages::NetGameMsgEvent& event); bool MsgGetFlag(GameMessages::GetFlag& msg); bool MsgGetFactionTokenType(GameMessages::GetFactionTokenType& msg); - bool MsgPickupItem(GameMessages::PickupItem& msg); + bool MsgPickupItem(GameMessages::NetGameMsgEvent& event); bool MsgChildRemoved(GameMessages::ChildRemoved& msg); // This is expceted to never return nullptr, an assert checks this. diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 877fe4fa8..ba217b99c 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -783,7 +783,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType lootMsg.spawnPos = m_Parent->GetPosition(); lootMsg.sourceID = source; lootMsg.item = LOT_NULL; - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); character->SetCoins(coinsTotal, eLootSourceType::DELETION); } } @@ -1022,17 +1022,17 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) { lootMsg.spawnPos = m_Parent->GetPosition(); lootMsg.sourceID = source; lootMsg.item = LOT_NULL; - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); lootMsg.Send(m_Parent->GetSystemAddress()); while (coinsToDrop > MAX_TO_DROP_PER_GM) { LOG("Dropping 100,000, %llu left", coinsToDrop); lootMsg.currency = 100'000; - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); lootMsg.Send(m_Parent->GetSystemAddress()); coinsToDrop -= 100'000; } lootMsg.currency = coinsToDrop; - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); lootMsg.Send(m_Parent->GetSystemAddress()); } return; diff --git a/dGame/dComponents/GhostComponent.cpp b/dGame/dComponents/GhostComponent.cpp index e55031d4f..6c0800b82 100644 --- a/dGame/dComponents/GhostComponent.cpp +++ b/dGame/dComponents/GhostComponent.cpp @@ -68,7 +68,9 @@ void GhostComponent::GhostEntity(LWOOBJID id) { m_ObservedEntities.erase(id); } -bool GhostComponent::OnToggleGMInvis(GameMessages::ToggleGMInvis& gmInvisMsg) { +bool GhostComponent::OnToggleGMInvis(GameMessages::ToggleGMInvisEvent& event) { + auto& gmInvisMsg = event.msg; + gmInvisMsg.target = event.target; // the wire message goes out with the target the event was delivered to gmInvisMsg.bStateOut = !m_IsGMInvisible; m_IsGMInvisible = !m_IsGMInvisible; LOG_DEBUG("GM Invisibility toggled to: %s", m_IsGMInvisible ? "true" : "false"); diff --git a/dGame/dComponents/GhostComponent.h b/dGame/dComponents/GhostComponent.h index 13a89640d..2011943d6 100644 --- a/dGame/dComponents/GhostComponent.h +++ b/dGame/dComponents/GhostComponent.h @@ -43,7 +43,7 @@ public: void GhostEntity(const LWOOBJID id); - bool OnToggleGMInvis(GameMessages::ToggleGMInvis& msg); + bool OnToggleGMInvis(GameMessages::ToggleGMInvisEvent& event); bool OnGetGMInvis(GameMessages::GetGMInvis& msg); diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 248cbbac3..e070b3c6a 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -59,7 +59,8 @@ bool ModelComponent::OnResetModelToDefaults(GameMessages::ResetModelToDefaults& return true; } -bool ModelComponent::OnRequestUse(GameMessages::RequestUse& requestUse) { +bool ModelComponent::OnRequestUse(GameMessages::RequestUseEvent& event) { + auto& requestUse = event.msg; bool toReturn = false; if (!m_IsPaused) { for (auto& behavior : m_Behaviors) behavior.HandleMsg(requestUse); diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index e821406b0..601f43543 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -32,7 +32,7 @@ public: void LoadBehaviors(); void Update(float deltaTime) override; - bool OnRequestUse(GameMessages::RequestUse& requestUse); + bool OnRequestUse(GameMessages::RequestUseEvent& event); bool OnResetModelToDefaults(GameMessages::ResetModelToDefaults& resetModelToDefaults); bool OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo); diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 1918ca2ef..02b81f8f6 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -43,7 +43,7 @@ namespace { using enum MessageType::Game; using namespace GameMessages; - using MessageCreator = std::function()>; + using MessageCreator = std::function()>; std::map g_MessageHandlers = { { REQUEST_USE, []() { return std::make_unique(); }}, { REQUEST_SERVER_OBJECT_INFO, []() { return std::make_unique(); } }, @@ -87,7 +87,10 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System } } - msg->Deserialize(inStream); + if (!msg->Deserialize(inStream)) { + LOG("Dropping malformed GM %4i, %s from (%llu) targeting (%llu)", messageID, StringifiedEnum::ToString(messageID).data(), usr->GetLoggedInChar(), objectID); + return; + } msg->Handle(*entity, sysAddr); return; } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index f40e79a45..ef1c939ef 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -6285,14 +6285,24 @@ namespace GameMessages { return Send(); } - void GameMsg::Send(const SystemAddress& sysAddr) const { - CBITSTREAM; + void NetGameMsg::WritePacket(RakNet::BitStream& bitStream) const { CMSGHEADER; bitStream.Write(target); // Who this message will be sent to on the (a) client bitStream.Write(msgId); // the ID of this message Serialize(bitStream); // write the message data + } + + void NetGameMsg::SendToClient(const SystemAddress& sysAddr) const { + CBITSTREAM; + WritePacket(bitStream); + SEND_PACKET; + } + + void NetGameMsg::Send(const SystemAddress& sysAddr) const { + CBITSTREAM; + WritePacket(bitStream); // Send to everyone if someone sent unassigned system address, or to one specific client. if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) { @@ -6378,8 +6388,10 @@ namespace GameMessages { void RequestServerObjectInfo::Handle(Entity& entity, const SystemAddress& sysAddr) { auto* handlingEntity = Game::entityManager->GetEntity(targetForReport); - if (handlingEntity) handlingEntity->HandleMsg(*this); - else LOG("Failed to find target %llu", targetForReport); + if (handlingEntity) { + RequestServerObjectInfoEvent event(*this); + handlingEntity->HandleMsg(event); + } else LOG("Failed to find target %llu", targetForReport); } bool RequestUse::Deserialize(RakNet::BitStream& stream) { @@ -6418,7 +6430,8 @@ namespace GameMessages { interactedObject->OnUse(&entity); } - interactedObject->HandleMsg(*this); + RequestUseEvent event(*this); + interactedObject->HandleMsg(event); //Perform use task if possible: auto missionComponent = entity.GetComponent(); @@ -6480,7 +6493,8 @@ namespace GameMessages { LOG("Has team %i picking up %llu:%llu", team != nullptr, lootID, lootOwnerID); if (team) { for (const auto memberId : team->members) { - this->Send(memberId); + PickupItemEvent event(*this); + event.Send(memberId); TeamPickupItem teamPickupMsg{}; teamPickupMsg.target = lootID; teamPickupMsg.lootID = lootID; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index ce70a42c5..2f33c9ff5 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -3,6 +3,7 @@ #include "dCommonVars.h" #include +#include #include #include #include "eMovementPlatformState.h" @@ -53,26 +54,78 @@ enum class eCameraTargetCyclingMode : int32_t { }; namespace GameMessages { + /** + * A server-internal event, delivered only to the handlers entities/components/scripts registered with + * RegisterMsg. It never goes on the wire: it has no Serialize and no way to send it to a client. + */ struct GameMsg { - GameMsg(MessageType::Game gmId, eGameMasterLevel lvl) : msgId{ gmId }, requiredGmLevel{ lvl } {} - GameMsg(MessageType::Game gmId) : GameMsg(gmId, eGameMasterLevel::CIVILIAN) {} + GameMsg(MessageType::Game gmId) : msgId{ gmId } {} virtual ~GameMsg() = default; - // Sends a message to the entity manager to route to the target + // Delivers the message to the handlers registered on the target entity. bool Send(); bool Send(const LWOOBJID _target); + MessageType::Game msgId; + LWOOBJID target{ LWOOBJID_EMPTY }; + }; + + /** + * A game message that goes on the wire, to (Serialize) or from (Deserialize + Handle) a client. + * It is not a GameMsg, so it cannot be delivered to local handlers by mistake. When local handlers need to + * observe a network message, wrap it in a NetGameMsgEvent. + */ + struct NetGameMsg { + NetGameMsg(MessageType::Game gmId, eGameMasterLevel lvl) : msgId{ gmId }, requiredGmLevel{ lvl } {} + NetGameMsg(MessageType::Game gmId) : NetGameMsg(gmId, eGameMasterLevel::CIVILIAN) {} + virtual ~NetGameMsg() = default; + // Sends the message to the specified client or // all clients if UNASSIGNED_SYSTEM_ADDRESS is specified void Send(const SystemAddress& sysAddr) const; + + // Sends the message to the specified client only and never broadcasts. Given UNASSIGNED_SYSTEM_ADDRESS + // nothing is delivered (RakNet rejects a non-broadcast send without an address). + void SendToClient(const SystemAddress& sysAddr) const; + + // Writes the complete client packet (CLIENT/GAME_MSG header, target, msgId, then Serialize()) into bitStream. + // 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; + virtual void Serialize(RakNet::BitStream& bitStream) const {} virtual bool Deserialize(RakNet::BitStream& bitStream) { return true; } + + // Called for messages received from a client, after a successful Deserialize. virtual void Handle(Entity& entity, const SystemAddress& sysAddr) {}; + MessageType::Game msgId; LWOOBJID target{ LWOOBJID_EMPTY }; + + // Minimum GM level the sending client needs for Handle to be called. eGameMasterLevel requiredGmLevel; }; + /** + * A server-internal event carrying a network message, so entity/component handlers can react to a message + * received from (or about to be sent to) a client. Uses the network message's msgId for local dispatch. + */ + template + struct NetGameMsgEvent : public GameMsg { + static_assert(std::is_base_of_v, "NetGameMsgEvent carries a NetGameMsg"); + NetGameMsgEvent() : GameMsg(Msg{}.msgId) {} + NetGameMsgEvent(const Msg& message) : GameMsg(message.msgId), msg{ message } { target = message.target; } + + Msg msg; + }; + + // Delivers a copy of a network message to the local handlers registered on msg.target (never to a client). + // Returns whether a handler handled it. Handlers see (and may modify) only the copy. + template + bool DeliverLocally(const Msg& msg) { + NetGameMsgEvent event(msg); + return event.Send(); + } + class PropertyDataMessage; void SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender); void SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation = false); @@ -705,8 +758,8 @@ namespace GameMessages { // This is a client gm however its default values are exactly what we need to get around the invisible inventory item issues. void SendUpdateInventoryUi(LWOOBJID objectId, const SystemAddress& sysAddr); - struct DisplayTooltip : public GameMsg { - DisplayTooltip() : GameMsg(MessageType::Game::DISPLAY_TOOLTIP) {} + struct DisplayTooltip : public NetGameMsg { + DisplayTooltip() : NetGameMsg(MessageType::Game::DISPLAY_TOOLTIP) {} bool doOrDie{}; bool noRepeat{}; bool noRevive{}; @@ -721,8 +774,8 @@ namespace GameMessages { void Serialize(RakNet::BitStream& bitStream) const override; }; - struct UseItemOnClient : public GameMsg { - UseItemOnClient() : GameMsg(MessageType::Game::USE_ITEM_ON_CLIENT) {} + struct UseItemOnClient : public NetGameMsg { + UseItemOnClient() : NetGameMsg(MessageType::Game::USE_ITEM_ON_CLIENT) {} LWOOBJID playerId{}; LWOOBJID itemToUse{}; uint32_t itemType{}; @@ -741,14 +794,14 @@ namespace GameMessages { LwoNameValue racingSettings{}; }; - struct SetModelToBuild : public GameMsg { - SetModelToBuild() : GameMsg(MessageType::Game::SET_MODEL_TO_BUILD) {} + struct SetModelToBuild : public NetGameMsg { + SetModelToBuild() : NetGameMsg(MessageType::Game::SET_MODEL_TO_BUILD) {} void Serialize(RakNet::BitStream& bitStream) const override; LOT modelLot{ -1 }; }; - struct SpawnModelBricks : public GameMsg { - SpawnModelBricks() : GameMsg(MessageType::Game::SPAWN_MODEL_BRICKS) {} + struct SpawnModelBricks : public NetGameMsg { + SpawnModelBricks() : NetGameMsg(MessageType::Game::SPAWN_MODEL_BRICKS) {} void Serialize(RakNet::BitStream& bitStream) const override; float amount{ 0.0f }; @@ -761,8 +814,8 @@ namespace GameMessages { LwoNameValue notification{}; }; - struct ShootingGalleryFire : public GameMsg { - ShootingGalleryFire() : GameMsg(MessageType::Game::SHOOTING_GALLERY_FIRE) {} + struct ShootingGalleryFire : public NetGameMsg { + ShootingGalleryFire() : NetGameMsg(MessageType::Game::SHOOTING_GALLERY_FIRE) {} bool Deserialize(RakNet::BitStream& bitStream) override; void Handle(Entity& entity, const SystemAddress& sysAddr) override; @@ -781,15 +834,16 @@ namespace GameMessages { PlayerResurrectionFinished() : GameMsg(MessageType::Game::PLAYER_RESURRECTION_FINISHED) {} }; - struct RequestServerObjectInfo : public GameMsg { + struct RequestServerObjectInfo : public NetGameMsg { bool bVerbose{}; LWOOBJID clientId{}; LWOOBJID targetForReport{}; - RequestServerObjectInfo() : GameMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, eGameMasterLevel::DEVELOPER) {} + RequestServerObjectInfo() : NetGameMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, eGameMasterLevel::DEVELOPER) {} bool Deserialize(RakNet::BitStream& bitStream) override; void Handle(Entity& entity, const SystemAddress& sysAddr) override; }; + using RequestServerObjectInfoEvent = NetGameMsgEvent; struct GetObjectReportInfo : public GameMsg { AMFArrayValue* info{}; @@ -797,11 +851,11 @@ namespace GameMessages { bool bVerbose{}; LWOOBJID clientID{}; - GetObjectReportInfo() : GameMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, eGameMasterLevel::DEVELOPER) {} + GetObjectReportInfo() : GameMsg(MessageType::Game::GET_OBJECT_REPORT_INFO) {} }; - struct RequestUse : public GameMsg { - RequestUse() : GameMsg(MessageType::Game::REQUEST_USE) {} + struct RequestUse : public NetGameMsg { + RequestUse() : NetGameMsg(MessageType::Game::REQUEST_USE) {} bool Deserialize(RakNet::BitStream& stream) override; void Handle(Entity& entity, const SystemAddress& sysAddr) override; @@ -819,11 +873,12 @@ namespace GameMessages { // Used only for multi-interaction, is of the enum type InteractionType int multiInteractType{}; }; + using RequestUseEvent = NetGameMsgEvent; - struct Smash : public GameMsg { - Smash() : GameMsg(MessageType::Game::SMASH) {} + struct Smash : public NetGameMsg { + Smash() : NetGameMsg(MessageType::Game::SMASH) {} - void Serialize(RakNet::BitStream& stream) const; + void Serialize(RakNet::BitStream& stream) const override; bool bIgnoreObjectVisibility{}; bool force{}; @@ -831,19 +886,19 @@ namespace GameMessages { LWOOBJID killerID{}; }; - struct UnSmash : public GameMsg { - UnSmash() : GameMsg(MessageType::Game::UN_SMASH) {} + struct UnSmash : public NetGameMsg { + UnSmash() : NetGameMsg(MessageType::Game::UN_SMASH) {} - void Serialize(RakNet::BitStream& stream) const; + void Serialize(RakNet::BitStream& stream) const override; LWOOBJID builderID{ LWOOBJID_EMPTY }; float duration{ 3.0f }; }; - struct PlayBehaviorSound : public GameMsg { - PlayBehaviorSound() : GameMsg(MessageType::Game::PLAY_BEHAVIOR_SOUND) {} + struct PlayBehaviorSound : public NetGameMsg { + PlayBehaviorSound() : NetGameMsg(MessageType::Game::PLAY_BEHAVIOR_SOUND) {} - void Serialize(RakNet::BitStream& stream) const; + void Serialize(RakNet::BitStream& stream) const override; int32_t soundID{ -1 }; }; @@ -857,8 +912,8 @@ namespace GameMessages { bool bResetBehaviors{ true }; }; - struct EmotePlayed : public GameMsg { - EmotePlayed() : GameMsg(MessageType::Game::EMOTE_PLAYED), emoteID(0), targetID(0) {} + struct EmotePlayed : public NetGameMsg { + EmotePlayed() : NetGameMsg(MessageType::Game::EMOTE_PLAYED), emoteID(0), targetID(0) {} void Serialize(RakNet::BitStream& stream) const override; @@ -880,8 +935,8 @@ namespace GameMessages { bool bIgnoreChecks{ false }; }; - struct DropClientLoot : public GameMsg { - DropClientLoot() : GameMsg(MessageType::Game::DROP_CLIENT_LOOT) {} + struct DropClientLoot : public NetGameMsg { + DropClientLoot() : NetGameMsg(MessageType::Game::DROP_CLIENT_LOOT) {} void Serialize(RakNet::BitStream& stream) const override; LWOOBJID sourceID{ LWOOBJID_EMPTY }; @@ -894,6 +949,7 @@ namespace GameMessages { LWOOBJID lootID{ LWOOBJID_EMPTY }; LWOOBJID ownerID{ LWOOBJID_EMPTY }; }; + using DropClientLootEvent = NetGameMsgEvent; struct GetMissionState : public GameMsg { GetMissionState() : GameMsg(MessageType::Game::GET_MISSION_STATE) {} @@ -923,17 +979,18 @@ namespace GameMessages { LOT item{}; }; - struct PickupItem : public GameMsg { - PickupItem() : GameMsg(MessageType::Game::PICKUP_ITEM) {} + struct PickupItem : public NetGameMsg { + PickupItem() : NetGameMsg(MessageType::Game::PICKUP_ITEM) {} void Handle(Entity& entity, const SystemAddress& sysAddr) override; bool Deserialize(RakNet::BitStream& stream) override; LWOOBJID lootID{}; LWOOBJID lootOwnerID{}; }; + using PickupItemEvent = NetGameMsgEvent; - struct TeamPickupItem : public GameMsg { - TeamPickupItem() : GameMsg(MessageType::Game::TEAM_PICKUP_ITEM) {} + struct TeamPickupItem : public NetGameMsg { + TeamPickupItem() : NetGameMsg(MessageType::Game::TEAM_PICKUP_ITEM) {} void Serialize(RakNet::BitStream& stream) const override; LWOOBJID lootID{}; @@ -946,13 +1003,14 @@ namespace GameMessages { bool bDead{}; }; - struct ToggleGMInvis : public GameMsg { - ToggleGMInvis() : GameMsg(MessageType::Game::TOGGLE_GM_INVIS) {} + struct ToggleGMInvis : public NetGameMsg { + ToggleGMInvis() : NetGameMsg(MessageType::Game::TOGGLE_GM_INVIS) {} void Serialize(RakNet::BitStream& stream) const override; bool bStateOut{ false }; }; + using ToggleGMInvisEvent = NetGameMsgEvent; struct GetGMInvis : public GameMsg { GetGMInvis() : GameMsg(MessageType::Game::GET_GM_INVIS) {} @@ -966,8 +1024,8 @@ namespace GameMessages { LWOOBJID childID{}; }; - struct UseSkillSet : public GameMsg { - UseSkillSet() : GameMsg(MessageType::Game::USE_SKILL_SET) {} + struct UseSkillSet : public NetGameMsg { + UseSkillSet() : NetGameMsg(MessageType::Game::USE_SKILL_SET) {} void Serialize(RakNet::BitStream& bitStream) const override; bool bRemove{}; diff --git a/dGame/dUtilities/Loot.cpp b/dGame/dUtilities/Loot.cpp index 2edec1c42..181f5e9b0 100644 --- a/dGame/dUtilities/Loot.cpp +++ b/dGame/dUtilities/Loot.cpp @@ -136,7 +136,7 @@ void DropFactionLoot(Entity& player, GameMessages::DropClientLoot& lootMsg) { lootMsg.lootID = ObjectIDManager::GenerateObjectID(); CalcFinalDropPos(lootMsg); // Register the drop on the player - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); // Visually drop it for the player lootMsg.Send(player.GetSystemAddress()); } @@ -165,7 +165,7 @@ void DropFactionLoot(const Team& team, GameMessages::DropClientLoot& lootMsg, co lootMsg.lootID = ObjectIDManager::GenerateObjectID(); CalcFinalDropPos(lootMsg); // Register the drop on this team member - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); // Show the rewards on all connected members of the team. Only the loot owner will be able to pick the tokens up. DistrbuteMsgToTeam(lootMsg, team); } @@ -184,7 +184,7 @@ void DropPowerupLoot(Entity& player, GameMessages::DropClientLoot& lootMsg) { lootMsg.target = playerID; // Register the drop on the player - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); // Visually drop it for the player lootMsg.Send(player.GetSystemAddress()); } @@ -210,7 +210,7 @@ void DropPowerupLoot(const Team& team, GameMessages::DropClientLoot& lootMsg, co lootMsg.target = member; // By sending this message with the same ID to all players on the team, all players on the team are allowed to pick it up. - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); // No need to send to all members in a loop since that will happen by using the outer loop above and also since there is no owner // sending to all will do nothing. const auto* const memberEntity = Game::entityManager->GetEntity(member); @@ -232,7 +232,7 @@ void DropMissionLoot(Entity& player, GameMessages::DropClientLoot& lootMsg) { lootMsg.lootID = ObjectIDManager::GenerateObjectID(); CalcFinalDropPos(lootMsg); // Register the drop with the player - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); // Visually drop the loot to be picked up lootMsg.Send(player.GetSystemAddress()); } @@ -261,7 +261,7 @@ void DropMissionLoot(const Team& team, GameMessages::DropClientLoot& lootMsg, co lootMsg.lootID = ObjectIDManager::GenerateObjectID(); CalcFinalDropPos(lootMsg); // Register the drop with the player - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); DistrbuteMsgToTeam(lootMsg, team); } } @@ -279,7 +279,7 @@ void DropRegularLoot(Entity& player, GameMessages::DropClientLoot& lootMsg) { lootMsg.target = playerID; lootMsg.ownerID = playerID; // Register the drop with the player - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); // Visually drop the loot to be picked up lootMsg.Send(player.GetSystemAddress()); @@ -309,14 +309,14 @@ void DropRegularLoot(Team& team, GameMessages::DropClientLoot& lootMsg, const bo if (team.lootOption == 0 /* Shared loot */) { lootMsg.target = earningPlayer; lootMsg.ownerID = earningPlayer; - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); } else /* Free for all loot */ { lootMsg.ownerID = LWOOBJID_EMPTY; // By sending the loot with NO owner and to ALL members of the team, // its a first come, first serve with who picks the item up. for (const auto ffaMember : team.members) { lootMsg.target = ffaMember; - lootMsg.Send(); + GameMessages::DeliverLocally(lootMsg); } } @@ -405,7 +405,7 @@ void DropLoot(Entity* player, const LWOOBJID source, const std::mapGetEntity(member); if (memberEntity) lootMsg.Send(memberEntity->GetSystemAddress()); } diff --git a/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp b/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp index 5b464ef00..54b0be853 100644 --- a/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp +++ b/dGame/dUtilities/SlashCommands/DEVGMCommands.cpp @@ -91,7 +91,7 @@ namespace DEVGMCommands { GameMessages::SendChatModeUpdate(entity->GetObjectID(), eGameMasterLevel::CIVILIAN); entity->SetGMLevel(eGameMasterLevel::CIVILIAN); - GameMessages::ToggleGMInvis msg; + GameMessages::ToggleGMInvisEvent msg; msg.Send(entity->GetObjectID()); GameMessages::SendSlashCommandFeedbackText(entity, u"Your game master level has been changed, you may not be able to use all commands."); @@ -1593,7 +1593,8 @@ namespace DEVGMCommands { objectInfo.target = closest->GetObjectID(); objectInfo.targetForReport = closest->GetObjectID(); objectInfo.clientId = entity->GetObjectID(); - closest->HandleMsg(objectInfo); + GameMessages::RequestServerObjectInfoEvent objectInfoEvent(objectInfo); + closest->HandleMsg(objectInfoEvent); Game::entityManager->SerializeEntity(closest); diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp index 7575b9cc1..e6752adb6 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp @@ -275,7 +275,7 @@ namespace GMGreaterThanZeroCommands { } void GmInvis(Entity* entity, const SystemAddress& sysAddr, const std::string args) { - GameMessages::ToggleGMInvis msg; + GameMessages::ToggleGMInvisEvent msg; msg.Send(entity->GetObjectID()); } diff --git a/dNet/BitStreamUtils.cpp b/dNet/BitStreamUtils.cpp index 912737850..c78a1c457 100644 --- a/dNet/BitStreamUtils.cpp +++ b/dNet/BitStreamUtils.cpp @@ -21,9 +21,13 @@ bool LUBitStream::ReadHeader(RakNet::BitStream& bitStream) { return true; } -void LUBitStream::Send(const SystemAddress& sysAddr) const { - RakNet::BitStream bitStream; +void LUBitStream::WritePacket(RakNet::BitStream& bitStream) const { this->WriteHeader(bitStream); this->Serialize(bitStream); +} + +void LUBitStream::Send(const SystemAddress& sysAddr) const { + RakNet::BitStream bitStream; + this->WritePacket(bitStream); Game::server->Send(bitStream, sysAddr, sysAddr == UNASSIGNED_SYSTEM_ADDRESS); } diff --git a/dNet/BitStreamUtils.h b/dNet/BitStreamUtils.h index 24d8c4dcb..a1e62b782 100644 --- a/dNet/BitStreamUtils.h +++ b/dNet/BitStreamUtils.h @@ -7,6 +7,7 @@ #include "ServiceType.h" #include #include +#include #define VALIDATE_READ(x) do { if (!x) return false; } while (0) @@ -51,6 +52,7 @@ struct LUBitStream { uint32_t internalPacketID = 0xFFFFFFFF; LUBitStream() = default; + virtual ~LUBitStream() = default; template LUBitStream(ServiceType connectionType, T internalPacketID) { @@ -63,6 +65,10 @@ struct LUBitStream { void Send(const SystemAddress& sysAddr) const; void Broadcast() const { Send(UNASSIGNED_SYSTEM_ADDRESS); }; + // Writes the complete packet (WriteHeader() then Serialize()) into bitStream. + // This is exactly what Send puts on the wire; tests use it to compare bytes without a server. + void WritePacket(RakNet::BitStream& bitStream) const; + virtual void Serialize(RakNet::BitStream& bitStream) const {} virtual bool Deserialize(RakNet::BitStream& bitStream) { return true; } virtual void Handle() {}; @@ -77,6 +83,59 @@ namespace BitStreamUtils { bitStream.Write(static_cast(internalPacketID)); bitStream.Write(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. + */ + template + void WriteOptional(RakNet::BitStream& bitStream, const T& value, const T& defaultValue) { + const bool isNotDefault = value != defaultValue; + bitStream.Write(isNotDefault); + if (isNotDefault) bitStream.Write(value); + } + + /** + * Reads a field written by WriteOptional. If the flag bit is not set, value is set to defaultValue. + */ + template + bool ReadOptional(RakNet::BitStream& bitStream, T& value, const T& defaultValue) { + bool isNotDefault = false; + if (!bitStream.Read(isNotDefault)) return false; + if (!isNotDefault) { + value = defaultValue; + return true; + } + return bitStream.Read(value); + } + + /** + * Writes a length prefixed string: a LenT holding the number of characters, followed by the raw + * characters (1 byte each for std::string, 2 bytes each for std::u16string) with no null terminator. + * This is the layout the client uses for std::string / std::wstring game message fields. + */ + template + void WriteLengthPrefixed(RakNet::BitStream& bitStream, const StringT& value) { + bitStream.Write(static_cast(value.size())); + bitStream.WriteBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size() * sizeof(typename StringT::value_type))); + } + + /** + * Reads a string written by WriteLengthPrefixed. Fails (returns false) if the stream runs out of data or + * if the length is negative or larger than maxLength characters. + */ + template + bool ReadLengthPrefixed(RakNet::BitStream& bitStream, StringT& value, const uint32_t maxLength = 0x500000 /* MAX_MESSAGE_LENGTH */) { + LenT length{}; + if (!bitStream.Read(length)) return false; + if constexpr (std::is_signed_v) { + if (length < 0) return false; + } + if (static_cast(length) > maxLength) return false; + value.resize(length); + if (length == 0) return true; + return bitStream.ReadBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size() * sizeof(typename StringT::value_type)), true); + } } namespace RakNet { diff --git a/dNet/ChatPackets.cpp b/dNet/ChatPackets.cpp index 0c54e2140..b7875e762 100644 --- a/dNet/ChatPackets.cpp +++ b/dNet/ChatPackets.cpp @@ -147,7 +147,6 @@ void ChatPackets::SendRoutedMsg(const LUBitStream& msg, const LWOOBJID targetID, bitStream.Write(targetID); // Now write the actual packet - msg.WriteHeader(bitStream); - msg.Serialize(bitStream); + msg.WritePacket(bitStream); Game::server->Send(bitStream, sysAddr, sysAddr == UNASSIGNED_SYSTEM_ADDRESS); } diff --git a/docs/PacketArchitecture.md b/docs/PacketArchitecture.md new file mode 100644 index 000000000..7d1a26358 --- /dev/null +++ b/docs/PacketArchitecture.md @@ -0,0 +1,271 @@ +# Packet and Game Message Architecture + +This document describes how DLU reads and writes network packets and game messages, the struct-based +architecture everything is being moved to, and the plan for getting there. + +**Hard rule: the wire format never changes as part of a conversion.** The LEGO Universe 1.10.64 client depends +on every message ID, enum value, field order, field width and bit of padding. A conversion may only change how +the server *produces* the bytes, never the bytes. Every conversion proves this with byte-equality tests against +the old code before the old code is deleted (see [Verification](#3-verification)). Where DLU's bytes are known to +be wrong, the fix is its own clearly labelled change, verified against the client, never part of a conversion. + +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.1 The newer style already in the tree + +| 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` | + +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`. + +### 1.2 What is left in the old style + +Hand-written `bitStream.Write`/`Read` sequences inside functions: + +| Area | Where | Count | +|---|---|---| +| 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 | + +Out of scope: replica/component serialization (`Component::Serialize`) and LDF/AMF, which are separate formats +with their own tests. + +### 1.3 Inconsistencies inside the new style, and how they are settled + +| # | Inconsistency | Decision | +|---|---|---| +| 1 | Three packet base designs in flight: `LUBitStream` on main, the unmerged `auth-packet-re-write` redesign (per-service bases), the old local `packet-refactor` branch (`dNet/packets/*`). | **`LUBitStream` as on main.** The other branches are not used. | +| 2 | `GameMessageHandler` ignored the result of `Deserialize`. | **Drop and log** messages that fail to deserialize (PR 0). | +| 3 | The same `GameMsg` type was used for wire messages and server-internal events; `msg.Send()` and `msg.Send(sysAddr)` went to different places. | **Split** into `GameMsg` (internal) and `NetGameMsg` (wire); mixing them is a compile error (PR 0). | +| 4 | Registration is ad hoc: one GM map + switch, a Mail map, switches or if-chains in every server. | One map per message family (see 2.1, 2.2). | +| 5 | Struct locations: 34 structs in the 1000-line `GameMessages.h`, 6 one-off headers, Mail in `Mail.h`, chat structs partly outside any namespace. | Per-domain files (see 2.3). | +| 6 | Naming: some fields use the client's names, some don't; stream parameters are `stream`/`bitStream`/`bitstream`/`inStream`; some overrides lack `override`. | Client names, `bitStream`, always `override` (new code; old structs as they are touched). | +| 7 | Optional ("default flag") fields written by hand; this produced a wire bug in `UnSmash` (flag checks `duration`, value guarded by `builderID != 3.0f`). | `BitStreamUtils::WriteOptional`/`ReadOptional` (PR 0). `UnSmash` fixed in its own wire-change commit. | +| 8 | Length-prefixed strings written with per-character loops. | `BitStreamUtils::WriteLengthPrefixed`/`ReadLengthPrefixed` (PR 0). | +| 9 | 73 `Send*` functions broadcast and then call `Send(UNASSIGNED, broadcast = false)`, which RakNet rejects (harmless). | Goes away with `NetGameMsg::Send`. | +| 10 | `dServerMock::Send` kept a pointer to the caller's stack `BitStream`; `LUBitStream` had virtual functions but no virtual destructor while dispatchers delete through the base. | Fixed in PR 0. | + +## 2. Target architecture + +### 2.1 Game messages + +There are two kinds of game message and they are different types: + +- **`GameMessages::NetGameMsg`** - goes on the wire. `Send(sysAddr)` (UNASSIGNED broadcasts), `SendToClient(sysAddr)` + (one client only, never broadcasts; used where the old function only did `SEND_PACKET`), `WritePacket`, + `Serialize`, `Deserialize`, `Handle(Entity&, sysAddr)`, `requiredGmLevel`. +- **`GameMessages::GameMsg`** - a server-internal event. `Send()` / `Send(target)` deliver it to the handlers + entities, components and scripts registered with `RegisterMsg`. It cannot reach a client. +- **`GameMessages::NetGameMsgEvent`** (aliases such as `RequestUseEvent`, `DropClientLootEvent`) wraps a copy of + a wire message so local handlers can react to it. `GameMessages::DeliverLocally(msg)` sends one to `msg.target`. + +Every wire message is a `NetGameMsg` subclass in a per-domain file `dGame/dGameMessages/Messages.{h,cpp}` +(pilot: `ActivityMessages`). Fields use the client's names and are declared in wire order. Every wire message +implements **both** `Serialize` and `Deserialize`, even if DLU only uses one direction, so it can be round-trip +tested. + +```cpp +// dGame/dGameMessages/ActivityMessages.h +namespace GameMessages { + // Server -> client. + struct ShowActivityCountdown : public NetGameMsg { + ShowActivityCountdown() : NetGameMsg(MessageType::Game::SHOW_ACTIVITY_COUNTDOWN) {} + void Serialize(RakNet::BitStream& bitStream) const override; + bool Deserialize(RakNet::BitStream& bitStream) override; + + bool bPlayAdditionalSound{}; + bool bPlayCountdownSound{}; + std::u16string sndName{}; + int32_t stateToPlaySoundOn{}; + }; + + // Client -> server. + struct RequestActivityExit : public NetGameMsg { + RequestActivityExit() : NetGameMsg(MessageType::Game::REQUEST_ACTIVITY_EXIT) {} + void Serialize(RakNet::BitStream& bitStream) const override; + bool Deserialize(RakNet::BitStream& bitStream) override; + void Handle(Entity& entity, const SystemAddress& sysAddr) override; + + bool bUserCancel{}; + LWOOBJID userID{}; + }; +} + +// dGame/dGameMessages/ActivityMessages.cpp +void ShowActivityCountdown::Serialize(RakNet::BitStream& bitStream) const { + bitStream.Write(bPlayAdditionalSound); + bitStream.Write(bPlayCountdownSound); + BitStreamUtils::WriteLengthPrefixed(bitStream, sndName); + bitStream.Write(stateToPlaySoundOn); +} + +bool ShowActivityCountdown::Deserialize(RakNet::BitStream& bitStream) { + VALIDATE_READ(bitStream.Read(bPlayAdditionalSound)); + VALIDATE_READ(bitStream.Read(bPlayCountdownSound)); + VALIDATE_READ(BitStreamUtils::ReadLengthPrefixed(bitStream, sndName)); + VALIDATE_READ(bitStream.Read(stateToPlaySoundOn)); + return true; +} +``` + +Sending replaces the `Send*` free function: + +```cpp +GameMessages::ShowActivityCountdown countdown; +countdown.target = self->GetObjectID(); +countdown.Send(sender->GetSystemAddress()); // UNASSIGNED_SYSTEM_ADDRESS broadcasts +``` + +Inbound messages are registered with one line in `GameMessageHandler.cpp`; the GM-level gate comes from the +struct, and a message whose `Deserialize` fails is logged and dropped before `Handle`: + +```cpp +std::map g_MessageHandlers = { + ... + { REQUEST_ACTIVITY_EXIT, []() { return std::make_unique(); } }, +}; +``` + +When every case is converted the switch is deleted and `GameMessages.cpp` goes away. + +### 2.2 Packets (`LUBitStream`, as on main) + +Every non-game-message packet is an `LUBitStream` subclass. The base owns the full header: + +- `LUBitStream(ServiceType, packetId)` - `WriteHeader` writes `0x53`, the `ServiceType` (u16), the packet id (u32) + and one pad byte; `ReadHeader` reads and checks the same. +- `WritePacket(bitStream)` = `WriteHeader` + `Serialize`; `Send(sysAddr)` sends that (`UNASSIGNED` broadcasts via + `Broadcast()`). Tests use `WritePacket`. +- Leaf structs only (de)serialize their own fields. A feature with its own sub-header (Mail's `eMessageID`) has an + intermediate base whose `Serialize`/`Deserialize` handle the sub-header, and leaf structs call it first + (`MailLUBitStream` is the model). +- `Handle()` takes no arguments; the dispatcher sets context members (`sysAddr`, and per-service extras such as + Mail's `player`) before calling `Deserialize` and `Handle`. +- Each service has one dispatch function with a `std::map`, exactly like + `Mail::HandleMail`: read the id, create, set context, `Deserialize` (log and drop on failure), `Handle`. Each + server's `HandlePacket` only routes by `ServiceType`. +- Structs live in their service's namespace and file: `AuthPackets`, `ChatPackets`, `ClientPackets`, + `CommonPackets` (new, for `ServiceType::COMMON`), `MasterPackets`, `WorldPackets` in `dNet/`; Mail stays in + `dGame/dUtilities/Mail.*`. Handlers that need game or server state stay in the server that owns that state + (`dChatServer`, `dMasterServer`, `dWorldServer`, `dAuthServer`) and are attached to the struct by overriding + `Handle` in that server's translation unit. +- Fixed-width strings use `LUString`/`LUWString` with the width spelled out (`LUWString password(41)`). + +```cpp +// dNet/ChatPackets.h +struct AchievementNotify : public LUBitStream { + LUWString targetPlayerName{}; + uint32_t missionEmailID{}; + LWOOBJID earningPlayerID{}; + LUWString earnerName{}; + + AchievementNotify() : LUBitStream(ServiceType::CHAT, MessageType::Chat::ACHIEVEMENT_NOTIFY) {} + void Serialize(RakNet::BitStream& bitStream) const override; + bool Deserialize(RakNet::BitStream& bitStream) override; +}; +``` + +### 2.3 Conventions + +- Wire order = declaration order. Comment the direction (`// Server -> client.`) and anything odd (padding, + unknown fields: write them as named constants, never drop them). +- Explicit widths for everything written: `bitStream.Write(x.size())`, never `size_t`, `int`, `long` or + `float_t`. Enums keep their declared underlying type. +- `Deserialize` returns `false` on the first failed read (`VALIDATE_READ`) and bounds-checks lengths + (`ReadLengthPrefixed` rejects negative sizes and anything above `MAX_MESSAGE_LENGTH` by default). +- Optional/default-flag fields: `BitStreamUtils::WriteOptional(bs, value, default)` / `ReadOptional`. +- Length-prefixed strings: `BitStreamUtils::WriteLengthPrefixed` / `ReadLengthPrefixed`. +- No new `CBITSTREAM` / `CMSGHEADER` / `SEND_PACKET` macros or `Send*` wrapper functions; build the struct at the + call site. +- Message IDs are append-only: never renumber, reuse or delete a value. `tests/dCommonTests/MessageIdPinTests.cpp` + and `tests/dGameTests/MailIdPinTests.cpp` pin every enumerator at compile time. +- Behaviour changes and wire fixes are separate, clearly labelled commits, never part of a conversion. + +### 2.4 Testing helpers + +- `tests/dGameTests/GameDependencies.h`: `dServerMock` copies every sent packet (`GetSentPackets()`, each with + bytes, exact bit count, address and broadcast flag). +- `tests/dGameTests/PacketTestUtils.h`: `Capture(fn)`, `FromBitStream`, `FromHex`, `ToHex`, `EXPECT_PACKET_EQ` + (compares bit count and bytes and prints both as hex on failure). +- `NetGameMsg::WritePacket` / `LUBitStream::WritePacket` produce exactly what `Send` puts on the wire. + +## 3. Verification + +Every conversion carries these tests, in `tests/dGameTests/dGameMessagesTests/MessagesTests.cpp` (or a +`dNet` test directory for packets): + +1. **Frozen oracle.** Copy the old functions *verbatim* into `tests/.../Legacy/Legacy.h` (namespace + `Legacy*`; only the namespace changes). A temporary test sends the same inputs through the production function + and the oracle and requires identical bytes; it is deleted in the commit that deletes the production code. From + then on the oracle pins the old bytes. +2. **Byte equality.** For a grid of inputs (every bool combination, empty/ASCII/non-ASCII/long strings, + 0/negative/max numbers, default and non-default values of every optional field) send through the oracle and + through the struct, to one client and as a broadcast. Require identical bits, identical bytes and the same + effective destination. +3. **Golden bytes.** At least one hand-computed hex packet per message family, independent of both + implementations. +4. **Round trip.** `Serialize` -> `Deserialize` -> `Serialize` gives the same bytes and fields and consumes every + bit. +5. **Inbound.** For handlers, compare the struct's `Deserialize` with the oracle's read sequence, and check a + truncated stream returns `false`. +6. **Mutation check** while writing the tests: break one field width and confirm the tests fail. +7. **Live captures, locally only.** Decoding real captured packets with the struct and re-serializing them is a + useful extra check, but it is done with a local script outside the repository. **No capture-derived bytes are + ever committed, not even anonymized.** +8. **Smoke test** the affected feature with the real 1.10.64 client before merging (tests cannot cover handler + behaviour). + +## 4. Migration plan + +Small, self-contained PRs by subsystem: add structs + oracle + tests, switch callers, delete old code. Each PR is a +clean range of commits on the working branch. Target: under ~1.5k changed lines per PR. + +| # | PR | Contents | Size | +|---|---|---|---| +| 0 | Foundations | Test infra (`dServerMock`, `PacketTestUtils`, `WritePacket`), string and optional helpers, compile-time pins of every message ID enum, drop GMs that fail to deserialize, `LUBitStream` virtual destructor and `WritePacket`, the `GameMsg`/`NetGameMsg` split, this document. | S | +| W1 | Wire fix: `UnSmash` | The one intended wire change: stop writing `duration` when it has its default, matching the client. | XS | +| 1 | Activity GMs | `ActivityMessages`: 8 outbound + `RequestActivityExit` inbound. | S | +| 2 | GMs: racing and vehicles | `SendVehicle*`, `SendRacing*`, `SendNotifyRacingClient`, `HandleRacing*`, `HandleVehicle*`, module assembly | M | +| 3 | GMs: effects, audio, animation, UI text | FX, animations, ND audio, 2D ambient, UI messages, message boxes, chat bubbles, billboards, cinematics, tooltips | M | +| 4 | GMs: missions, flags, levels | Offer/notify mission(+task), respond, dialog OK, linked missions, flags, collectibles, level rewards | M | +| 5 | GMs: inventory and items | Add/remove/move/equip/unequip, inventory size and groups, use/consume item, `UpdateInventoryUi` | M | +| 6 | GMs: vendors, donation, trade | Vendor window/status/transactions, buyback, donation vendor, trade | M | +| 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 | +| 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 | + +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. + +### Risks + +- **Silent wire fixes.** A struct written from the client's definition can differ from what DLU has been sending + (e.g. `UnSmash`). The oracle test catches it; the conversion must reproduce the old bytes, and the fix goes in its + own commit. +- **Implicit widths at old call sites** (`int`, `char`, `size_t`, `float_t`, enum underlying types, 1-bit bools vs + `uint8_t`). The byte-equality grid catches these; that is why the oracle is copied verbatim. +- **Default arguments.** Old `Send*` defaults must become the struct's member initializers exactly. +- **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. diff --git a/tests/dCommonTests/CMakeLists.txt b/tests/dCommonTests/CMakeLists.txt index 74039be1a..d5ecacfb0 100644 --- a/tests/dCommonTests/CMakeLists.txt +++ b/tests/dCommonTests/CMakeLists.txt @@ -9,6 +9,8 @@ set(DCOMMONTEST_SOURCES "TestEncoding.cpp" "TestLUString.cpp" "TestLUWString.cpp" + "TestBitStreamUtils.cpp" + "MessageIdPinTests.cpp" "dCommonDependencies.cpp" "LxfmlTests.cpp" ) diff --git a/tests/dCommonTests/MessageIdPinTests.cpp b/tests/dCommonTests/MessageIdPinTests.cpp new file mode 100644 index 000000000..e32d58342 --- /dev/null +++ b/tests/dCommonTests/MessageIdPinTests.cpp @@ -0,0 +1,1838 @@ +// GENERATED by a one-off script from the enum definitions at the time this file was added. +// Message IDs are sent on the wire and are append-only: never renumber, reuse or remove one. +// If one of these fails to compile, the change to the enum is wrong, not this file. +// New enumerators may be added freely; add a pin for them here too. + +#include +#include "ServiceType.h" +#include "MessageType/World.h" +#include "MessageType/Server.h" +#include "MessageType/Master.h" +#include "MessageType/Game.h" +#include "MessageType/Client.h" +#include "MessageType/Chat.h" +#include "MessageType/Auth.h" +#include + +// MessageType::Auth: 6 enumerators +static_assert(static_cast(MessageType::Auth::LOGIN_REQUEST) == 0); +static_assert(static_cast(MessageType::Auth::LOGOUT_REQUEST) == 1); +static_assert(static_cast(MessageType::Auth::CREATE_NEW_ACCOUNT_REQUEST) == 2); +static_assert(static_cast(MessageType::Auth::LEGOINTERFACE_AUTH_RESPONSE) == 3); +static_assert(static_cast(MessageType::Auth::SESSIONKEY_RECEIVED_CONFIRM) == 4); +static_assert(static_cast(MessageType::Auth::RUNTIME_CONFIG) == 5); + +// MessageType::Chat: 69 enumerators +static_assert(static_cast(MessageType::Chat::LOGIN_SESSION_NOTIFY) == 0); +static_assert(static_cast(MessageType::Chat::GENERAL_CHAT_MESSAGE) == 1); +static_assert(static_cast(MessageType::Chat::PRIVATE_CHAT_MESSAGE) == 2); +static_assert(static_cast(MessageType::Chat::USER_CHANNEL_CHAT_MESSAGE) == 3); +static_assert(static_cast(MessageType::Chat::WORLD_DISCONNECT_REQUEST) == 4); +static_assert(static_cast(MessageType::Chat::WORLD_PROXIMITY_RESPONSE) == 5); +static_assert(static_cast(MessageType::Chat::WORLD_PARCEL_RESPONSE) == 6); +static_assert(static_cast(MessageType::Chat::ADD_FRIEND_REQUEST) == 7); +static_assert(static_cast(MessageType::Chat::ADD_FRIEND_RESPONSE) == 8); +static_assert(static_cast(MessageType::Chat::REMOVE_FRIEND) == 9); +static_assert(static_cast(MessageType::Chat::GET_FRIENDS_LIST) == 10); +static_assert(static_cast(MessageType::Chat::ADD_IGNORE) == 11); +static_assert(static_cast(MessageType::Chat::REMOVE_IGNORE) == 12); +static_assert(static_cast(MessageType::Chat::GET_IGNORE_LIST) == 13); +static_assert(static_cast(MessageType::Chat::TEAM_MISSED_INVITE_CHECK) == 14); +static_assert(static_cast(MessageType::Chat::TEAM_INVITE) == 15); +static_assert(static_cast(MessageType::Chat::TEAM_INVITE_RESPONSE) == 16); +static_assert(static_cast(MessageType::Chat::TEAM_KICK) == 17); +static_assert(static_cast(MessageType::Chat::TEAM_LEAVE) == 18); +static_assert(static_cast(MessageType::Chat::TEAM_SET_LOOT) == 19); +static_assert(static_cast(MessageType::Chat::TEAM_SET_LEADER) == 20); +static_assert(static_cast(MessageType::Chat::TEAM_GET_STATUS) == 21); +static_assert(static_cast(MessageType::Chat::GUILD_CREATE) == 22); +static_assert(static_cast(MessageType::Chat::GUILD_INVITE) == 23); +static_assert(static_cast(MessageType::Chat::GUILD_INVITE_RESPONSE) == 24); +static_assert(static_cast(MessageType::Chat::GUILD_LEAVE) == 25); +static_assert(static_cast(MessageType::Chat::GUILD_KICK) == 26); +static_assert(static_cast(MessageType::Chat::GUILD_GET_STATUS) == 27); +static_assert(static_cast(MessageType::Chat::GUILD_GET_ALL) == 28); +static_assert(static_cast(MessageType::Chat::SHOW_ALL) == 29); +static_assert(static_cast(MessageType::Chat::BLUEPRINT_MODERATED) == 30); +static_assert(static_cast(MessageType::Chat::BLUEPRINT_MODEL_READY) == 31); +static_assert(static_cast(MessageType::Chat::PROPERTY_READY_FOR_APPROVAL) == 32); +static_assert(static_cast(MessageType::Chat::PROPERTY_MODERATION_CHANGED) == 33); +static_assert(static_cast(MessageType::Chat::PROPERTY_BUILDMODE_CHANGED) == 34); +static_assert(static_cast(MessageType::Chat::PROPERTY_BUILDMODE_CHANGED_REPORT) == 35); +static_assert(static_cast(MessageType::Chat::MAIL) == 36); +static_assert(static_cast(MessageType::Chat::WORLD_INSTANCE_LOCATION_REQUEST) == 37); +static_assert(static_cast(MessageType::Chat::REPUTATION_UPDATE) == 38); +static_assert(static_cast(MessageType::Chat::SEND_CANNED_TEXT) == 39); +static_assert(static_cast(MessageType::Chat::GMLEVEL_UPDATE) == 40); +static_assert(static_cast(MessageType::Chat::CHARACTER_NAME_CHANGE_REQUEST) == 41); +static_assert(static_cast(MessageType::Chat::CSR_REQUEST) == 42); +static_assert(static_cast(MessageType::Chat::CSR_REPLY) == 43); +static_assert(static_cast(MessageType::Chat::GM_KICK) == 44); +static_assert(static_cast(MessageType::Chat::GM_ANNOUNCE) == 45); +static_assert(static_cast(MessageType::Chat::GM_MUTE) == 46); +static_assert(static_cast(MessageType::Chat::ACTIVITY_UPDATE) == 47); +static_assert(static_cast(MessageType::Chat::WORLD_ROUTE_PACKET) == 48); +static_assert(static_cast(MessageType::Chat::GET_ZONE_POPULATIONS) == 49); +static_assert(static_cast(MessageType::Chat::REQUEST_MINIMUM_CHAT_MODE) == 50); +static_assert(static_cast(MessageType::Chat::REQUEST_MINIMUM_CHAT_MODE_PRIVATE) == 51); +static_assert(static_cast(MessageType::Chat::MATCH_REQUEST) == 52); +static_assert(static_cast(MessageType::Chat::UGCMANIFEST_REPORT_MISSING_FILE) == 53); +static_assert(static_cast(MessageType::Chat::UGCMANIFEST_REPORT_DONE_FILE) == 54); +static_assert(static_cast(MessageType::Chat::UGCMANIFEST_REPORT_DONE_BLUEPRINT) == 55); +static_assert(static_cast(MessageType::Chat::UGCC_REQUEST) == 56); +static_assert(static_cast(MessageType::Chat::WHO) == 57); +static_assert(static_cast(MessageType::Chat::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE) == 58); +static_assert(static_cast(MessageType::Chat::ACHIEVEMENT_NOTIFY) == 59); +static_assert(static_cast(MessageType::Chat::GM_CLOSE_PRIVATE_CHAT_WINDOW) == 60); +static_assert(static_cast(MessageType::Chat::UNEXPECTED_DISCONNECT) == 61); +static_assert(static_cast(MessageType::Chat::PLAYER_READY) == 62); +static_assert(static_cast(MessageType::Chat::GET_DONATION_TOTAL) == 63); +static_assert(static_cast(MessageType::Chat::UPDATE_DONATION) == 64); +static_assert(static_cast(MessageType::Chat::PRG_CSR_COMMAND) == 65); +static_assert(static_cast(MessageType::Chat::HEARTBEAT_REQUEST_FROM_WORLD) == 66); +static_assert(static_cast(MessageType::Chat::UPDATE_FREE_TRIAL_STATUS) == 67); +static_assert(static_cast(MessageType::Chat::CREATE_TEAM) == 68); + +// MessageType::Client: 67 enumerators +static_assert(static_cast(MessageType::Client::LOGIN_RESPONSE) == 0); +static_assert(static_cast(MessageType::Client::LOGOUT_RESPONSE) == 1); +static_assert(static_cast(MessageType::Client::LOAD_STATIC_ZONE) == 2); +static_assert(static_cast(MessageType::Client::CREATE_OBJECT) == 3); +static_assert(static_cast(MessageType::Client::CREATE_CHARACTER) == 4); +static_assert(static_cast(MessageType::Client::CREATE_CHARACTER_EXTENDED) == 5); +static_assert(static_cast(MessageType::Client::CHARACTER_LIST_RESPONSE) == 6); +static_assert(static_cast(MessageType::Client::CHARACTER_CREATE_RESPONSE) == 7); +static_assert(static_cast(MessageType::Client::CHARACTER_RENAME_RESPONSE) == 8); +static_assert(static_cast(MessageType::Client::CHAT_CONNECT_RESPONSE) == 9); +static_assert(static_cast(MessageType::Client::AUTH_ACCOUNT_CREATE_RESPONSE) == 10); +static_assert(static_cast(MessageType::Client::DELETE_CHARACTER_RESPONSE) == 11); +static_assert(static_cast(MessageType::Client::GAME_MSG) == 12); +static_assert(static_cast(MessageType::Client::CONNECT_CHAT) == 13); +static_assert(static_cast(MessageType::Client::TRANSFER_TO_WORLD) == 14); +static_assert(static_cast(MessageType::Client::IMPENDING_RELOAD_NOTIFY) == 15); +static_assert(static_cast(MessageType::Client::MAKE_GM_RESPONSE) == 16); +static_assert(static_cast(MessageType::Client::HTTP_MONITOR_INFO_RESPONSE) == 17); +static_assert(static_cast(MessageType::Client::SLASH_PUSH_MAP_RESPONSE) == 18); +static_assert(static_cast(MessageType::Client::SLASH_PULL_MAP_RESPONSE) == 19); +static_assert(static_cast(MessageType::Client::SLASH_LOCK_MAP_RESPONSE) == 20); +static_assert(static_cast(MessageType::Client::BLUEPRINT_SAVE_RESPONSE) == 21); +static_assert(static_cast(MessageType::Client::BLUEPRINT_LUP_SAVE_RESPONSE) == 22); +static_assert(static_cast(MessageType::Client::BLUEPRINT_LOAD_RESPONSE_ITEMID) == 23); +static_assert(static_cast(MessageType::Client::BLUEPRINT_GET_ALL_DATA_RESPONSE) == 24); +static_assert(static_cast(MessageType::Client::MODEL_INSTANTIATE_RESPONSE) == 25); +static_assert(static_cast(MessageType::Client::DEBUG_OUTPUT) == 26); +static_assert(static_cast(MessageType::Client::ADD_FRIEND_REQUEST) == 27); +static_assert(static_cast(MessageType::Client::ADD_FRIEND_RESPONSE) == 28); +static_assert(static_cast(MessageType::Client::REMOVE_FRIEND_RESPONSE) == 29); +static_assert(static_cast(MessageType::Client::GET_FRIENDS_LIST_RESPONSE) == 30); +static_assert(static_cast(MessageType::Client::UPDATE_FRIEND_NOTIFY) == 31); +static_assert(static_cast(MessageType::Client::ADD_IGNORE_RESPONSE) == 32); +static_assert(static_cast(MessageType::Client::REMOVE_IGNORE_RESPONSE) == 33); +static_assert(static_cast(MessageType::Client::GET_IGNORE_LIST_RESPONSE) == 34); +static_assert(static_cast(MessageType::Client::TEAM_INVITE) == 35); +static_assert(static_cast(MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE) == 36); +static_assert(static_cast(MessageType::Client::GUILD_CREATE_RESPONSE) == 37); +static_assert(static_cast(MessageType::Client::GUILD_GET_STATUS_RESPONSE) == 38); +static_assert(static_cast(MessageType::Client::GUILD_INVITE) == 39); +static_assert(static_cast(MessageType::Client::GUILD_INVITE_INITIAL_RESPONSE) == 40); +static_assert(static_cast(MessageType::Client::GUILD_INVITE_FINAL_RESPONSE) == 41); +static_assert(static_cast(MessageType::Client::GUILD_INVITE_CONFIRM) == 42); +static_assert(static_cast(MessageType::Client::GUILD_ADD_PLAYER) == 43); +static_assert(static_cast(MessageType::Client::GUILD_REMOVE_PLAYER) == 44); +static_assert(static_cast(MessageType::Client::GUILD_LOGIN_LOGOUT) == 45); +static_assert(static_cast(MessageType::Client::GUILD_RANK_CHANGE) == 46); +static_assert(static_cast(MessageType::Client::GUILD_DATA) == 47); +static_assert(static_cast(MessageType::Client::GUILD_STATUS) == 48); +static_assert(static_cast(MessageType::Client::MAIL) == 49); +static_assert(static_cast(MessageType::Client::DB_PROXY_RESULT) == 50); +static_assert(static_cast(MessageType::Client::SHOW_ALL_RESPONSE) == 51); +static_assert(static_cast(MessageType::Client::WHO_RESPONSE) == 52); +static_assert(static_cast(MessageType::Client::SEND_CANNED_TEXT) == 53); +static_assert(static_cast(MessageType::Client::UPDATE_CHARACTER_NAME) == 54); +static_assert(static_cast(MessageType::Client::SET_NETWORK_SIMULATOR) == 55); +static_assert(static_cast(MessageType::Client::INVALID_CHAT_MESSAGE) == 56); +static_assert(static_cast(MessageType::Client::MINIMUM_CHAT_MODE_RESPONSE) == 57); +static_assert(static_cast(MessageType::Client::MINIMUM_CHAT_MODE_RESPONSE_PRIVATE) == 58); +static_assert(static_cast(MessageType::Client::CHAT_MODERATION_STRING) == 59); +static_assert(static_cast(MessageType::Client::UGC_MANIFEST_RESPONSE) == 60); +static_assert(static_cast(MessageType::Client::IN_LOGIN_QUEUE) == 61); +static_assert(static_cast(MessageType::Client::SERVER_STATES) == 62); +static_assert(static_cast(MessageType::Client::GM_CLOSE_TARGET_CHAT_WINDOW) == 63); +static_assert(static_cast(MessageType::Client::GENERAL_TEXT_FOR_LOCALIZATION) == 64); +static_assert(static_cast(MessageType::Client::UPDATE_FREE_TRIAL_STATUS) == 65); +static_assert(static_cast(MessageType::Client::UGC_DOWNLOAD_FAILED) == 120); + +// MessageType::Game: 1599 enumerators +static_assert(static_cast(MessageType::Game::GET_POSITION) == 0); +static_assert(static_cast(MessageType::Game::GET_ROTATION) == 1); +static_assert(static_cast(MessageType::Game::GET_LINEAR_VELOCITY) == 2); +static_assert(static_cast(MessageType::Game::GET_ANGULAR_VELOCITY) == 3); +static_assert(static_cast(MessageType::Game::GET_FORWARD_VELOCITY) == 4); +static_assert(static_cast(MessageType::Game::GET_PLAYER_FORWARD) == 5); +static_assert(static_cast(MessageType::Game::GET_FORWARD_VECTOR) == 6); +static_assert(static_cast(MessageType::Game::SET_POSITION) == 7); +static_assert(static_cast(MessageType::Game::SET_LOCAL_POSITION) == 8); +static_assert(static_cast(MessageType::Game::SET_ROTATION) == 9); +static_assert(static_cast(MessageType::Game::SET_LINEAR_VELOCITY) == 10); +static_assert(static_cast(MessageType::Game::MODIFY_LINEAR_VELOCITY) == 11); +static_assert(static_cast(MessageType::Game::SET_ANGULAR_VELOCITY) == 12); +static_assert(static_cast(MessageType::Game::MODIFY_ANGULAR_VELOCITY) == 13); +static_assert(static_cast(MessageType::Game::DEFLECT) == 14); +static_assert(static_cast(MessageType::Game::SEND_POSITION_UPDATE) == 15); +static_assert(static_cast(MessageType::Game::SET_OBJECT_SCALE) == 16); +static_assert(static_cast(MessageType::Game::GET_OBJECT_SCALE) == 17); +static_assert(static_cast(MessageType::Game::TIMED_SCALE_FINISHED) == 18); +static_assert(static_cast(MessageType::Game::TELEPORT) == 19); +static_assert(static_cast(MessageType::Game::TOGGLE_PLAYER_FWD_TO_CAMERA) == 20); +static_assert(static_cast(MessageType::Game::LOCK_PLAYER_ROT_TO_CAMERA) == 21); +static_assert(static_cast(MessageType::Game::UNLOCK_PLAYER_ROT_FROM_CAMERA) == 22); +static_assert(static_cast(MessageType::Game::TOGGLE_PLAYER_ROT_LOCK_TO_MOUSE) == 23); +static_assert(static_cast(MessageType::Game::LOCK_PLAYER_ROT_TO_MOUSE) == 24); +static_assert(static_cast(MessageType::Game::UNLOCK_PLAYER_ROT_FROM_MOUSE) == 25); +static_assert(static_cast(MessageType::Game::SET_PLAYER_CONTROL_SCHEME) == 26); +static_assert(static_cast(MessageType::Game::GET_PLAYER_CONTROL_SCHEME) == 27); +static_assert(static_cast(MessageType::Game::RESET_PLAYER_CONTROL_SCHEME) == 28); +static_assert(static_cast(MessageType::Game::PLAYER_TO_PREVIOUS_CONTROL_SCHEME) == 29); +static_assert(static_cast(MessageType::Game::DROP_CLIENT_LOOT) == 30); +static_assert(static_cast(MessageType::Game::GET_SPEED) == 34); +static_assert(static_cast(MessageType::Game::GET_ROT_SPEED) == 35); +static_assert(static_cast(MessageType::Game::IS_DEAD) == 36); +static_assert(static_cast(MessageType::Game::DIE) == 37); +static_assert(static_cast(MessageType::Game::REQUEST_DIE) == 38); +static_assert(static_cast(MessageType::Game::ADD_OBJECT) == 39); +static_assert(static_cast(MessageType::Game::PLAY_EMOTE) == 41); +static_assert(static_cast(MessageType::Game::PRELOAD_ANIMATION) == 42); +static_assert(static_cast(MessageType::Game::PLAY_ANIMATION) == 43); +static_assert(static_cast(MessageType::Game::ANIMATION_COMPLETE) == 44); +static_assert(static_cast(MessageType::Game::ENABLE_HIGHLIGHT) == 45); +static_assert(static_cast(MessageType::Game::DISABLE_HIGHLIGHT) == 46); +static_assert(static_cast(MessageType::Game::GET_ANIMATION_NAMES) == 47); +static_assert(static_cast(MessageType::Game::CONTROL_BEHAVIORS) == 48); +static_assert(static_cast(MessageType::Game::BLEND_PRIMARY_ANIMATION) == 52); +static_assert(static_cast(MessageType::Game::SET_OFFSCREEN_ANIMATION) == 53); +static_assert(static_cast(MessageType::Game::GET_MOVEMENT_INPUT_VALUES) == 54); +static_assert(static_cast(MessageType::Game::SWAP_TEXTURE) == 55); +static_assert(static_cast(MessageType::Game::SWAP_COLOR) == 56); +static_assert(static_cast(MessageType::Game::ATTACH_HAIR) == 57); +static_assert(static_cast(MessageType::Game::GET_ENTITY_STRUCT) == 58); +static_assert(static_cast(MessageType::Game::SET_ENTITY_STRUCT) == 59); +static_assert(static_cast(MessageType::Game::SET_ATTR) == 60); +static_assert(static_cast(MessageType::Game::GET_ATTR) == 61); +static_assert(static_cast(MessageType::Game::ON_HIT) == 62); +static_assert(static_cast(MessageType::Game::HIT_OR_HEAL_RESULT) == 63); +static_assert(static_cast(MessageType::Game::SHOW_ATTACK) == 64); +static_assert(static_cast(MessageType::Game::GO_TO) == 65); +static_assert(static_cast(MessageType::Game::GET_CONFIG_DATA) == 66); +static_assert(static_cast(MessageType::Game::SET_CONFIG_DATA) == 68); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_EXTRA_INFO) == 69); +static_assert(static_cast(MessageType::Game::GET_DISPLAY_NAME) == 70); +static_assert(static_cast(MessageType::Game::GET_NAME) == 71); +static_assert(static_cast(MessageType::Game::SET_NAME) == 72); +static_assert(static_cast(MessageType::Game::IS_NAME_LOCALIZED) == 73); +static_assert(static_cast(MessageType::Game::GET_HAIR_COLOR) == 74); +static_assert(static_cast(MessageType::Game::SET_HAIR_COLOR) == 75); +static_assert(static_cast(MessageType::Game::GET_HAIR_STYLE) == 76); +static_assert(static_cast(MessageType::Game::SET_HAIR_STYLE) == 77); +static_assert(static_cast(MessageType::Game::GET_HEAD) == 78); +static_assert(static_cast(MessageType::Game::SET_HEAD) == 79); +static_assert(static_cast(MessageType::Game::GET_TORSO) == 80); +static_assert(static_cast(MessageType::Game::SET_TORSO) == 81); +static_assert(static_cast(MessageType::Game::GET_LEGS) == 82); +static_assert(static_cast(MessageType::Game::SET_LEGS) == 83); +static_assert(static_cast(MessageType::Game::SET_PROXIMITY_RADIUS) == 84); +static_assert(static_cast(MessageType::Game::PROXIMITY_UPDATE) == 85); +static_assert(static_cast(MessageType::Game::GET_PROXIMITY_OBJECTS) == 86); +static_assert(static_cast(MessageType::Game::UNSET_PROXIMITY_RADIUS) == 87); +static_assert(static_cast(MessageType::Game::CLEAR_PROXIMITY_RADIUS) == 88); +static_assert(static_cast(MessageType::Game::GET_PROXIMITY_DATA) == 89); +static_assert(static_cast(MessageType::Game::SET_PROXIMITY_RADIUS_ICON) == 90); +static_assert(static_cast(MessageType::Game::TOGGLE_TAC_ARC) == 93); +static_assert(static_cast(MessageType::Game::CAST_SKILL) == 95); +static_assert(static_cast(MessageType::Game::CAST_LOCAL_SKILL) == 96); +static_assert(static_cast(MessageType::Game::ECHO_LOCAL_SKILL) == 97); +static_assert(static_cast(MessageType::Game::QUEUE_AI_SKILL) == 98); +static_assert(static_cast(MessageType::Game::ADD_THREAT_RATING) == 99); +static_assert(static_cast(MessageType::Game::GET_THREAT_RATING) == 100); +static_assert(static_cast(MessageType::Game::CLEAR_THREAT_LIST) == 103); +static_assert(static_cast(MessageType::Game::GET_TIME_FOR_NPC_SKILL) == 111); +static_assert(static_cast(MessageType::Game::ENEMY_HEAL_NOTIFICATION) == 112); +static_assert(static_cast(MessageType::Game::RESET_SCRIPTED_AI_STATE) == 113); +static_assert(static_cast(MessageType::Game::ENABLE_COMBAT_AI_COMPONENT) == 114); +static_assert(static_cast(MessageType::Game::COMBAT_AI_FORCE_TETHER) == 115); +static_assert(static_cast(MessageType::Game::SUSPEND_MOVEMENT_AI) == 116); +static_assert(static_cast(MessageType::Game::NOTIFY_SCRIPT_VARS_INITIALIZED) == 117); +static_assert(static_cast(MessageType::Game::ECHO_START_SKILL) == 118); +static_assert(static_cast(MessageType::Game::START_SKILL) == 119); +static_assert(static_cast(MessageType::Game::CASTER_DEAD) == 120); +static_assert(static_cast(MessageType::Game::VERIFY_ACK) == 121); +static_assert(static_cast(MessageType::Game::ADD_PENDING_VERIFY) == 122); +static_assert(static_cast(MessageType::Game::MAP_SKILL) == 123); +static_assert(static_cast(MessageType::Game::SELECT_SKILL) == 124); +static_assert(static_cast(MessageType::Game::CAST_ACTIVE_SKILL) == 125); +static_assert(static_cast(MessageType::Game::MODIFY_SKILL_COOLDOWN) == 126); +static_assert(static_cast(MessageType::Game::ADD_SKILL) == 127); +static_assert(static_cast(MessageType::Game::REMOVE_SKILL) == 128); +static_assert(static_cast(MessageType::Game::LOG) == 129); +static_assert(static_cast(MessageType::Game::LOG_CHAT) == 130); +static_assert(static_cast(MessageType::Game::SET_MAX_CURRENCY) == 131); +static_assert(static_cast(MessageType::Game::GET_MAX_CURRENCY) == 132); +static_assert(static_cast(MessageType::Game::SET_CURRENCY) == 133); +static_assert(static_cast(MessageType::Game::GET_CURRENCY) == 134); +static_assert(static_cast(MessageType::Game::ADD_PENDING_CURRENCY) == 136); +static_assert(static_cast(MessageType::Game::PICKUP_CURRENCY) == 137); +static_assert(static_cast(MessageType::Game::SERVER_DELETE_LOOT_ITEM) == 138); +static_assert(static_cast(MessageType::Game::PICKUP_ITEM) == 139); +static_assert(static_cast(MessageType::Game::TEAM_PICKUP_ITEM) == 140); +static_assert(static_cast(MessageType::Game::CLIENT_DELETE_LOOT_ITEM) == 141); +static_assert(static_cast(MessageType::Game::CLIENT_SET_LOOT_ITEM_FFA) == 143); +static_assert(static_cast(MessageType::Game::COLLISION_PHANTOM) == 144); +static_assert(static_cast(MessageType::Game::OFF_COLLISION_PHANTOM) == 145); +static_assert(static_cast(MessageType::Game::COLLISION_PROXIMITY) == 146); +static_assert(static_cast(MessageType::Game::OFF_COLLISION_PROXIMITY) == 147); +static_assert(static_cast(MessageType::Game::COLLISION) == 148); +static_assert(static_cast(MessageType::Game::OFF_COLLISION) == 149); +static_assert(static_cast(MessageType::Game::GET_SKILLS) == 150); +static_assert(static_cast(MessageType::Game::CLEAR_FX_SINGLE_EFFECT) == 152); +static_assert(static_cast(MessageType::Game::GET_FX_EXIST_EFFECT) == 153); +static_assert(static_cast(MessageType::Game::PLAY_FX_EFFECT) == 154); +static_assert(static_cast(MessageType::Game::STOP_FX_EFFECT) == 155); +static_assert(static_cast(MessageType::Game::CLEAR_FX_ALL_CREATE_EFFECTS) == 156); +static_assert(static_cast(MessageType::Game::UPDATE_FX_ALL_CREATE_EFFECTS) == 157); +static_assert(static_cast(MessageType::Game::REQUEST_RESURRECT) == 159); +static_assert(static_cast(MessageType::Game::RESURRECT) == 160); +static_assert(static_cast(MessageType::Game::UPDATE_FROM_GHOST) == 162); +static_assert(static_cast(MessageType::Game::FETCH_GHOST) == 163); +static_assert(static_cast(MessageType::Game::KFM_LOADED) == 164); +static_assert(static_cast(MessageType::Game::NIF_LOADED) == 165); +static_assert(static_cast(MessageType::Game::HKX_LOADED) == 166); +static_assert(static_cast(MessageType::Game::MOVE_TO_DELETE_QUEUE) == 167); +static_assert(static_cast(MessageType::Game::RESTORE_FROM_DELETE_QUEUE) == 168); +static_assert(static_cast(MessageType::Game::IS_ENEMY) == 169); +static_assert(static_cast(MessageType::Game::GET_FACTION) == 170); +static_assert(static_cast(MessageType::Game::SET_IMAGINATION) == 171); +static_assert(static_cast(MessageType::Game::GET_IMAGINATION) == 172); +static_assert(static_cast(MessageType::Game::SET_MAX_IMAGINATION) == 173); +static_assert(static_cast(MessageType::Game::GET_MAX_IMAGINATION) == 174); +static_assert(static_cast(MessageType::Game::MODIFY_IMAGINATION) == 175); +static_assert(static_cast(MessageType::Game::MODIFY_MAX_IMAGINATION) == 176); +static_assert(static_cast(MessageType::Game::SET_HEALTH) == 177); +static_assert(static_cast(MessageType::Game::GET_HEALTH) == 178); +static_assert(static_cast(MessageType::Game::SET_MAX_HEALTH) == 179); +static_assert(static_cast(MessageType::Game::GET_MAX_HEALTH) == 180); +static_assert(static_cast(MessageType::Game::MODIFY_HEALTH) == 181); +static_assert(static_cast(MessageType::Game::MODIFY_MAX_HEALTH) == 182); +static_assert(static_cast(MessageType::Game::SET_ARMOR) == 183); +static_assert(static_cast(MessageType::Game::GET_ARMOR) == 184); +static_assert(static_cast(MessageType::Game::SET_MAX_ARMOR) == 185); +static_assert(static_cast(MessageType::Game::GET_MAX_ARMOR) == 186); +static_assert(static_cast(MessageType::Game::MODIFY_ARMOR) == 187); +static_assert(static_cast(MessageType::Game::MODIFY_MAX_ARMOR) == 188); +static_assert(static_cast(MessageType::Game::POP_HEALTH_STATE) == 190); +static_assert(static_cast(MessageType::Game::PUSH_EQUIPPED_ITEMS_STATE) == 191); +static_assert(static_cast(MessageType::Game::POP_EQUIPPED_ITEMS_STATE) == 192); +static_assert(static_cast(MessageType::Game::SET_GM_LEVEL) == 193); +static_assert(static_cast(MessageType::Game::GET_GM_LEVEL) == 194); +static_assert(static_cast(MessageType::Game::ADD_STATUS_EFFECT) == 196); +static_assert(static_cast(MessageType::Game::REMOVE_STATUS_EFFECT) == 197); +static_assert(static_cast(MessageType::Game::SET_STUNNED) == 198); +static_assert(static_cast(MessageType::Game::GET_STUNNED) == 199); +static_assert(static_cast(MessageType::Game::SET_STUN_IMMUNITY) == 200); +static_assert(static_cast(MessageType::Game::GET_STUN_IMMUNITY) == 201); +static_assert(static_cast(MessageType::Game::KNOCKBACK) == 202); +static_assert(static_cast(MessageType::Game::SET_VISIBLE) == 203); +static_assert(static_cast(MessageType::Game::GET_VISIBLE) == 204); +static_assert(static_cast(MessageType::Game::REPORT_ITEM_INFO) == 205); +static_assert(static_cast(MessageType::Game::GET_REBUILD_STATE) == 207); +static_assert(static_cast(MessageType::Game::REBUILD_CANCEL) == 209); +static_assert(static_cast(MessageType::Game::REBUILD_START) == 211); +static_assert(static_cast(MessageType::Game::ENABLE_REBUILD) == 213); +static_assert(static_cast(MessageType::Game::SKILL_FAILURE) == 214); +static_assert(static_cast(MessageType::Game::IS_ATTACK_STANCE) == 216); +static_assert(static_cast(MessageType::Game::SET_OBJECT_RENDER) == 217); +static_assert(static_cast(MessageType::Game::REQUEST_MAPPED_SKILLS) == 218); +static_assert(static_cast(MessageType::Game::UI_SELECT_MAPPED_SKILL) == 219); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_ITEM_IN_SLOT) == 220); +static_assert(static_cast(MessageType::Game::GET_FIRST_INVENTORY_ITEM_BY_LOT) == 221); +static_assert(static_cast(MessageType::Game::GET_SMALLEST_INVENTORY_STACK_BY_LOT) == 222); +static_assert(static_cast(MessageType::Game::MOVE_ITEM_IN_INVENTORY) == 224); +static_assert(static_cast(MessageType::Game::ADD_ITEM_TO_INVENTORY_CLIENT_SYNC) == 227); +static_assert(static_cast(MessageType::Game::GET_EQUIPPED_ITEMS) == 229); +static_assert(static_cast(MessageType::Game::REMOVE_ITEM_FROM_INVENTORY) == 230); +static_assert(static_cast(MessageType::Game::EQUIP_INVENTORY) == 231); +static_assert(static_cast(MessageType::Game::UN_EQUIP_INVENTORY) == 233); +static_assert(static_cast(MessageType::Game::EQUIP_ITEM) == 234); +static_assert(static_cast(MessageType::Game::UN_EQUIP_ITEM) == 235); +static_assert(static_cast(MessageType::Game::IS_ITEM_RESPOND) == 236); +static_assert(static_cast(MessageType::Game::IS_ITEM_EQUIPPED) == 237); +static_assert(static_cast(MessageType::Game::ATTACH_ITEM) == 238); +static_assert(static_cast(MessageType::Game::DETACH_ITEM) == 239); +static_assert(static_cast(MessageType::Game::GET_NODE) == 240); +static_assert(static_cast(MessageType::Game::GET_LOT) == 241); +static_assert(static_cast(MessageType::Game::IS_ITEM_EQUIPPABLE) == 242); +static_assert(static_cast(MessageType::Game::GET_CURRENT_ANIMATION) == 243); +static_assert(static_cast(MessageType::Game::GET_INV_ITEM_COUNT) == 244); +static_assert(static_cast(MessageType::Game::POST_LOAD_EQUIP) == 245); +static_assert(static_cast(MessageType::Game::SET_PHYSICS_ACTIVE_STATE) == 246); +static_assert(static_cast(MessageType::Game::GET_CURRENT_SKILL_TAC_ARC) == 247); +static_assert(static_cast(MessageType::Game::OFFER_MISSION) == 248); +static_assert(static_cast(MessageType::Game::RESPOND_TO_MISSION) == 249); +static_assert(static_cast(MessageType::Game::GET_MISSION_STATE) == 250); +static_assert(static_cast(MessageType::Game::GET_MISSION_COMPLETE_TIMESTAMP) == 251); +static_assert(static_cast(MessageType::Game::NOTIFY_MISSION) == 254); +static_assert(static_cast(MessageType::Game::NOTIFY_MISSION_TASK) == 255); +static_assert(static_cast(MessageType::Game::ARE_GFX_LOADED) == 257); +static_assert(static_cast(MessageType::Game::ADDED_TO_WORLD) == 258); +static_assert(static_cast(MessageType::Game::REMOVE_EXTRA_GFX_FROM_PIPE) == 259); +static_assert(static_cast(MessageType::Game::HIDE_EQUIPED_WEAPON) == 260); +static_assert(static_cast(MessageType::Game::UN_HIDE_EQUIPED_WEAPON) == 261); +static_assert(static_cast(MessageType::Game::GET_ITEM_SLOT) == 262); +static_assert(static_cast(MessageType::Game::IS_CHARACTER) == 263); +static_assert(static_cast(MessageType::Game::SET_IMMUNITY) == 264); +static_assert(static_cast(MessageType::Game::TOGGLE_TOOLTIPS) == 266); +static_assert(static_cast(MessageType::Game::GET_TOOLTIPS_DISABLED) == 267); +static_assert(static_cast(MessageType::Game::GET_BOUNDING_INFO) == 268); +static_assert(static_cast(MessageType::Game::OVERRIDE_BOUNDING_RADIUS) == 269); +static_assert(static_cast(MessageType::Game::GET_OFFSCREEN) == 270); +static_assert(static_cast(MessageType::Game::USE_STATE_MACHINE) == 271); +static_assert(static_cast(MessageType::Game::ADD_STATE) == 272); +static_assert(static_cast(MessageType::Game::ADD_SUB_STATE) == 273); +static_assert(static_cast(MessageType::Game::SET_STATE) == 274); +static_assert(static_cast(MessageType::Game::SET_SUB_STATE) == 275); +static_assert(static_cast(MessageType::Game::ADD_MESSAGE) == 276); +static_assert(static_cast(MessageType::Game::RELOAD_SCRIPT) == 277); +static_assert(static_cast(MessageType::Game::RELOAD_ALL_SCRIPTS) == 278); +static_assert(static_cast(MessageType::Game::FRIEND_INVITE_MSG) == 279); +static_assert(static_cast(MessageType::Game::ADD_FRIEND_REPOSNSE_MSG) == 280); +static_assert(static_cast(MessageType::Game::REMOVE_FRIEND_RESPONSE_MSG) == 281); +static_assert(static_cast(MessageType::Game::ADD_FRIEND_FROM_UI_MSG) == 282); +static_assert(static_cast(MessageType::Game::GET_CACHED_FRIENDS_LIST_MSG) == 283); +static_assert(static_cast(MessageType::Game::REQUEST_NEW_FRIENDS_LIST_MSG) == 284); +static_assert(static_cast(MessageType::Game::REPOPULATE_FRIENDS_LIST_MSG) == 285); +static_assert(static_cast(MessageType::Game::ADD_IGNORE_REPONSE_MSG) == 286); +static_assert(static_cast(MessageType::Game::REMOVE_IGNORE_RESPONSE_MSG) == 287); +static_assert(static_cast(MessageType::Game::ADD_IGNORE_FROM_UI_MSG) == 288); +static_assert(static_cast(MessageType::Game::GET_CACHED_IGNORE_LIST_MSG) == 289); +static_assert(static_cast(MessageType::Game::REQUEST_NEW_IGNORE_LIST_MSG) == 290); +static_assert(static_cast(MessageType::Game::REMOVE_FRIEND_BY_NAME) == 291); +static_assert(static_cast(MessageType::Game::REMOVE_IGNORE_BY_NAME) == 292); +static_assert(static_cast(MessageType::Game::IS_PLAYER_IN_IGNORE_LIST_MSG) == 293); +static_assert(static_cast(MessageType::Game::REPOPULATE_IGNORE_LIST_MSG) == 294); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_LIST) == 295); +static_assert(static_cast(MessageType::Game::UPDATE_FRIEND_MSG) == 296); +static_assert(static_cast(MessageType::Game::UPDATE_FRIEND_NAME_MSG) == 297); +static_assert(static_cast(MessageType::Game::UPDATE_IGNORE_NAME_MSG) == 298); +static_assert(static_cast(MessageType::Game::DEPARTED) == 299); +static_assert(static_cast(MessageType::Game::ARRIVED) == 300); +static_assert(static_cast(MessageType::Game::TEMPLATE_CHANGE_WAYPOINTS) == 301); +static_assert(static_cast(MessageType::Game::CANCELLED) == 302); +static_assert(static_cast(MessageType::Game::FLUSH_CACHED_GRAPHICS) == 303); +static_assert(static_cast(MessageType::Game::FOLLOW_TARGET) == 304); +static_assert(static_cast(MessageType::Game::TIMER_DONE) == 305); +static_assert(static_cast(MessageType::Game::TIMER_CANCELLED) == 306); +static_assert(static_cast(MessageType::Game::SET_TETHER_POINT) == 307); +static_assert(static_cast(MessageType::Game::GET_TETHER_POINT) == 308); +static_assert(static_cast(MessageType::Game::LEFT_TETHER_RADIUS) == 309); +static_assert(static_cast(MessageType::Game::GET_SCRIPT_VARS_PTR) == 310); +static_assert(static_cast(MessageType::Game::FACE_TARGET) == 311); +static_assert(static_cast(MessageType::Game::ROTATE_BY_DEGREES) == 312); +static_assert(static_cast(MessageType::Game::STRING_RENDERED) == 313); +static_assert(static_cast(MessageType::Game::RESET_PRIMARY_ANIMATION) == 314); +static_assert(static_cast(MessageType::Game::FACE_PLAY_STREAM) == 315); +static_assert(static_cast(MessageType::Game::TORSO_PLAY_STREAM) == 316); +static_assert(static_cast(MessageType::Game::CAN_PICKUP) == 317); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_SIZE) == 318); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_COUNT) == 319); +static_assert(static_cast(MessageType::Game::GET_OBJECTS_IN_GROUP) == 320); +static_assert(static_cast(MessageType::Game::HIDE_ITEM) == 321); +static_assert(static_cast(MessageType::Game::IS_OBJECT_IN_FOV) == 322); +static_assert(static_cast(MessageType::Game::GET_TYPE) == 323); +static_assert(static_cast(MessageType::Game::TEAM_INVITE_MSG) == 324); +static_assert(static_cast(MessageType::Game::TEAM_GET_SIZE) == 325); +static_assert(static_cast(MessageType::Game::TEAM_REQUEST_SET_LOOT) == 326); +static_assert(static_cast(MessageType::Game::TEAM_REMOVE_PLAYER_MSG) == 327); +static_assert(static_cast(MessageType::Game::TEAM_UPDATE_PLAYER_NAME_MSG) == 328); +static_assert(static_cast(MessageType::Game::SET_UPDATABLE) == 329); +static_assert(static_cast(MessageType::Game::REQUEST_TEAM_UI_UPDATE) == 330); +static_assert(static_cast(MessageType::Game::SET_COLLISION_GROUP) == 331); +static_assert(static_cast(MessageType::Game::GET_COLLISION_GROUP) == 332); +static_assert(static_cast(MessageType::Game::GET_ORIGINAL_COLLISION_GROUP) == 333); +static_assert(static_cast(MessageType::Game::SET_COLLISION_GROUP_TO_ORIGINAL) == 334); +static_assert(static_cast(MessageType::Game::GET_OBJECT_RADIUS) == 335); +static_assert(static_cast(MessageType::Game::REBUILD_NOTIFY_STATE) == 336); +static_assert(static_cast(MessageType::Game::GET_PLAYER_INTERACTION) == 337); +static_assert(static_cast(MessageType::Game::SET_PLAYER_INTERACTION) == 338); +static_assert(static_cast(MessageType::Game::FORCE_PLAYER_TO_INTERACT) == 339); +static_assert(static_cast(MessageType::Game::GET_SELECTED_POTENTIAL_INTERACTION) == 340); +static_assert(static_cast(MessageType::Game::SET_SELECTED_POTENTIAL_INTERACTION) == 341); +static_assert(static_cast(MessageType::Game::GET_INTERACTION_DISTANCE) == 342); +static_assert(static_cast(MessageType::Game::SET_INTERACTION_DISTANCE) == 343); +static_assert(static_cast(MessageType::Game::CALCULATE_INTERACTION_DISTANCE) == 344); +static_assert(static_cast(MessageType::Game::INTERACTION_ATTEMPT_FROM_OUT_OF_RANGE) == 345); +static_assert(static_cast(MessageType::Game::SET_PICKING_TARGET) == 346); +static_assert(static_cast(MessageType::Game::CLIENT_UNUSE) == 347); +static_assert(static_cast(MessageType::Game::BEGIN_PET_INTERACTION) == 348); +static_assert(static_cast(MessageType::Game::WANTS_INTERACTION_ICON) == 349); +static_assert(static_cast(MessageType::Game::PROPERTY_EDIT_ICON_INTERACTION) == 350); +static_assert(static_cast(MessageType::Game::PROPERTY_MODEL_INTERACTION) == 351); +static_assert(static_cast(MessageType::Game::GET_INTERACTION_DETAILS) == 352); +static_assert(static_cast(MessageType::Game::GET_DISABLED_INTERACTION_TYPES) == 353); +static_assert(static_cast(MessageType::Game::GET_INTERACTION_INFO) == 354); +static_assert(static_cast(MessageType::Game::INTERACTION_GAME_STATE_CHANGE) == 355); +static_assert(static_cast(MessageType::Game::TOGGLE_INTERACTION_UPDATES) == 356); +static_assert(static_cast(MessageType::Game::TERMINATE_INTERACTION) == 357); +static_assert(static_cast(MessageType::Game::SERVER_TERMINATE_INTERACTION) == 358); +static_assert(static_cast(MessageType::Game::GET_PLAYERS_TARGET_FOR_SELECTION) == 359); +static_assert(static_cast(MessageType::Game::PROCESS_INTERACTION_UNDER_CURSOR) == 360); +static_assert(static_cast(MessageType::Game::HANDLE_INTERACT_ACTION) == 361); +static_assert(static_cast(MessageType::Game::ATTEMPT_INTERACTION) == 362); +static_assert(static_cast(MessageType::Game::HANDLE_INTERACTION_CAMERA) == 363); +static_assert(static_cast(MessageType::Game::REQUEST_USE) == 364); +static_assert(static_cast(MessageType::Game::CLIENT_USE) == 366); +static_assert(static_cast(MessageType::Game::GET_PLAYER_MULTI_INTERACTION) == 367); +static_assert(static_cast(MessageType::Game::GET_MULTI_INTERACTION_STATE) == 368); +static_assert(static_cast(MessageType::Game::VENDOR_OPEN_WINDOW) == 369); +static_assert(static_cast(MessageType::Game::VENDOR_CLOSE_WINDOW) == 370); +static_assert(static_cast(MessageType::Game::EMOTE_PLAYED) == 371); +static_assert(static_cast(MessageType::Game::EMOTE_RECEIVED) == 372); +static_assert(static_cast(MessageType::Game::BUY_FROM_VENDOR) == 373); +static_assert(static_cast(MessageType::Game::SELL_TO_VENDOR) == 374); +static_assert(static_cast(MessageType::Game::ADD_DONATION_ITEM) == 375); +static_assert(static_cast(MessageType::Game::REMOVE_DONATION_ITEM) == 376); +static_assert(static_cast(MessageType::Game::CONFIRM_DONATION_ON_PLAYER) == 378); +static_assert(static_cast(MessageType::Game::CANCEL_DONATION_ON_PLAYER) == 379); +static_assert(static_cast(MessageType::Game::TEAM_GET_LEADER) == 380); +static_assert(static_cast(MessageType::Game::TEAM_GET_ON_WORLD_MEMBERS) == 381); +static_assert(static_cast(MessageType::Game::TEAM_GET_ALL_MEMBERS) == 382); +static_assert(static_cast(MessageType::Game::TEAM_SET_OFF_WORLD_FLAG) == 383); +static_assert(static_cast(MessageType::Game::SET_TRANSPARENCY) == 385); +static_assert(static_cast(MessageType::Game::GET_PREFERS_FADE) == 386); +static_assert(static_cast(MessageType::Game::PROJECTILE_IMPACT) == 387); +static_assert(static_cast(MessageType::Game::SET_PROJECTILE_PARAMS) == 388); +static_assert(static_cast(MessageType::Game::SET_INVENTORY_SIZE) == 389); +static_assert(static_cast(MessageType::Game::ACKNOWLEDGE_POSSESSION) == 391); +static_assert(static_cast(MessageType::Game::SET_POSSESSED_OBJECT) == 392); +static_assert(static_cast(MessageType::Game::CHANGE_POSSESSOR) == 393); +static_assert(static_cast(MessageType::Game::GET_POSSESSION_TYPE) == 395); +static_assert(static_cast(MessageType::Game::GET_POSSESSED_OBJECT) == 396); +static_assert(static_cast(MessageType::Game::GET_POSSESSOR) == 397); +static_assert(static_cast(MessageType::Game::IS_POSSESSED) == 398); +static_assert(static_cast(MessageType::Game::ENABLE_ACTIVITY) == 399); +static_assert(static_cast(MessageType::Game::SET_SHOOTING_GALLERY_PARAMS) == 400); +static_assert(static_cast(MessageType::Game::OPEN_ACTIVITY_START_DIALOG) == 401); +static_assert(static_cast(MessageType::Game::REQUEST_ACTIVITY_START_STOP) == 402); +static_assert(static_cast(MessageType::Game::REQUEST_ACTIVITY_ENTER) == 403); +static_assert(static_cast(MessageType::Game::REQUEST_ACTIVITY_EXIT) == 404); +static_assert(static_cast(MessageType::Game::ACTIVITY_ENTER) == 405); +static_assert(static_cast(MessageType::Game::ACTIVITY_EXIT) == 406); +static_assert(static_cast(MessageType::Game::ACTIVITY_START) == 407); +static_assert(static_cast(MessageType::Game::ACTIVITY_STOP) == 408); +static_assert(static_cast(MessageType::Game::SHOOTING_GALLERY_CLIENT_AIM_UPDATE) == 409); +static_assert(static_cast(MessageType::Game::ROTATE_TO_POINT) == 410); +static_assert(static_cast(MessageType::Game::SHOOTING_GALLERY_FIRE) == 411); +static_assert(static_cast(MessageType::Game::CALCULATE_FIRING_PARAMETERS) == 412); +static_assert(static_cast(MessageType::Game::GET_MUZZLE_OFFSET) == 413); +static_assert(static_cast(MessageType::Game::GET_ACTIVITY_POINTS) == 414); +static_assert(static_cast(MessageType::Game::TEAM_IS_ON_WORLD_MEMBER) == 415); +static_assert(static_cast(MessageType::Game::REQUEST_VENDOR_STATUS_UPDATE) == 416); +static_assert(static_cast(MessageType::Game::VENDOR_STATUS_UPDATE) == 417); +static_assert(static_cast(MessageType::Game::CANCEL_MISSION) == 418); +static_assert(static_cast(MessageType::Game::RESET_MISSIONS) == 419); +static_assert(static_cast(MessageType::Game::RENDER_COMPONENT_READY) == 420); +static_assert(static_cast(MessageType::Game::SEND_MINIFIG_DECALS) == 421); +static_assert(static_cast(MessageType::Game::PHYSICS_COMPONENT_READY) == 422); +static_assert(static_cast(MessageType::Game::ENTER_STANDBY_MODE) == 423); +static_assert(static_cast(MessageType::Game::LEAVE_STANDBY_MODE) == 424); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_SHOOTING_GALLERY_SCORE) == 425); +static_assert(static_cast(MessageType::Game::REQUEST_CONSUME_ITEM) == 426); +static_assert(static_cast(MessageType::Game::CONSUME_CLIENT_ITEM) == 427); +static_assert(static_cast(MessageType::Game::CLIENT_ITEM_CONSUMED) == 428); +static_assert(static_cast(MessageType::Game::QUERY_STANDBY_MODE) == 429); +static_assert(static_cast(MessageType::Game::GET_NI_BOUND) == 430); +static_assert(static_cast(MessageType::Game::MISSION_FAILURE) == 431); +static_assert(static_cast(MessageType::Game::GET_ANIMATION_TIME) == 432); +static_assert(static_cast(MessageType::Game::GET_CURRENT_ACTIVITY) == 434); +static_assert(static_cast(MessageType::Game::SET_EYEBROWS) == 435); +static_assert(static_cast(MessageType::Game::GET_EYEBROWS) == 436); +static_assert(static_cast(MessageType::Game::SET_EYES) == 437); +static_assert(static_cast(MessageType::Game::GET_EYES) == 438); +static_assert(static_cast(MessageType::Game::SET_MOUTH) == 439); +static_assert(static_cast(MessageType::Game::GET_MOUTH) == 440); +static_assert(static_cast(MessageType::Game::IS_OBJECT_SMASHABLE) == 441); +static_assert(static_cast(MessageType::Game::SMASHABLE_STATE_CHANGED) == 443); +static_assert(static_cast(MessageType::Game::USE_STATE_LOGGER) == 444); +static_assert(static_cast(MessageType::Game::ROTATE_SUB_NODE) == 445); +static_assert(static_cast(MessageType::Game::GET_SUB_NODE_POSITION) == 446); +static_assert(static_cast(MessageType::Game::GET_SUB_NODE) == 447); +static_assert(static_cast(MessageType::Game::UPDATE_SHOOTING_GALLERY_ROTATION) == 448); +static_assert(static_cast(MessageType::Game::RENDER_FLOATING_TEXT) == 449); +static_assert(static_cast(MessageType::Game::REQUEST2_D_TEXT_ELEMENT) == 450); +static_assert(static_cast(MessageType::Game::UPDATE2_D_TEXT_ELEMENT) == 451); +static_assert(static_cast(MessageType::Game::REMOVE2_D_TEXT_ELEMENT) == 452); +static_assert(static_cast(MessageType::Game::SET_COLOR) == 453); +static_assert(static_cast(MessageType::Game::GET_COLOR) == 454); +static_assert(static_cast(MessageType::Game::HKX_CHARACTER_LOADED) == 455); +static_assert(static_cast(MessageType::Game::ACTIVATE_PHYSICS) == 457); +static_assert(static_cast(MessageType::Game::SET_ICON_ABOVE_HEAD) == 458); +static_assert(static_cast(MessageType::Game::ADD_ICON_COMPOSITE) == 459); +static_assert(static_cast(MessageType::Game::CLEAR_ICON_COMPOSITES) == 460); +static_assert(static_cast(MessageType::Game::ICON_NIF_LOADED) == 461); +static_assert(static_cast(MessageType::Game::ICON_KFM_LOADED) == 462); +static_assert(static_cast(MessageType::Game::GET_OVERHEAD_ICON_PROPERTIES_FROM_PARENT) == 463); +static_assert(static_cast(MessageType::Game::BOUNCE_PLAYER) == 464); +static_assert(static_cast(MessageType::Game::SET_USER_CTRL_COMP_PAUSE) == 466); +static_assert(static_cast(MessageType::Game::HAS_COLLIDED) == 467); +static_assert(static_cast(MessageType::Game::GET_TOOLTIP_FLAG) == 468); +static_assert(static_cast(MessageType::Game::SET_TOOLTIP_FLAG) == 469); +static_assert(static_cast(MessageType::Game::GET_FLAG) == 470); +static_assert(static_cast(MessageType::Game::SET_FLAG) == 471); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_FLAG_CHANGE) == 472); +static_assert(static_cast(MessageType::Game::CURSOR_ON) == 473); +static_assert(static_cast(MessageType::Game::CURSOR_OFF) == 474); +static_assert(static_cast(MessageType::Game::HELP) == 475); +static_assert(static_cast(MessageType::Game::VENDOR_TRANSACTION_RESULT) == 476); +static_assert(static_cast(MessageType::Game::PERFORM_SPECIAL_DEATH) == 477); +static_assert(static_cast(MessageType::Game::GET_SHADER_ID) == 478); +static_assert(static_cast(MessageType::Game::GET_RENDER_ENVIRONMENT) == 479); +static_assert(static_cast(MessageType::Game::FINISHED_LOADING_SCENE) == 480); +static_assert(static_cast(MessageType::Game::GET_SKILL_INFO) == 481); +static_assert(static_cast(MessageType::Game::ACTIVITY_CANCEL) == 482); +static_assert(static_cast(MessageType::Game::MISSION_USES_OBJECT) == 483); +static_assert(static_cast(MessageType::Game::GET_POSITIONAL_ID) == 484); +static_assert(static_cast(MessageType::Game::SET_COLLECTIBLE_STATUS) == 485); +static_assert(static_cast(MessageType::Game::HAS_BEEN_COLLECTED) == 486); +static_assert(static_cast(MessageType::Game::HAS_BEEN_COLLECTED_BY_CLIENT) == 487); +static_assert(static_cast(MessageType::Game::GET_POS_UPDATE_STATS) == 488); +static_assert(static_cast(MessageType::Game::GET_NUM_VIEWERS_SCOPING_THIS) == 489); +static_assert(static_cast(MessageType::Game::GET_ACTIVITY_USER) == 490); +static_assert(static_cast(MessageType::Game::GET_ALL_ACTIVITY_USERS) == 491); +static_assert(static_cast(MessageType::Game::GET_MISSION_FOR_PLAYER) == 492); +static_assert(static_cast(MessageType::Game::SET_FACTION) == 493); +static_assert(static_cast(MessageType::Game::SET_PLATFORM_IDLE_STATE) == 494); +static_assert(static_cast(MessageType::Game::DISPLAY_CHAT_BUBBLE) == 495); +static_assert(static_cast(MessageType::Game::REQUEST_CHAT_BUBBLE_ELEMENT) == 496); +static_assert(static_cast(MessageType::Game::GET_MISSION_DATA) == 497); +static_assert(static_cast(MessageType::Game::SPAWN_PET) == 498); +static_assert(static_cast(MessageType::Game::DESPAWN_PET) == 499); +static_assert(static_cast(MessageType::Game::SET_LOCAL_SPACE_STATE) == 500); +static_assert(static_cast(MessageType::Game::GET_LOCAL_SPACE_STATE) == 501); +static_assert(static_cast(MessageType::Game::SET_POSITION_TO_LOCAL_POSITION) == 502); +static_assert(static_cast(MessageType::Game::ALLOW_LOCAL_SPACE_UPDATE) == 503); +static_assert(static_cast(MessageType::Game::TOGGLE_FREE_CAM_MODE) == 504); +static_assert(static_cast(MessageType::Game::PLAYER_LOADED) == 505); +static_assert(static_cast(MessageType::Game::PLAYER_ADDED_TO_WORLD_LOCAL) == 506); +static_assert(static_cast(MessageType::Game::OBJECT_LOADED) == 507); +static_assert(static_cast(MessageType::Game::GET_PLAYER_READY) == 508); +static_assert(static_cast(MessageType::Game::PLAYER_READY) == 509); +static_assert(static_cast(MessageType::Game::SET_SMASHABLE_PARAMS) == 510); +static_assert(static_cast(MessageType::Game::IS_LOOTABLE_CHEST) == 511); +static_assert(static_cast(MessageType::Game::LOOT_OPEN_WINDOW) == 512); +static_assert(static_cast(MessageType::Game::LOOT_SELECTION_UPDATE) == 513); +static_assert(static_cast(MessageType::Game::TAKE_LOOT_CHEST_ITEM) == 514); +static_assert(static_cast(MessageType::Game::REQUEST_LINKED_MISSION) == 515); +static_assert(static_cast(MessageType::Game::TRANSFER_TO_ZONE) == 516); +static_assert(static_cast(MessageType::Game::TRANSFER_TO_ZONE_CHECKED_IM) == 517); +static_assert(static_cast(MessageType::Game::SECURED_TRANSFER_TO_ZONE) == 518); +static_assert(static_cast(MessageType::Game::INVALID_ZONE_TRANSFER_LIST) == 519); +static_assert(static_cast(MessageType::Game::MISSION_DIALOGUE_OK) == 520); +static_assert(static_cast(MessageType::Game::GET_OBJECT_IN_SCOPE) == 521); +static_assert(static_cast(MessageType::Game::SET_LAUNCHED_STATE) == 522); +static_assert(static_cast(MessageType::Game::P_CREATE_EFFECT_FINISHED) == 523); +static_assert(static_cast(MessageType::Game::SMASHED_OBJECT) == 524); +static_assert(static_cast(MessageType::Game::CHECK_SMASHCHAIN_OVERRIDE) == 525); +static_assert(static_cast(MessageType::Game::DISPLAY_REBUILD_ACTIVATOR) == 526); +static_assert(static_cast(MessageType::Game::TRANSFER_TO_LAST_NON_INSTANCE) == 527); +static_assert(static_cast(MessageType::Game::SET_ACTIVE_LOCAL_CHARACTER_ID) == 528); +static_assert(static_cast(MessageType::Game::DISPLAY_MESSAGE_BOX) == 529); +static_assert(static_cast(MessageType::Game::MESSAGE_BOX_RESPOND) == 530); +static_assert(static_cast(MessageType::Game::CHOICE_BOX_RESPOND) == 531); +static_assert(static_cast(MessageType::Game::SERVER_SET_USER_CTRL_COMP_PAUSE) == 532); +static_assert(static_cast(MessageType::Game::SET_CHARACTER_AUTO_RUN) == 533); +static_assert(static_cast(MessageType::Game::FOLLOW_WAYPOINTS) == 534); +static_assert(static_cast(MessageType::Game::SWAP_DECAL_AND_COLOR) == 535); +static_assert(static_cast(MessageType::Game::CONTINUE_WAYPOINTS) == 536); +static_assert(static_cast(MessageType::Game::SMASH) == 537); +static_assert(static_cast(MessageType::Game::UN_SMASH) == 538); +static_assert(static_cast(MessageType::Game::GET_IS_SMASHED) == 539); +static_assert(static_cast(MessageType::Game::GET_UP_VECTOR) == 540); +static_assert(static_cast(MessageType::Game::SET_GRAVITY_SCALE) == 541); +static_assert(static_cast(MessageType::Game::SET_GRAVITY_SCALE_FOR_RIGID_BODY) == 542); +static_assert(static_cast(MessageType::Game::STOP_MOVING) == 543); +static_assert(static_cast(MessageType::Game::SET_PATHING_SPEED) == 544); +static_assert(static_cast(MessageType::Game::SET_SHIELDED) == 545); +static_assert(static_cast(MessageType::Game::SET_SHOOTING_GALLERY_RETICULE_EFFECT) == 546); +static_assert(static_cast(MessageType::Game::PLACE_MODEL_RESPONSE) == 547); +static_assert(static_cast(MessageType::Game::SET_DODGE_INFO) == 548); +static_assert(static_cast(MessageType::Game::GET_DODGE_INFO) == 549); +static_assert(static_cast(MessageType::Game::SET_SKILL_ATTACK_SPEED) == 550); +static_assert(static_cast(MessageType::Game::GET_SKILL_COOLDOWN_GROUP) == 551); +static_assert(static_cast(MessageType::Game::GET_INITIAL_SKILL_COOLDOWN) == 552); +static_assert(static_cast(MessageType::Game::GET_SKILL_COOLDOWN_REMAINING) == 553); +static_assert(static_cast(MessageType::Game::GET_GLOBAL_COOLDOWN) == 554); +static_assert(static_cast(MessageType::Game::SET_GLOBAL_COOLDOWN) == 555); +static_assert(static_cast(MessageType::Game::RESET_GLOBAL_COOLDOWN) == 556); +static_assert(static_cast(MessageType::Game::FINDINVENTORY_ITEM) == 558); +static_assert(static_cast(MessageType::Game::PATH_STUCK) == 559); +static_assert(static_cast(MessageType::Game::SET_CURRENT_PATH) == 560); +static_assert(static_cast(MessageType::Game::SET_JET_PACK_MODE) == 561); +static_assert(static_cast(MessageType::Game::SET_JET_PACK_TIME) == 562); +static_assert(static_cast(MessageType::Game::PET_FOLLOW_OWNER) == 563); +static_assert(static_cast(MessageType::Game::PLAYER_DIED) == 564); +static_assert(static_cast(MessageType::Game::REGISTER_PET_ID) == 565); +static_assert(static_cast(MessageType::Game::REGISTER_PET_DBID) == 566); +static_assert(static_cast(MessageType::Game::GET_PET_ID) == 567); +static_assert(static_cast(MessageType::Game::SHOW_ACTIVITY_COUNTDOWN) == 568); +static_assert(static_cast(MessageType::Game::DISPLAY_TOOLTIP) == 569); +static_assert(static_cast(MessageType::Game::SET_PHANTOM_BASE) == 570); +static_assert(static_cast(MessageType::Game::GET_MOTION_STATE) == 571); +static_assert(static_cast(MessageType::Game::GET_MOTION_CONFIG) == 572); +static_assert(static_cast(MessageType::Game::SET_ACTIVE_PROJECTILE_SKILL) == 573); +static_assert(static_cast(MessageType::Game::INITIALIZE_MISSION_VISUALS) == 574); +static_assert(static_cast(MessageType::Game::GET_MISSIONS) == 575); +static_assert(static_cast(MessageType::Game::START_ACTIVITY_TIME) == 576); +static_assert(static_cast(MessageType::Game::ADD_ACTIVITY_TIME) == 577); +static_assert(static_cast(MessageType::Game::GUILD_GET_SIZE) == 578); +static_assert(static_cast(MessageType::Game::GUILD_CAN_WE_INVITE) == 579); +static_assert(static_cast(MessageType::Game::GUILD_CAN_WE_KICK) == 580); +static_assert(static_cast(MessageType::Game::SET_CHAR_GUILD_INFO) == 581); +static_assert(static_cast(MessageType::Game::GET_CHAR_GUILD_INFO) == 582); +static_assert(static_cast(MessageType::Game::GET_CHAR_IS_IN_GUILD) == 583); +static_assert(static_cast(MessageType::Game::RE_RENDER_NAME_BILLBOARD) == 584); +static_assert(static_cast(MessageType::Game::IS_IN_LOCAL_CHAR_PROXIMITY) == 585); +static_assert(static_cast(MessageType::Game::GUILD_SET_STATUS) == 586); +static_assert(static_cast(MessageType::Game::GUILD_ADD_PLAYER) == 587); +static_assert(static_cast(MessageType::Game::GUILD_REMOVE_PLAYER) == 588); +static_assert(static_cast(MessageType::Game::GUILD_UPDATE_PLAYER_NAME) == 589); +static_assert(static_cast(MessageType::Game::GUILD_SET_PLAYER_RANK) == 590); +static_assert(static_cast(MessageType::Game::GUILD_SET_ONLINE_STATUS) == 591); +static_assert(static_cast(MessageType::Game::GUILD_INVITE) == 592); +static_assert(static_cast(MessageType::Game::REQUEST_GUILD_DATA) == 593); +static_assert(static_cast(MessageType::Game::POPULATE_GUILD_DATA) == 594); +static_assert(static_cast(MessageType::Game::GET_CACHED_GUILD_DATA) == 595); +static_assert(static_cast(MessageType::Game::GUILD_RENDER_NAME) == 596); +static_assert(static_cast(MessageType::Game::GET_IS_SUPPORTED) == 600); +static_assert(static_cast(MessageType::Game::CHARACTER_SUPPORT_CHANGED) == 601); +static_assert(static_cast(MessageType::Game::ACTIVITY_PAUSE) == 602); +static_assert(static_cast(MessageType::Game::USE_NON_EQUIPMENT_ITEM) == 603); +static_assert(static_cast(MessageType::Game::REQUEST_USE_ITEM_ON) == 604); +static_assert(static_cast(MessageType::Game::REQUEST_USE_ITEM_ON_TARGET) == 605); +static_assert(static_cast(MessageType::Game::USE_ITEM_ON) == 606); +static_assert(static_cast(MessageType::Game::USE_ITEM_RESULT) == 607); +static_assert(static_cast(MessageType::Game::GET_PARENT_OBJ) == 608); +static_assert(static_cast(MessageType::Game::SET_PARENT_OBJ) == 609); +static_assert(static_cast(MessageType::Game::GET_UPDATES_WITH_PARENT_POSITION) == 610); +static_assert(static_cast(MessageType::Game::PARENT_REMOVED) == 611); +static_assert(static_cast(MessageType::Game::PARENT_LEFT_SCOPE) == 612); +static_assert(static_cast(MessageType::Game::PARENT_ENTERED_SCOPE) == 613); +static_assert(static_cast(MessageType::Game::CHILD_LOADED) == 614); +static_assert(static_cast(MessageType::Game::CHILD_REMOVED) == 615); +static_assert(static_cast(MessageType::Game::CHILD_DETACHED) == 616); +static_assert(static_cast(MessageType::Game::CHILD_ENTERED_SCOPE) == 617); +static_assert(static_cast(MessageType::Game::CHILD_LEFT_SCOPE) == 618); +static_assert(static_cast(MessageType::Game::GET_CHILD_OBJECTS) == 619); +static_assert(static_cast(MessageType::Game::ZONE_TRANSFER_FINISHED) == 621); +static_assert(static_cast(MessageType::Game::CHAT_CONNECTION_UPDATE) == 622); +static_assert(static_cast(MessageType::Game::PLATFORM_AT_LAST_WAYPOINT) == 623); +static_assert(static_cast(MessageType::Game::LOOT_TAKE_ALL) == 624); +static_assert(static_cast(MessageType::Game::GET_EQUIPPED_ITEM_INFO) == 625); +static_assert(static_cast(MessageType::Game::DISPLAY_GUILD_CREATE_BOX) == 626); +static_assert(static_cast(MessageType::Game::GET_EDITOR_LEVEL) == 627); +static_assert(static_cast(MessageType::Game::GET_ACCOUNT_ID) == 628); +static_assert(static_cast(MessageType::Game::GET_LAST_LOGOUT) == 629); +static_assert(static_cast(MessageType::Game::GET_LAST_PROP_MOD_DISPLAY_TIME) == 630); +static_assert(static_cast(MessageType::Game::SET_LAST_PROP_MOD_DISPLAY_TIME) == 631); +static_assert(static_cast(MessageType::Game::SHOW_ACTIVITY_SUMMARY) == 632); +static_assert(static_cast(MessageType::Game::CAN_RECEIVE_ALL_REWARDS) == 633); +static_assert(static_cast(MessageType::Game::GET_ACTIVITY_REWARD) == 634); +static_assert(static_cast(MessageType::Game::LOOT_CLOSE_WINDOW) == 635); +static_assert(static_cast(MessageType::Game::GET_BLUEPRINT_ID) == 636); +static_assert(static_cast(MessageType::Game::NOTIFY_BLUEPRINT_UPDATE) == 637); +static_assert(static_cast(MessageType::Game::FETCH_MODEL_METADATA_REQUEST) == 638); +static_assert(static_cast(MessageType::Game::FETCH_MODEL_METADATA_RESPONSE) == 639); +static_assert(static_cast(MessageType::Game::COMMAND_PET) == 640); +static_assert(static_cast(MessageType::Game::PET_RESPONSE) == 641); +static_assert(static_cast(MessageType::Game::GET_ICON_ABOVE_HEAD_STATE) == 642); +static_assert(static_cast(MessageType::Game::GET_ICON_ABOVE_HEAD) == 643); +static_assert(static_cast(MessageType::Game::ICON_FINISHED_LOADING) == 644); +static_assert(static_cast(MessageType::Game::ADD_PET_STATE) == 645); +static_assert(static_cast(MessageType::Game::REMOVE_PET_STATE) == 646); +static_assert(static_cast(MessageType::Game::SET_PET_STATE) == 647); +static_assert(static_cast(MessageType::Game::REQUEST_ACTIVITY_SUMMARY_LEADERBOARD_DATA) == 648); +static_assert(static_cast(MessageType::Game::SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA) == 649); +static_assert(static_cast(MessageType::Game::SET_ON_TEAM) == 650); +static_assert(static_cast(MessageType::Game::GET_PET_HAS_STATE) == 651); +static_assert(static_cast(MessageType::Game::FIND_PROPERTY) == 652); +static_assert(static_cast(MessageType::Game::SET_PET_MOVEMENT_STATE) == 653); +static_assert(static_cast(MessageType::Game::GET_ITEM_TYPE) == 654); +static_assert(static_cast(MessageType::Game::GET_ITEM_INFO_KEY) == 655); +static_assert(static_cast(MessageType::Game::NOTIFY_OBJECT) == 656); +static_assert(static_cast(MessageType::Game::IS_PET_WILD) == 657); +static_assert(static_cast(MessageType::Game::CLIENT_NOTIFY_PET) == 659); +static_assert(static_cast(MessageType::Game::NOTIFY_PET) == 660); +static_assert(static_cast(MessageType::Game::NOTIFY_PET_TAMING_MINIGAME) == 661); +static_assert(static_cast(MessageType::Game::START_SERVER_PET_MINIGAME_TIMER) == 662); +static_assert(static_cast(MessageType::Game::CLIENT_EXIT_TAMING_MINIGAME) == 663); +static_assert(static_cast(MessageType::Game::GET_BUILDMODE_ACTIVE) == 664); +static_assert(static_cast(MessageType::Game::GET_PET_TAMING_MINIGAME_ACTIVE) == 665); +static_assert(static_cast(MessageType::Game::PET_TAMING_OBJECT_PICKED) == 666); +static_assert(static_cast(MessageType::Game::PET_TAMING_MINIGAME_RESULT) == 667); +static_assert(static_cast(MessageType::Game::PET_TAMING_TRY_BUILD_RESULT) == 668); +static_assert(static_cast(MessageType::Game::SET_PET_TAMING_MODEL) == 669); +static_assert(static_cast(MessageType::Game::GET_PET_TAMING_MODEL) == 670); +static_assert(static_cast(MessageType::Game::PET_ON_SWITCH) == 671); +static_assert(static_cast(MessageType::Game::PET_OFF_SWITCH) == 672); +static_assert(static_cast(MessageType::Game::NOTIFY_TAMING_BUILD_SUCCESS) == 673); +static_assert(static_cast(MessageType::Game::NOTIFY_TAMING_MODEL_LOADED_ON_SERVER) == 674); +static_assert(static_cast(MessageType::Game::NOTIFY_TAMING_PUZZLE_SELECTED) == 675); +static_assert(static_cast(MessageType::Game::GET_INSTRUCTION_COUNT) == 676); +static_assert(static_cast(MessageType::Game::GET_IS_NPC) == 677); +static_assert(static_cast(MessageType::Game::ACTIVATE_BUBBLE_BUFF) == 678); +static_assert(static_cast(MessageType::Game::DECTIVATE_BUBBLE_BUFF) == 679); +static_assert(static_cast(MessageType::Game::EXHIBIT_VOTE) == 680); +static_assert(static_cast(MessageType::Game::ADD_PET_TO_PLAYER) == 681); +static_assert(static_cast(MessageType::Game::REMOVE_PET_FROM_PLAYER) == 682); +static_assert(static_cast(MessageType::Game::REQUEST_SET_PET_NAME) == 683); +static_assert(static_cast(MessageType::Game::SET_PET_NAME) == 684); +static_assert(static_cast(MessageType::Game::PET_NAME_CHANGED) == 686); +static_assert(static_cast(MessageType::Game::GET_PET_AT_INDEX) == 687); +static_assert(static_cast(MessageType::Game::GET_LOT_FOR_PET_BY_DBID) == 688); +static_assert(static_cast(MessageType::Game::GET_NAME_FOR_PET_BY_DBID) == 689); +static_assert(static_cast(MessageType::Game::GET_ACTIVE_PET_OBJ_ID) == 690); +static_assert(static_cast(MessageType::Game::GET_ACTIVE_PET_INVENTORY_OBJ_ID) == 691); +static_assert(static_cast(MessageType::Game::SHOW_PET_ACTION_BUTTON) == 692); +static_assert(static_cast(MessageType::Game::SET_EMOTE_LOCK_STATE) == 693); +static_assert(static_cast(MessageType::Game::GET_EMOTE_LOCK_STATE) == 694); +static_assert(static_cast(MessageType::Game::LEAVE_TEAM_MSG) == 695); +static_assert(static_cast(MessageType::Game::TEAM_KICK_PLAYER_MSG) == 697); +static_assert(static_cast(MessageType::Game::TEAM_SET_LEADER_SEND_MSG) == 698); +static_assert(static_cast(MessageType::Game::USE_ITEM_ON_CLIENT) == 699); +static_assert(static_cast(MessageType::Game::DOES_FORWARD_TARGET_CLICKING) == 700); +static_assert(static_cast(MessageType::Game::CHECK_USE_REQUIREMENTS) == 701); +static_assert(static_cast(MessageType::Game::USE_REQUIREMENTS_RESPONSE) == 702); +static_assert(static_cast(MessageType::Game::USE_ITEM_REQUIREMENTS_RESPONSE) == 703); +static_assert(static_cast(MessageType::Game::PET_ADDED_TO_WORLD) == 704); +static_assert(static_cast(MessageType::Game::BOUNCER_TRIGGERED) == 705); +static_assert(static_cast(MessageType::Game::EXHIBIT_QUERY_CURRENT_MODEL) == 706); +static_assert(static_cast(MessageType::Game::EXHIBIT_QUERY_CURRENT_MODEL_RESPONSE) == 707); +static_assert(static_cast(MessageType::Game::EXHIBIT_ATTEMPT_VOTE) == 708); +static_assert(static_cast(MessageType::Game::EXHIBIT_VOTE_RESPONSE) == 709); +static_assert(static_cast(MessageType::Game::EHIBIT_REQUERYMODELS) == 710); +static_assert(static_cast(MessageType::Game::IS_SKILL_ACTIVE) == 711); +static_assert(static_cast(MessageType::Game::TOGGLE_ACTIVE_SKILL) == 712); +static_assert(static_cast(MessageType::Game::PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT) == 713); +static_assert(static_cast(MessageType::Game::EXHIBIT_GET_INFO) == 714); +static_assert(static_cast(MessageType::Game::GET_PROPERTY_DATA) == 715); +static_assert(static_cast(MessageType::Game::DOWNLOAD_PROPERTY_DATA) == 716); +static_assert(static_cast(MessageType::Game::QUERY_PROPERTY_DATA) == 717); +static_assert(static_cast(MessageType::Game::MODEL_MODERATION_ACTION) == 719); +static_assert(static_cast(MessageType::Game::NOTIFY_SERVER_UGC_REVIEW_READY) == 720); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_UGC_REVIEW_READY) == 721); +static_assert(static_cast(MessageType::Game::OLD_USE_ITEM_ON) == 722); +static_assert(static_cast(MessageType::Game::FIND_PROPERTY_FOR_SALE_RESPONSE) == 723); +static_assert(static_cast(MessageType::Game::PROPERTY_EDITOR_BEGIN) == 724); +static_assert(static_cast(MessageType::Game::PROPERTY_EDITOR_END) == 725); +static_assert(static_cast(MessageType::Game::PROPERTY_EDITOR_SET_MODE) == 726); +static_assert(static_cast(MessageType::Game::TOGGLE_TRIGGER) == 727); +static_assert(static_cast(MessageType::Game::FIRE_EVENT) == 728); +static_assert(static_cast(MessageType::Game::IS_MINIFIG_IN_A_BUBBLE) == 729); +static_assert(static_cast(MessageType::Game::GET_ITEM_INFO) == 730); +static_assert(static_cast(MessageType::Game::MISSION_NEEDS_LOT) == 731); +static_assert(static_cast(MessageType::Game::STOP_PATHING) == 732); +static_assert(static_cast(MessageType::Game::START_PATHING) == 733); +static_assert(static_cast(MessageType::Game::ACTIVATE_BUBBLE_BUFF_FROM_SERVER) == 734); +static_assert(static_cast(MessageType::Game::DEACTIVATE_BUBBLE_BUFF_FROM_SERVER) == 735); +static_assert(static_cast(MessageType::Game::HAS_SKILL) == 736); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_ZONE_OBJECT) == 737); +static_assert(static_cast(MessageType::Game::MOVE_OBJECT) == 738); +static_assert(static_cast(MessageType::Game::ROTATE_OBJECT) == 739); +static_assert(static_cast(MessageType::Game::GET_SPAWNER_CONFIG_DATA) == 740); +static_assert(static_cast(MessageType::Game::UPDATE_SPAWNER_CONFIG_DATA) == 741); +static_assert(static_cast(MessageType::Game::TURN_AROUND) == 743); +static_assert(static_cast(MessageType::Game::GO_FORWARD) == 744); +static_assert(static_cast(MessageType::Game::GO_BACKWARD) == 745); +static_assert(static_cast(MessageType::Game::UPDATE_REPUTATION) == 746); +static_assert(static_cast(MessageType::Game::GET_REPUTATION) == 747); +static_assert(static_cast(MessageType::Game::ADD_REPUTATION) == 748); +static_assert(static_cast(MessageType::Game::UPDATE_PROPERTY_DATA) == 749); +static_assert(static_cast(MessageType::Game::PROPERTY_RENTAL_RESPONSE) == 750); +static_assert(static_cast(MessageType::Game::EXHIBIT_PLACEMENT_RESPONSE) == 751); +static_assert(static_cast(MessageType::Game::SQUIRT_WITH_WATERGUN) == 752); +static_assert(static_cast(MessageType::Game::GET_VOTES_LEFT) == 753); +static_assert(static_cast(MessageType::Game::ADJUST_VOTES_LEFT) == 754); +static_assert(static_cast(MessageType::Game::EVADE_TARGET) == 755); +static_assert(static_cast(MessageType::Game::STOPPED_EVADING) == 756); +static_assert(static_cast(MessageType::Game::GET_PET_HAS_ABILITY) == 757); +static_assert(static_cast(MessageType::Game::REQUEST_PLATFORM_RESYNC) == 760); +static_assert(static_cast(MessageType::Game::PLATFORM_RESYNC) == 761); +static_assert(static_cast(MessageType::Game::PLAY_CINEMATIC) == 762); +static_assert(static_cast(MessageType::Game::END_CINEMATIC) == 763); +static_assert(static_cast(MessageType::Game::CINEMATIC_UPDATE) == 764); +static_assert(static_cast(MessageType::Game::ATTACH_CAMERA_TO_RAIL) == 765); +static_assert(static_cast(MessageType::Game::DETACH_CAMERA_FROM_RAIL) == 766); +static_assert(static_cast(MessageType::Game::TOGGLE_GHOST_REFERENCE_OVERRIDE) == 767); +static_assert(static_cast(MessageType::Game::SET_GHOST_REFERENCE_POSITION) == 768); +static_assert(static_cast(MessageType::Game::GET_GHOST_REFERENCE_POSITION) == 769); +static_assert(static_cast(MessageType::Game::FIRE_EVENT_SERVER_SIDE) == 770); +static_assert(static_cast(MessageType::Game::GET_PET_ABILITY_OBJECT) == 771); +static_assert(static_cast(MessageType::Game::TEAM_INVITE_MSG_FROM_UI) == 772); +static_assert(static_cast(MessageType::Game::ADD_CAMERA_EFFECT) == 773); +static_assert(static_cast(MessageType::Game::REMOVE_CAMERA_EFFECT) == 774); +static_assert(static_cast(MessageType::Game::REMOVE_ALL_CAMERA_EFFECTS) == 775); +static_assert(static_cast(MessageType::Game::GET_MY_PROPERTIES_IN_THIS_ZONE) == 776); +static_assert(static_cast(MessageType::Game::IS_MODEL_WITHIN_PROPERTY_BOUNDS) == 777); +static_assert(static_cast(MessageType::Game::PROPERTY_DATA_RESULTS) == 778); +static_assert(static_cast(MessageType::Game::ON_UN_SERIALIZE) == 779); +static_assert(static_cast(MessageType::Game::SCRIPT_NETWORK_VAR_UPDATE) == 781); +static_assert(static_cast(MessageType::Game::ADD_OBJECT_TO_GROUP) == 783); +static_assert(static_cast(MessageType::Game::REMOVE_OBJECT_FROM_GROUP) == 784); +static_assert(static_cast(MessageType::Game::IS_OBJECT_STATIC) == 785); +static_assert(static_cast(MessageType::Game::GET_HAS_MISSION) == 786); +static_assert(static_cast(MessageType::Game::GET_MISSION_TARGET_LOT) == 787); +static_assert(static_cast(MessageType::Game::GET_MISSION_OFFERER_LOT) == 788); +static_assert(static_cast(MessageType::Game::USE_UNIQUE_ITEM) == 789); +static_assert(static_cast(MessageType::Game::GET_IS_PET) == 790); +static_assert(static_cast(MessageType::Game::DELETE_PROPERTY) == 791); +static_assert(static_cast(MessageType::Game::CREATEMODEL_FROM_CLIENT) == 792); +static_assert(static_cast(MessageType::Game::UPDATE_MODEL_FROM_CLIENT) == 793); +static_assert(static_cast(MessageType::Game::DELETE_MODEL_FROM_CLIENT) == 794); +static_assert(static_cast(MessageType::Game::SHOW_PROPERTY_BOUNDS) == 795); +static_assert(static_cast(MessageType::Game::SET_PROPERTY_I_DS) == 796); +static_assert(static_cast(MessageType::Game::PLAY_FACE_DECAL_ANIMATION) == 797); +static_assert(static_cast(MessageType::Game::ADD_ACTIVITY_USER) == 798); +static_assert(static_cast(MessageType::Game::REMOVE_ACTIVITY_USER) == 799); +static_assert(static_cast(MessageType::Game::GET_NUM_ACTIVITY_USERS) == 800); +static_assert(static_cast(MessageType::Game::ACTIVITY_USER_EXISTS) == 801); +static_assert(static_cast(MessageType::Game::DO_COMPLETE_ACTIVITY_EVENTS) == 805); +static_assert(static_cast(MessageType::Game::SET_ACTIVITY_PARAMS) == 806); +static_assert(static_cast(MessageType::Game::SET_ACTIVITY_USER_DATA) == 807); +static_assert(static_cast(MessageType::Game::GET_ACTIVITY_USER_DATA) == 808); +static_assert(static_cast(MessageType::Game::DO_CALCULATE_ACTIVITY_RATING) == 809); +static_assert(static_cast(MessageType::Game::ND_AUDIO_POST_SETUP) == 812); +static_assert(static_cast(MessageType::Game::ND_AUDIO_PRE_SHUTDOWN) == 813); +static_assert(static_cast(MessageType::Game::SET_ND_AUDION_LISTENER_STANCE) == 814); +static_assert(static_cast(MessageType::Game::SET_UP_ND_AUDIO_EMIITTER) == 815); +static_assert(static_cast(MessageType::Game::SHUT_DOWN_ND_AUDIO_EMITTER) == 816); +static_assert(static_cast(MessageType::Game::METAIFY_ND_AUDIO_EMITTER) == 817); +static_assert(static_cast(MessageType::Game::UN_METAIFY_ND_AUDIO_EMITTER) == 818); +static_assert(static_cast(MessageType::Game::METAIFY_ND_AUDIO_EMITTERS) == 819); +static_assert(static_cast(MessageType::Game::UN_METAIFY_ND_AUDIO_EMITTERS) == 820); +static_assert(static_cast(MessageType::Game::PLAY_ND_AUDIO_EMITTER) == 821); +static_assert(static_cast(MessageType::Game::STOP_ND_AUDIO_EMITTER) == 822); +static_assert(static_cast(MessageType::Game::STOP_ND_AUDIO_EMITTER_ALL) == 823); +static_assert(static_cast(MessageType::Game::SET_ND_AUDIO_EMITTER_PARAMETER) == 824); +static_assert(static_cast(MessageType::Game::SET_ND_AUDIO_EMITTERS_PARAMETER) == 825); +static_assert(static_cast(MessageType::Game::ND_AUDIO_CALLBACK) == 826); +static_assert(static_cast(MessageType::Game::ACTIVATE_ND_AUDIO_MUSIC_CUE) == 827); +static_assert(static_cast(MessageType::Game::DEACTIVATE_ND_AUDIO_MUSIC_CUE) == 828); +static_assert(static_cast(MessageType::Game::FLASH_ND_AUDIO_MUSIC_CUE) == 829); +static_assert(static_cast(MessageType::Game::SET_ND_AUDIO_MUSIC_PARAMETER) == 830); +static_assert(static_cast(MessageType::Game::PLAY2_D_AMBIENT_SOUND) == 831); +static_assert(static_cast(MessageType::Game::STOP2_D_AMBIENT_SOUND) == 832); +static_assert(static_cast(MessageType::Game::PLAY3_D_AMBIENT_SOUND) == 834); +static_assert(static_cast(MessageType::Game::STOP3_D_AMBIENT_SOUND) == 835); +static_assert(static_cast(MessageType::Game::ACTIVATE_ND_AUDIO_MIXER_PROGRAM) == 836); +static_assert(static_cast(MessageType::Game::DEACTIVATE_ND_AUDIO_MIXER_PROGRAM) == 837); +static_assert(static_cast(MessageType::Game::UPDATE_ACTIVITY_LEADERBOARD) == 838); +static_assert(static_cast(MessageType::Game::ACTIVITY_LEADERBOARD_UPDATED) == 839); +static_assert(static_cast(MessageType::Game::ENTER_PROPERTY1) == 840); +static_assert(static_cast(MessageType::Game::ENTER_PROPERTY2) == 841); +static_assert(static_cast(MessageType::Game::PROPERTY_ENTRANCE_SYNC) == 842); +static_assert(static_cast(MessageType::Game::SEND_PROPERTY_POPULATION_TO_CLIENT) == 843); +static_assert(static_cast(MessageType::Game::SEN_PROPERTY_PLAQUE_VIS_UPDATE) == 844); +static_assert(static_cast(MessageType::Game::PROPERTY_SELECT_QUERY) == 845); +static_assert(static_cast(MessageType::Game::CREATE_POSITION_STRING) == 848); +static_assert(static_cast(MessageType::Game::GET_PARALLEL_POSITION) == 849); +static_assert(static_cast(MessageType::Game::PARSE_CHAT_MESSAGE) == 850); +static_assert(static_cast(MessageType::Game::SET_MISSION_TYPE_STATE) == 851); +static_assert(static_cast(MessageType::Game::GET_LOCATIONS_VISITED) == 852); +static_assert(static_cast(MessageType::Game::GET_MISSION_TYPE_STATES) == 853); +static_assert(static_cast(MessageType::Game::GET_TIME_PLAYED) == 854); +static_assert(static_cast(MessageType::Game::SET_MISSION_VIEWED) == 855); +static_assert(static_cast(MessageType::Game::HKX_VEHICLE_LOADED) == 856); +static_assert(static_cast(MessageType::Game::SLASH_COMMAND_TEXT_FEEDBACK) == 857); +static_assert(static_cast(MessageType::Game::BROADCAST_TEXT_TO_CHATBOX) == 858); +static_assert(static_cast(MessageType::Game::HANDLE_SLASH_COMMAND_KORE_DEBUGGER) == 859); +static_assert(static_cast(MessageType::Game::OPEN_PROPERTY_MANAGEMENT) == 860); +static_assert(static_cast(MessageType::Game::OPEN_PROPERTY_VENDOR) == 861); +static_assert(static_cast(MessageType::Game::VOTE_ON_PROPERTY) == 862); +static_assert(static_cast(MessageType::Game::UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK) == 863); +static_assert(static_cast(MessageType::Game::NOTIFY_PLAYER_OF_PROPERTY_SUBMISSION) == 865); +static_assert(static_cast(MessageType::Game::NOTIFY_PLAYER_OF_MODEL_SUBMISSION) == 866); +static_assert(static_cast(MessageType::Game::PHYSICS_SYSTEM_LOADED) == 867); +static_assert(static_cast(MessageType::Game::CLIENT_TRADE_REQUEST) == 868); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_REQUEST) == 869); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_INVITE) == 870); +static_assert(static_cast(MessageType::Game::CLIENT_TRADE_REPLY) == 871); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_REPLY) == 872); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_INITIAL_REPLY) == 873); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_FINAL_REPLY) == 874); +static_assert(static_cast(MessageType::Game::CLIENT_TRADE_UPDATE) == 875); +static_assert(static_cast(MessageType::Game::SERVER_SIDE_TRADE_UPDATE) == 876); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_UPDATE) == 877); +static_assert(static_cast(MessageType::Game::CLIENT_TRADE_CANCEL) == 878); +static_assert(static_cast(MessageType::Game::CLIENT_SIDE_TRADE_CANCEL) == 879); +static_assert(static_cast(MessageType::Game::CLIENT_TRADE_ACCEPT) == 880); +static_assert(static_cast(MessageType::Game::SERVER_SIDE_TRADE_ACCEPT) == 881); +static_assert(static_cast(MessageType::Game::SERVER_SIDE_TRADE_CANCEL) == 882); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_CANCEL) == 883); +static_assert(static_cast(MessageType::Game::SERVER_TRADE_ACCEPT) == 884); +static_assert(static_cast(MessageType::Game::GET_TRADE_INFO) == 885); +static_assert(static_cast(MessageType::Game::KF_LOADED) == 886); +static_assert(static_cast(MessageType::Game::BRICKS_LOADED) == 887); +static_assert(static_cast(MessageType::Game::READY_FOR_UPDATES) == 888); +static_assert(static_cast(MessageType::Game::SEND_READY_FOR_UPDATES) == 889); +static_assert(static_cast(MessageType::Game::SET_LAST_CUSTOM_BUILD) == 890); +static_assert(static_cast(MessageType::Game::GET_LAST_CUSTOM_BUILD) == 891); +static_assert(static_cast(MessageType::Game::GET_STATUS_EFFECT_BY_ID) == 892); +static_assert(static_cast(MessageType::Game::GET_ALL_STATUS_EFFECTS) == 893); +static_assert(static_cast(MessageType::Game::CHILD_RENDER_COMPONENT_READY) == 894); +static_assert(static_cast(MessageType::Game::NOTIFY_APPEARANCE_CHANGED_MSG) == 895); +static_assert(static_cast(MessageType::Game::SET_PHYSICS_MOTION_STATE) == 896); +static_assert(static_cast(MessageType::Game::GET_PHYSICS_MOTION_STATE) == 897); +static_assert(static_cast(MessageType::Game::ATTACH_GRAYSCALE_EFFECT) == 898); +static_assert(static_cast(MessageType::Game::ATTACH_FADE_EFFECT) == 899); +static_assert(static_cast(MessageType::Game::ATTACH_CHANGE_RENDER_ENVIRONMENT_EFFECT) == 900); +static_assert(static_cast(MessageType::Game::FORCE_MOVEMENT) == 901); +static_assert(static_cast(MessageType::Game::CANCEL_FORCE_MOVEMENT) == 902); +static_assert(static_cast(MessageType::Game::SET_IGNORE_PROJECTILE_COLLISION) == 903); +static_assert(static_cast(MessageType::Game::GET_IGNORE_PROJECTILE_COLLISION) == 904); +static_assert(static_cast(MessageType::Game::ORIENT_TO_OBJECT) == 905); +static_assert(static_cast(MessageType::Game::ORIENT_TO_POSITION) == 906); +static_assert(static_cast(MessageType::Game::ORIENT_TO_ANGLE) == 907); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_UGC_MODEL_READY) == 909); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_UGC_ICON_READY) == 911); +static_assert(static_cast(MessageType::Game::PROPERTY_BUILD_MODE_CHANGED) == 912); +static_assert(static_cast(MessageType::Game::PROPERTY_BUILD_MODE_UPDATE) == 913); +static_assert(static_cast(MessageType::Game::PROPERTY_DELETION_ACTION) == 914); +static_assert(static_cast(MessageType::Game::PROPERTY_MODERATION_STATUS_ACTION) == 915); +static_assert(static_cast(MessageType::Game::PROPERTY_MODERATION_STATUS_ACTION_RESPONSE) == 916); +static_assert(static_cast(MessageType::Game::PROPERTY_MODERATION_STATUS_UPDATE) == 917); +static_assert(static_cast(MessageType::Game::PROPERTY_NEEDS_GM_ATTENTION) == 918); +static_assert(static_cast(MessageType::Game::PROPERTY_MODERATION_CHANGED) == 919); +static_assert(static_cast(MessageType::Game::INVENTORY_REFRESH_ITEM_DETAILS) == 922); +static_assert(static_cast(MessageType::Game::INVENTORY_LOAD_CUSTOM_ICON) == 923); +static_assert(static_cast(MessageType::Game::GET_STATUS_EFFECT_BY_TYPE) == 924); +static_assert(static_cast(MessageType::Game::RELEASE_CHARGED_SKILL) == 925); +static_assert(static_cast(MessageType::Game::PROPERTY_RELOAD_DB) == 926); +static_assert(static_cast(MessageType::Game::SET_PLAYER_TARGET) == 927); +static_assert(static_cast(MessageType::Game::GET_PLAYER_TARGET) == 928); +static_assert(static_cast(MessageType::Game::LOCK_CAMERA_NETWORKED) == 929); +static_assert(static_cast(MessageType::Game::MOVE_CAMERA_NETWORKED) == 930); +static_assert(static_cast(MessageType::Game::REBUILD_ACTIVATED) == 931); +static_assert(static_cast(MessageType::Game::BOUNCE_NOTIFICATION) == 932); +static_assert(static_cast(MessageType::Game::REQUEST_CLIENT_BOUNCE) == 934); +static_assert(static_cast(MessageType::Game::GET_RECENT_BOUNCED) == 935); +static_assert(static_cast(MessageType::Game::SET_RECENT_BOUNCED) == 936); +static_assert(static_cast(MessageType::Game::SET_ACTIVE_STATE) == 937); +static_assert(static_cast(MessageType::Game::GET_ACTIVE_STATE) == 938); +static_assert(static_cast(MessageType::Game::HAS_COMPONENT_TYPE) == 939); +static_assert(static_cast(MessageType::Game::GET_COMPONENT_LIST) == 940); +static_assert(static_cast(MessageType::Game::RESPONDS_TO_FACTION) == 941); +static_assert(static_cast(MessageType::Game::BOUNCER_ACTIVE_STATUS) == 942); +static_assert(static_cast(MessageType::Game::HF_ATTRIBUTES_PUSH) == 943); +static_assert(static_cast(MessageType::Game::HF_ATTRIBUTES_PULL) == 944); +static_assert(static_cast(MessageType::Game::HF_ATTRIBUTES_PATH_DISPLAY) == 945); +static_assert(static_cast(MessageType::Game::HF_CONTROLS_PULL) == 946); +static_assert(static_cast(MessageType::Game::HF_OBJECT_SELECTED) == 947); +static_assert(static_cast(MessageType::Game::HF_PLACEHOLDER_UPDATE) == 948); +static_assert(static_cast(MessageType::Game::HF_PLACEHOLDER_TOGGLE) == 949); +static_assert(static_cast(MessageType::Game::HF_GET_ASSOCIATED_PATHS) == 950); +static_assert(static_cast(MessageType::Game::HF_GETS_WANT_PATH) == 951); +static_assert(static_cast(MessageType::Game::GET_RECENT_MOVEMENT_KEYS) == 952); +static_assert(static_cast(MessageType::Game::TRACK_RECENT_MOVEMENT_KEYS) == 953); +static_assert(static_cast(MessageType::Game::PHYSICS_MOVEMENT_NOTIFICATION_REQUEST) == 954); +static_assert(static_cast(MessageType::Game::PHYSICS_MOVEMENT_NOTIFICATION) == 955); +static_assert(static_cast(MessageType::Game::MOVE_INVENTORY_SINGLE) == 956); +static_assert(static_cast(MessageType::Game::MOVE_INVENTORY_BATCH) == 957); +static_assert(static_cast(MessageType::Game::MINI_GAME_SET_PARAMETERS) == 958); +static_assert(static_cast(MessageType::Game::MINI_GAME_GET_TEAM_SKILLS) == 961); +static_assert(static_cast(MessageType::Game::MINI_GAME_GET_TEAM_SCORE) == 963); +static_assert(static_cast(MessageType::Game::MINI_GAME_GET_PLAYER_SCORE) == 967); +static_assert(static_cast(MessageType::Game::MINI_GAME_GET_TEAM_COLOR) == 972); +static_assert(static_cast(MessageType::Game::MINI_GAME_GET_TEAM_PLAYERS) == 975); +static_assert(static_cast(MessageType::Game::MINI_GAME_UPDATE_CLIENT) == 976); +static_assert(static_cast(MessageType::Game::MINI_GAME_GET_TEAM) == 977); +static_assert(static_cast(MessageType::Game::MINI_GAME_GET_PARAMETERS) == 978); +static_assert(static_cast(MessageType::Game::OBJECT_ACTIVATED_CLIENT) == 980); +static_assert(static_cast(MessageType::Game::IS_RESURRECTING) == 983); +static_assert(static_cast(MessageType::Game::GET_ITEM_OWNER) == 984); +static_assert(static_cast(MessageType::Game::GET_STORED_CONFIG_DATA) == 985); +static_assert(static_cast(MessageType::Game::SET_STORED_CONFIG_DATA) == 986); +static_assert(static_cast(MessageType::Game::ON_PLAYER_RESSURECTED) == 988); +static_assert(static_cast(MessageType::Game::PLAYER_RESURRECTION_FINISHED) == 989); +static_assert(static_cast(MessageType::Game::TRANSFORM_CHANGELING_BUILD) == 990); +static_assert(static_cast(MessageType::Game::RETURN_CHANGELING_BUILD_ID) == 991); +static_assert(static_cast(MessageType::Game::SPEND_BRICK_INVENTORY_FOR_LXFML) == 992); +static_assert(static_cast(MessageType::Game::BRICK_INVENTORY_FOR_LXFML_SPENT) == 993); +static_assert(static_cast(MessageType::Game::REBUILD_BBB_AUTOSAVE_MSG) == 995); +static_assert(static_cast(MessageType::Game::SET_BBB_AUTOSAVE) == 996); +static_assert(static_cast(MessageType::Game::USE_BBB_INVENTORY) == 998); +static_assert(static_cast(MessageType::Game::UN_USE_BBB_MODEL) == 999); +static_assert(static_cast(MessageType::Game::BBB_LOAD_ITEM_REQUEST) == 1000); +static_assert(static_cast(MessageType::Game::BBB_SAVE_REQUEST) == 1001); +static_assert(static_cast(MessageType::Game::BBBLUP_SAVE_REQUEST) == 1002); +static_assert(static_cast(MessageType::Game::BBB_GET_METADATA_SOURCE_ITEM) == 1003); +static_assert(static_cast(MessageType::Game::BBB_RESET_METADATA_SOURCE_ITEM) == 1004); +static_assert(static_cast(MessageType::Game::BBB_SAVE_RESPONSE) == 1005); +static_assert(static_cast(MessageType::Game::PLAYER_EXIT) == 1006); +static_assert(static_cast(MessageType::Game::SET_PVP_STATUS) == 1008); +static_assert(static_cast(MessageType::Game::GET_PVP_STATUS) == 1009); +static_assert(static_cast(MessageType::Game::IS_VALID_PVP_TARGET) == 1010); +static_assert(static_cast(MessageType::Game::PVP_RENDER_NAME) == 1011); +static_assert(static_cast(MessageType::Game::ATTACH_OBJECT) == 1012); +static_assert(static_cast(MessageType::Game::DETACH_OBJECT) == 1013); +static_assert(static_cast(MessageType::Game::BOUNCE_SUCCEEDED) == 1014); +static_assert(static_cast(MessageType::Game::GET_GAME_OBJECT_POINTER) == 1015); +static_assert(static_cast(MessageType::Game::PHANTOM_HKX_LOADED) == 1016); +static_assert(static_cast(MessageType::Game::DELAY_CREATE_EFFECT) == 1017); +static_assert(static_cast(MessageType::Game::CHOICE_BUILD_SELECTION_CONFIRMED) == 1018); +static_assert(static_cast(MessageType::Game::NOTIFY_FADE_UP_VIS_COMPLETE) == 1019); +static_assert(static_cast(MessageType::Game::ITEM_HAS_NEW_INFO) == 1020); +static_assert(static_cast(MessageType::Game::RESET_SECONDARY_ANIMATION) == 1021); +static_assert(static_cast(MessageType::Game::GET_PICK_TYPE) == 1022); +static_assert(static_cast(MessageType::Game::SET_PICK_TYPE) == 1023); +static_assert(static_cast(MessageType::Game::GET_PRIORITY_PICK_LIST_TYPE) == 1024); +static_assert(static_cast(MessageType::Game::REQUEST_PICK_TYPE_UPDATE) == 1025); +static_assert(static_cast(MessageType::Game::GET_OVERRIDE_PICK_TYPE) == 1026); +static_assert(static_cast(MessageType::Game::REQUEST_DISPLAY_OBJECT_INFO) == 1027); +static_assert(static_cast(MessageType::Game::REQUEST_SERVER_OBJECT_INFO) == 1028); +static_assert(static_cast(MessageType::Game::REQUEST_OBJECT_INFO_AS_XML) == 1029); +static_assert(static_cast(MessageType::Game::GET_OBJECT_REPORT_INFO) == 1030); +static_assert(static_cast(MessageType::Game::GET_OBJECT_REPORT_WINDOW_CLOSE) == 1031); +static_assert(static_cast(MessageType::Game::GET_OBJECT_REPORT_STATUS) == 1032); +static_assert(static_cast(MessageType::Game::GET_MISSION_DATA_FOR_OBJECT_REPORT) == 1033); +static_assert(static_cast(MessageType::Game::GET_OBJECT_ROLLOVER_INFO) == 1034); +static_assert(static_cast(MessageType::Game::PERFORM_ZONE_ANALYSIS) == 1035); +static_assert(static_cast(MessageType::Game::UPDATE_HK_VISUAL_IZATION) == 1036); +static_assert(static_cast(MessageType::Game::CLEAR_ITEMS_OWNER) == 1037); +static_assert(static_cast(MessageType::Game::APPLY_LINEAR_IMPULSE) == 1038); +static_assert(static_cast(MessageType::Game::APPLY_ANGULAR_IMPULSE) == 1039); +static_assert(static_cast(MessageType::Game::GET_CONTACT_NORMALS) == 1040); +static_assert(static_cast(MessageType::Game::IS_WATCHING_FOR_EMOTE) == 1041); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_OBJECT) == 1042); +static_assert(static_cast(MessageType::Game::DISPLAY_ZONE_SUMMARY) == 1043); +static_assert(static_cast(MessageType::Game::ZONE_SUMMARY_DISMISSED) == 1044); +static_assert(static_cast(MessageType::Game::GET_PLAYER_ZONE_STATISTIC) == 1045); +static_assert(static_cast(MessageType::Game::MODIFY_PLAYER_ZONE_STATISTIC) == 1046); +static_assert(static_cast(MessageType::Game::APPLY_EXTERNAL_FORCE) == 1049); +static_assert(static_cast(MessageType::Game::GET_APPLIED_EXTERNAL_FORCE) == 1050); +static_assert(static_cast(MessageType::Game::ACTIVITY_NOTIFY) == 1051); +static_assert(static_cast(MessageType::Game::ITEM_EQUIPPED) == 1052); +static_assert(static_cast(MessageType::Game::ACTIVITY_STATE_CHANGE_REQUEST) == 1053); +static_assert(static_cast(MessageType::Game::OVERRIDE_FRICTION) == 1054); +static_assert(static_cast(MessageType::Game::ARRANGE_WITH_ITEM) == 1055); +static_assert(static_cast(MessageType::Game::CHECK_CAN_BUILD_WITH_ITEM) == 1056); +static_assert(static_cast(MessageType::Game::START_BUILDING_WITH_ITEM) == 1057); +static_assert(static_cast(MessageType::Game::START_BUILD_SESSION) == 1058); +static_assert(static_cast(MessageType::Game::FINISH_BUILD_SESSION) == 1059); +static_assert(static_cast(MessageType::Game::DONE_BUILD_SESSION) == 1060); +static_assert(static_cast(MessageType::Game::START_ARRANGING_WITH_ITEM) == 1061); +static_assert(static_cast(MessageType::Game::FINISH_ARRANGING_WITH_ITEM) == 1062); +static_assert(static_cast(MessageType::Game::DONE_ARRANGING_WITH_ITEM) == 1063); +static_assert(static_cast(MessageType::Game::START_ARRANGE_MODE) == 1064); +static_assert(static_cast(MessageType::Game::ARRANGE_MODE_WITH_ITEM) == 1065); +static_assert(static_cast(MessageType::Game::FINISH_ARRANGE_MODE) == 1066); +static_assert(static_cast(MessageType::Game::DONE_ARRANGE_MODE) == 1067); +static_assert(static_cast(MessageType::Game::SET_BUILD_MODE) == 1068); +static_assert(static_cast(MessageType::Game::BUILD_MODE_SET) == 1069); +static_assert(static_cast(MessageType::Game::CONFIRM_BUILD_MODE) == 1070); +static_assert(static_cast(MessageType::Game::BUILD_MODE_CONFIRMATION) == 1071); +static_assert(static_cast(MessageType::Game::BUILD_EXIT_CONFIRMATION) == 1072); +static_assert(static_cast(MessageType::Game::SET_BUILD_MODE_CONFIRMED) == 1073); +static_assert(static_cast(MessageType::Game::BUILD_MODE_NOTIFICATION) == 1074); +static_assert(static_cast(MessageType::Game::BUILD_MODE_NOTIFICATION_REPORT) == 1075); +static_assert(static_cast(MessageType::Game::CLIENT_USE_MODULE_ON) == 1076); +static_assert(static_cast(MessageType::Game::SET_MODEL_TO_BUILD) == 1077); +static_assert(static_cast(MessageType::Game::SPAWN_MODEL_BRICKS) == 1078); +static_assert(static_cast(MessageType::Game::CHECK_PRECONDITION) == 1079); +static_assert(static_cast(MessageType::Game::CHECK_ALL_PRECONDITIONS) == 1080); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_FAILED_PRECONDITION) == 1081); +static_assert(static_cast(MessageType::Game::GET_IS_ITEM_EQUIPPED_BY_LOT) == 1082); +static_assert(static_cast(MessageType::Game::GET_IS_ITEM_EQUIPPED_BY_ID) == 1083); +static_assert(static_cast(MessageType::Game::GET_OBJECT_DIRECTION_VECTORS) == 1084); +static_assert(static_cast(MessageType::Game::GET_CASTABLE_SKILLS) == 1085); +static_assert(static_cast(MessageType::Game::CHOICEBUILD_COMPLETE) == 1086); +static_assert(static_cast(MessageType::Game::GET_MISSION_CHAT) == 1087); +static_assert(static_cast(MessageType::Game::GET_MISSION_AUDIO) == 1088); +static_assert(static_cast(MessageType::Game::MODULE_EQUIPPED) == 1089); +static_assert(static_cast(MessageType::Game::MODULE_DROPPED) == 1090); +static_assert(static_cast(MessageType::Game::MODULE_PICKED_UP) == 1091); +static_assert(static_cast(MessageType::Game::MODULE_INFO) == 1092); +static_assert(static_cast(MessageType::Game::MOVE_ITEM_BETWEEN_INVENTORY_TYPES) == 1093); +static_assert(static_cast(MessageType::Game::MODULAR_BUILD_BEGIN) == 1094); +static_assert(static_cast(MessageType::Game::MODULAR_BUILD_END) == 1095); +static_assert(static_cast(MessageType::Game::MODULAR_BUILD_MOVE_AND_EQUIP) == 1096); +static_assert(static_cast(MessageType::Game::MODULAR_BUILD_FINISH) == 1097); +static_assert(static_cast(MessageType::Game::SET_REGISTRATION_FOR_UI_UPDATE) == 1114); +static_assert(static_cast(MessageType::Game::GO_TO_WAYPOINT) == 1115); +static_assert(static_cast(MessageType::Game::ARRIVED_AT_DESIRED_WAYPOINT) == 1116); +static_assert(static_cast(MessageType::Game::CHECK_WITHIN_BOUNDS) == 1117); +static_assert(static_cast(MessageType::Game::ATTACH_TO_BUILD_ASSEMBLY) == 1118); +static_assert(static_cast(MessageType::Game::SET_BUILD_ASSEMBLY) == 1119); +static_assert(static_cast(MessageType::Game::RESET_BUILD_ASSEMBLY) == 1120); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_ITEM_INFO) == 1125); +static_assert(static_cast(MessageType::Game::GET_ITEM_DETAILS) == 1126); +static_assert(static_cast(MessageType::Game::GET_BUILD_ACTIVATOR) == 1127); +static_assert(static_cast(MessageType::Game::GET_MISSION_ANIMATION) == 1128); +static_assert(static_cast(MessageType::Game::MISSION_DIALOGUE_CANCELLED) == 1129); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_DB_DATA) == 1130); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT) == 1131); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_QUERY_DATA) == 1132); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_HKX_LOADED) == 1133); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_NIF_LOADED) == 1134); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_MAIN_NIF_LOADED) == 1135); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_KFM_LOADED) == 1136); +static_assert(static_cast(MessageType::Game::GET_PRECONDITION_INFO) == 1137); +static_assert(static_cast(MessageType::Game::GET_MODEL_LOT) == 1138); +static_assert(static_cast(MessageType::Game::ANIMATION_FINISHED_PRELOADING) == 1139); +static_assert(static_cast(MessageType::Game::CHILD_BUILD_ASSEMBLY_COMPLETE) == 1140); +static_assert(static_cast(MessageType::Game::CHARACTER_UNSERIALIZED) == 1141); +static_assert(static_cast(MessageType::Game::CHARACTER_NEEDS_TRANSITION) == 1142); +static_assert(static_cast(MessageType::Game::SET_NEEDS_TRANSITION) == 1143); +static_assert(static_cast(MessageType::Game::ECHO_SYNC_SKILL) == 1144); +static_assert(static_cast(MessageType::Game::SYNC_SKILL) == 1145); +static_assert(static_cast(MessageType::Game::GET_BEHAVIOR_HANDLE) == 1146); +static_assert(static_cast(MessageType::Game::ADD_OUTSTANDING_BEHAVIOR) == 1147); +static_assert(static_cast(MessageType::Game::REQUEST_SERVER_PROJECTILE_IMPACT) == 1148); +static_assert(static_cast(MessageType::Game::OFF_WORLD_IMPACT_REQUEST) == 1149); +static_assert(static_cast(MessageType::Game::SERVER_IMPACT_REQUEST) == 1150); +static_assert(static_cast(MessageType::Game::DO_CLIENT_PROJECTILE_IMPACT) == 1151); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_PART_INFO) == 1152); +static_assert(static_cast(MessageType::Game::GET_BUILD_TYPE) == 1153); +static_assert(static_cast(MessageType::Game::CHECK_BUILD_TYPE) == 1154); +static_assert(static_cast(MessageType::Game::MODULAR_BUILD_CONVERT_MODEL) == 1155); +static_assert(static_cast(MessageType::Game::DO_NPC_SHOWCASE_MODEL_SUBMISSION) == 1156); +static_assert(static_cast(MessageType::Game::GET_MISSION_I_DS_LIST) == 1157); +static_assert(static_cast(MessageType::Game::SET_SHOWCASE_MISSION_NPC_VALS) == 1158); +static_assert(static_cast(MessageType::Game::NOTIFY_SHOWCASE_MISSION_NP_COF_SUCCESS) == 1159); +static_assert(static_cast(MessageType::Game::SEND_LUA_NOTIFICATION_REQUEST) == 1160); +static_assert(static_cast(MessageType::Game::SEND_LUA_NOTIFICATION_CANCEL) == 1161); +static_assert(static_cast(MessageType::Game::ACTIVATOR_TOGGLE) == 1162); +static_assert(static_cast(MessageType::Game::MAKE_PHYSICS) == 1163); +static_assert(static_cast(MessageType::Game::SET_RESPAWN_GROUP) == 1164); +static_assert(static_cast(MessageType::Game::SET_PLAYER_ALLOWED_RESPAWN) == 1165); +static_assert(static_cast(MessageType::Game::TOGGLE_SENDING_POSITION_UPDATES) == 1166); +static_assert(static_cast(MessageType::Game::TOGGLE_RECEIVING_POSITION_UPDATES) == 1167); +static_assert(static_cast(MessageType::Game::GET_ENEMY_PRECONDITIONS) == 1168); +static_assert(static_cast(MessageType::Game::START_MODEL_VISUALIZATION) == 1169); +static_assert(static_cast(MessageType::Game::PLACE_PROPERTY_MODEL) == 1170); +static_assert(static_cast(MessageType::Game::PROPERTY_MODEL_PLACED) == 1171); +static_assert(static_cast(MessageType::Game::OPEN_EXHIBIT_REPLACE_MODEL_UI) == 1172); +static_assert(static_cast(MessageType::Game::REPLACE_SHOWCASEMODEL) == 1173); +static_assert(static_cast(MessageType::Game::CLEAR_UI_HOOK_EXHIBIT_REPLACEMENT) == 1174); +static_assert(static_cast(MessageType::Game::ATTACH_FLYTO_SCREEN_POS) == 1175); +static_assert(static_cast(MessageType::Game::VEHICLE_GET_DEBUG_INFO) == 1176); +static_assert(static_cast(MessageType::Game::VEHICLE_GET_MOVEMENT_INPUT_VALUES) == 1177); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_SET) == 1178); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_UPDATE) == 1179); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_GET) == 1180); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_STOP) == 1181); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_DONE) == 1182); +static_assert(static_cast(MessageType::Game::GET_ATTACK_PRIORITY) == 1183); +static_assert(static_cast(MessageType::Game::UI_MESSAGE_SERVER_TO_SINGLE_CLIENT) == 1184); +static_assert(static_cast(MessageType::Game::UI_MESSAGE_SERVER_TO_ALL_CLIENTS) == 1185); +static_assert(static_cast(MessageType::Game::SET_LOSE_COINS_ON_DEATH) == 1186); +static_assert(static_cast(MessageType::Game::LOAD_EFFECTS) == 1187); +static_assert(static_cast(MessageType::Game::SET_CUSTOM_BUILD) == 1188); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_RESET) == 1189); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_STOP_ALL_TIMERS) == 1190); +static_assert(static_cast(MessageType::Game::ACTIVITY_TIMER_MODIFY) == 1191); +static_assert(static_cast(MessageType::Game::SET_KEYFRAM_TRANSFORM) == 1192); +static_assert(static_cast(MessageType::Game::ADD_ACTIVITY_OWNER) == 1193); +static_assert(static_cast(MessageType::Game::REMOVE_ACTIVITY_OWNER) == 1194); +static_assert(static_cast(MessageType::Game::GET_CURRENT_ACTIVITY_OWNERS) == 1195); +static_assert(static_cast(MessageType::Game::TOGGLE_SKILL_DEBUGGING) == 1196); +static_assert(static_cast(MessageType::Game::PET_TAMING_TRY_BUILD) == 1197); +static_assert(static_cast(MessageType::Game::REPORT_BUG) == 1198); +static_assert(static_cast(MessageType::Game::REPORT_OFFENSIVE_MODEL) == 1199); +static_assert(static_cast(MessageType::Game::REPORT_OFFENSIVE_PROPERTY) == 1200); +static_assert(static_cast(MessageType::Game::GET_ACTIVITY_ID) == 1201); +static_assert(static_cast(MessageType::Game::REQUEST_SMASH_PLAYER) == 1202); +static_assert(static_cast(MessageType::Game::GET_TIMES_REQUESTED_SMASH) == 1203); +static_assert(static_cast(MessageType::Game::RESPONSE_SMASH_PLAYER) == 1204); +static_assert(static_cast(MessageType::Game::MODIFY_DAMAGE_ABSORPTION) == 1205); +static_assert(static_cast(MessageType::Game::UNCAST_SKILL) == 1206); +static_assert(static_cast(MessageType::Game::GET_SHOWCASE_MODEL_READY) == 1207); +static_assert(static_cast(MessageType::Game::IS_SKILL_NEEDED) == 1208); +static_assert(static_cast(MessageType::Game::GET_COMPONENT_DATA) == 1209); +static_assert(static_cast(MessageType::Game::VEHICLE_SET_POWERSLIDE_METHOD) == 1210); +static_assert(static_cast(MessageType::Game::SHOWS_NAMETAG) == 1211); +static_assert(static_cast(MessageType::Game::FIRE_EVENT_CLIENT_SIDE) == 1213); +static_assert(static_cast(MessageType::Game::GET_REQUIRES_NAME_RESUBMISSION) == 1216); +static_assert(static_cast(MessageType::Game::SET_REQUIRES_NAME_RESUBMISSION) == 1217); +static_assert(static_cast(MessageType::Game::TOGGLE_GM_INVIS) == 1218); +static_assert(static_cast(MessageType::Game::GET_GM_INVIS) == 1219); +static_assert(static_cast(MessageType::Game::KILLED_PLAYER) == 1220); +static_assert(static_cast(MessageType::Game::GET_PICKUP_SKILLS) == 1221); +static_assert(static_cast(MessageType::Game::GET_FACTION_SKILL) == 1222); +static_assert(static_cast(MessageType::Game::CHANGE_OBJECT_WORLD_STATE) == 1223); +static_assert(static_cast(MessageType::Game::GET_OBJECT_WORLD_STATE) == 1224); +static_assert(static_cast(MessageType::Game::VISIBILITY_CHANGED) == 1225); +static_assert(static_cast(MessageType::Game::MOTION_EFFECT_COMPLETE) == 1226); +static_assert(static_cast(MessageType::Game::TOGGLE_FREEZE_MODE) == 1227); +static_assert(static_cast(MessageType::Game::SHADER_RENDER_MSG_APPLIED) == 1228); +static_assert(static_cast(MessageType::Game::PLAYER_RENAME_REQUEST) == 1229); +static_assert(static_cast(MessageType::Game::VEHICLE_LOCK_INPUT) == 1230); +static_assert(static_cast(MessageType::Game::VEHICLE_UNLOCK_INPUT) == 1231); +static_assert(static_cast(MessageType::Game::SET_AIR_MOVEMENT) == 1232); +static_assert(static_cast(MessageType::Game::MOVEMENT_STATE_CHANGED) == 1233); +static_assert(static_cast(MessageType::Game::SKILL_MOVEMENT_CANCELLED) == 1234); +static_assert(static_cast(MessageType::Game::AIR_MOVEMENT_COMPLETE) == 1235); +static_assert(static_cast(MessageType::Game::CANCEL_AIR_MOVEMENT) == 1236); +static_assert(static_cast(MessageType::Game::FORCE_MINIFIGURE_TEXTURE_UPDATE) == 1237); +static_assert(static_cast(MessageType::Game::RESYNC_EQUIPMENT) == 1238); +static_assert(static_cast(MessageType::Game::ADD_COMPONENT_TO_OBJECT) == 1239); +static_assert(static_cast(MessageType::Game::VEHICLE_GET_MAX_GAME_SPEED) == 1240); +static_assert(static_cast(MessageType::Game::VEHICLE_GET_MAX_GAME_SPEED_WITH_BOOST) == 1241); +static_assert(static_cast(MessageType::Game::GET_SPEED_FACTOR) == 1242); +static_assert(static_cast(MessageType::Game::FREEZE_INVENTORY) == 1243); +static_assert(static_cast(MessageType::Game::ADD_STAT_TRIGGER) == 1244); +static_assert(static_cast(MessageType::Game::ADD_STAT_TRIGGER_CHILD) == 1245); +static_assert(static_cast(MessageType::Game::CHECK_TRIGGERS_AND_FIRE_IF_NEEDED) == 1246); +static_assert(static_cast(MessageType::Game::STAT_EVENT_TRIGGERED) == 1247); +static_assert(static_cast(MessageType::Game::GET_CURRENT_SPEED) == 1248); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_RANK_CHANGED) == 1249); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_WRONG_WAY_STATUS_CHANGED) == 1250); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_CROSSED_FINISH_LINE) == 1251); +static_assert(static_cast(MessageType::Game::RACING_RESET_PLAYER_TO_LAST_RESET) == 1252); +static_assert(static_cast(MessageType::Game::RACING_SERVER_SET_PLAYER_LAP_AND_PLANE) == 1253); +static_assert(static_cast(MessageType::Game::RACING_SET_PLAYER_RESET_INFO) == 1254); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_INFO_RESET_FINISHED) == 1255); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_OUT_OF_TRACK_BOUNDS) == 1256); +static_assert(static_cast(MessageType::Game::RACING_SYNC_INFO) == 1257); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_KEEP_ALIVE) == 1258); +static_assert(static_cast(MessageType::Game::RACING_SERVER_KEEP_ALIVE) == 1259); +static_assert(static_cast(MessageType::Game::LOCK_NODE_ROTATION) == 1260); +static_assert(static_cast(MessageType::Game::GET_PHYSICS_COLLIDABLE) == 1261); +static_assert(static_cast(MessageType::Game::SET_PHYSICS_COLOR_FOR_DEBUG) == 1262); +static_assert(static_cast(MessageType::Game::GET_PHYSICS_COLOR_FOR_DEBUG) == 1263); +static_assert(static_cast(MessageType::Game::SET_PHYSICS_TEXT_AND_STATE_FOR_DEBUG) == 1264); +static_assert(static_cast(MessageType::Game::REQUEST_INFO_FOR_PHYSICS_DEBUGGER) == 1265); +static_assert(static_cast(MessageType::Game::GET_COLLIDABLE_AT_ADDRESS) == 1266); +static_assert(static_cast(MessageType::Game::REQUEST_SERVER_GET_COLLIDABLE_REPORT) == 1267); +static_assert(static_cast(MessageType::Game::COLLISION_POINT_ADDED) == 1268); +static_assert(static_cast(MessageType::Game::COLLISION_POINT_REMOVED) == 1269); +static_assert(static_cast(MessageType::Game::SET_ATTACHED) == 1270); +static_assert(static_cast(MessageType::Game::SET_DESTROYABLE_MODEL_BRICKS) == 1271); +static_assert(static_cast(MessageType::Game::VEHICLE_SET_POWERSLIDE_LOCK_WHEELS) == 1272); +static_assert(static_cast(MessageType::Game::VEHICLE_SET_WHEEL_LOCK_STATE) == 1273); +static_assert(static_cast(MessageType::Game::SHOW_HEALTH_BAR) == 1274); +static_assert(static_cast(MessageType::Game::GET_SHOWS_HEALTH_BAR) == 1275); +static_assert(static_cast(MessageType::Game::NOTIFY_VEHICLE_OF_RACING_OBJECT) == 1276); +static_assert(static_cast(MessageType::Game::ENABLE_CLIENT_EQUIP_MODE) == 1278); +static_assert(static_cast(MessageType::Game::CLIENT_EQUIP_MODE_WAS_CHANGED) == 1279); +static_assert(static_cast(MessageType::Game::VEHICLE_GET_SPAWN_HEIGHT) == 1281); +static_assert(static_cast(MessageType::Game::SET_NAME_BILLBOARD_STATE) == 1284); +static_assert(static_cast(MessageType::Game::CHECK_TARGETING_REQUIREMENTS) == 1285); +static_assert(static_cast(MessageType::Game::VEHICLE_CAN_WRECK) == 1286); +static_assert(static_cast(MessageType::Game::ATTACH_RENDER_EFFECT) == 1287); +static_assert(static_cast(MessageType::Game::DETACH_RENDER_EFFECT) == 1288); +static_assert(static_cast(MessageType::Game::IS_PET_USING_ABILITY) == 1289); +static_assert(static_cast(MessageType::Game::SET_BLOCKING) == 1290); +static_assert(static_cast(MessageType::Game::GET_BLOCKING) == 1291); +static_assert(static_cast(MessageType::Game::UPDATE_BLOCKING) == 1292); +static_assert(static_cast(MessageType::Game::CHECK_DAMAGE_RESULTS) == 1293); +static_assert(static_cast(MessageType::Game::GET_OBJECT_IS_IN_RENDER_PIPE) == 1294); +static_assert(static_cast(MessageType::Game::ATTACH_MOTION_FX_ARC) == 1295); +static_assert(static_cast(MessageType::Game::PLAYER_REACHED_RESPAWN_CHECKPOINT) == 1296); +static_assert(static_cast(MessageType::Game::GET_LAST_RESPAWN_CHECKPOINT) == 1297); +static_assert(static_cast(MessageType::Game::GET_VEHICLE_DEBUG_COLLISIONS) == 1298); +static_assert(static_cast(MessageType::Game::VISITING_PROPERTY) == 1299); +static_assert(static_cast(MessageType::Game::HANDLE_UGC_POST_DELETE_BASED_ON_EDIT_MODE) == 1300); +static_assert(static_cast(MessageType::Game::HANDLE_UGC_POST_CREATE_BASED_ON_EDIT_MODE) == 1301); +static_assert(static_cast(MessageType::Game::WORLD_CHECK_RESPONSE) == 1302); +static_assert(static_cast(MessageType::Game::ADD_DAMAGE_REDUCTION) == 1303); +static_assert(static_cast(MessageType::Game::REMOVE_DAMAGE_REDUCTION) == 1304); +static_assert(static_cast(MessageType::Game::PROPERTY_CONTENTS_FROM_CLIENT) == 1305); +static_assert(static_cast(MessageType::Game::GET_MODELS_ON_PROPERTY) == 1306); +static_assert(static_cast(MessageType::Game::IS_SHOWCASE_DISPLAY_PEDESTAL) == 1307); +static_assert(static_cast(MessageType::Game::MATCH_REQUEST) == 1308); +static_assert(static_cast(MessageType::Game::MATCH_RESPONSE) == 1309); +static_assert(static_cast(MessageType::Game::MATCH_UPDATE) == 1310); +static_assert(static_cast(MessageType::Game::IS_DEFAULT_SKILL_ACTIVE) == 1311); +static_assert(static_cast(MessageType::Game::PROPERTY_EDITOR_CARRY) == 1312); +static_assert(static_cast(MessageType::Game::GET_LOOT_OWNER_ID) == 1313); +static_assert(static_cast(MessageType::Game::GET_ENEMY_LOOT_TAG) == 1314); +static_assert(static_cast(MessageType::Game::GET_NUM_SPAWNED_BRICKS) == 1315); +static_assert(static_cast(MessageType::Game::SET_ITEM_EQUIP_TRANSFORM) == 1316); +static_assert(static_cast(MessageType::Game::GET_ITEM_EQUIP_TRANSFORM) == 1317); +static_assert(static_cast(MessageType::Game::GET_PROPERTY_BUDGET_INFO) == 1318); +static_assert(static_cast(MessageType::Game::CHATBOX_IS_INIT) == 1319); +static_assert(static_cast(MessageType::Game::GET_SPAWNED_I_DS) == 1320); +static_assert(static_cast(MessageType::Game::GET_IMMUNITY) == 1321); +static_assert(static_cast(MessageType::Game::GET_GM_IMMUNITY) == 1322); +static_assert(static_cast(MessageType::Game::PROCESS_REMOTE_SLASH_COMMAND) == 1323); +static_assert(static_cast(MessageType::Game::IS_FRIEND_MSG) == 1324); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_EVENT) == 1325); +static_assert(static_cast(MessageType::Game::GET_PROPERTY_EDIT_VALID) == 1326); +static_assert(static_cast(MessageType::Game::REFRESH_RENDER_ASSET) == 1327); +static_assert(static_cast(MessageType::Game::VEHICLE_APPLY_STAT_CHANGE) == 1328); +static_assert(static_cast(MessageType::Game::ZONE_LOADED_INFO) == 1329); +static_assert(static_cast(MessageType::Game::B3_INTERFACE_ACTION) == 1330); +static_assert(static_cast(MessageType::Game::RACING_STAT_MODIFIERS_FROM_CLIENT) == 1332); +static_assert(static_cast(MessageType::Game::GET_RACING_STAT_MODIFIERS) == 1333); +static_assert(static_cast(MessageType::Game::SET_RACING_STAT_MODIFIERS) == 1334); +static_assert(static_cast(MessageType::Game::GET_RACING_LICENSE_LEVEL) == 1335); +static_assert(static_cast(MessageType::Game::ADD_EQUIP_CAST) == 1336); +static_assert(static_cast(MessageType::Game::SHOW_BILLBOARD_INTERACT_ICON) == 1337); +static_assert(static_cast(MessageType::Game::CHANGE_IDLE_FLAGS) == 1338); +static_assert(static_cast(MessageType::Game::GET_ANIMATION_FLAG) == 1339); +static_assert(static_cast(MessageType::Game::VEHICLE_ADD_PASSIVE_BOOST_ACTION) == 1340); +static_assert(static_cast(MessageType::Game::VEHICLE_REMOVE_PASSIVE_BOOST_ACTION) == 1341); +static_assert(static_cast(MessageType::Game::NOTIFY_SERVER_VEHICLE_ADD_PASSIVE_BOOST_ACTION) == 1342); +static_assert(static_cast(MessageType::Game::NOTIFY_SERVER_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION) == 1343); +static_assert(static_cast(MessageType::Game::VEHICLE_ADD_SLOWDOWN_ACTION) == 1344); +static_assert(static_cast(MessageType::Game::VEHICLE_REMOVE_SLOWDOWN_ACTION) == 1345); +static_assert(static_cast(MessageType::Game::NOTIFY_SERVER_VEHICLE_ADD_SLOWDOWN_ACTION) == 1346); +static_assert(static_cast(MessageType::Game::NOTIFY_SERVER_VEHICLE_REMOVE_SLOWDOWN_ACTION) == 1347); +static_assert(static_cast(MessageType::Game::FORCE_UPDATE_ANIMATIONS) == 1348); +static_assert(static_cast(MessageType::Game::MATCH_GET_DATA_FOR_PLAYER) == 1349); +static_assert(static_cast(MessageType::Game::BUYBACK_FROM_VENDOR) == 1350); +static_assert(static_cast(MessageType::Game::SET_INVENTORY_FILTER) == 1351); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_FILTER) == 1352); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_GROUPS) == 1353); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_GROUP) == 1354); +static_assert(static_cast(MessageType::Game::UPDATE_INVENTORY_GROUP) == 1355); +static_assert(static_cast(MessageType::Game::UPDATE_INVENTORY_UI) == 1356); +static_assert(static_cast(MessageType::Game::UPDATE_INVENTORY_GROUP_CONTENTS) == 1357); +static_assert(static_cast(MessageType::Game::CAN_REMOVE_ITEM_FROM_INVENTORY) == 1362); +static_assert(static_cast(MessageType::Game::DRIVE_THIS_CAR) == 1363); +static_assert(static_cast(MessageType::Game::VEHICLE_CAN_ADD_ACTIVE_BOOST) == 1364); +static_assert(static_cast(MessageType::Game::VEHICLE_ADD_ACTIVE_BOOST) == 1365); +static_assert(static_cast(MessageType::Game::SET_PROPERTY_ACCESS) == 1366); +static_assert(static_cast(MessageType::Game::ZONE_PROPERTY_MODEL_PLACED) == 1369); +static_assert(static_cast(MessageType::Game::ZONE_PROPERTY_MODEL_ROTATED) == 1370); +static_assert(static_cast(MessageType::Game::ZONE_PROPERTY_MODEL_REMOVED_WHILE_EQUIPPED) == 1371); +static_assert(static_cast(MessageType::Game::ZONE_PROPERTY_MODEL_EQUIPPED) == 1372); +static_assert(static_cast(MessageType::Game::ZONE_PROPERTY_MODEL_PICKED_UP) == 1373); +static_assert(static_cast(MessageType::Game::ZONE_PROPERTY_MODEL_REMOVED) == 1374); +static_assert(static_cast(MessageType::Game::GET_VERSIONING_INFO) == 1381); +static_assert(static_cast(MessageType::Game::OPEN_UG_BEHAVIOR_UI) == 1382); +static_assert(static_cast(MessageType::Game::VEHICLE_NOTIFY_HIT_SMASHABLE) == 1383); +static_assert(static_cast(MessageType::Game::GET_TETHER_RADIUS) == 1384); +static_assert(static_cast(MessageType::Game::VEHICLE_NOTIFY_HIT_EXPLODER) == 1385); +static_assert(static_cast(MessageType::Game::CHECK_NEAREST_ROCKET_LAUNCH_PRE_CONDITIONS) == 1386); +static_assert(static_cast(MessageType::Game::REQUEST_NEAREST_ROCKET_LAUNCH_PRE_CONDITIONS) == 1387); +static_assert(static_cast(MessageType::Game::CONFIGURE_RACING_CONTROL) == 1388); +static_assert(static_cast(MessageType::Game::CONFIGURE_RACING_CONTROL_CLIENT) == 1389); +static_assert(static_cast(MessageType::Game::NOTIFY_RACING_CLIENT) == 1390); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_HACK_CAR) == 1391); +static_assert(static_cast(MessageType::Game::RACING_PLAYER_LOADED) == 1392); +static_assert(static_cast(MessageType::Game::RACING_CLIENT_READY) == 1393); +static_assert(static_cast(MessageType::Game::POSSESSION_FINISHED_ATTACH) == 1394); +static_assert(static_cast(MessageType::Game::UPDATE_CHAT_MODE) == 1395); +static_assert(static_cast(MessageType::Game::VEHICLE_NOTIFY_FINISHED_RACE) == 1396); +static_assert(static_cast(MessageType::Game::EQUIPPED_ITEM_STARTUP) == 1397); +static_assert(static_cast(MessageType::Game::FACTION_TRIGGER_ITEM_EQUIPPED) == 1400); +static_assert(static_cast(MessageType::Game::FACTION_TRIGGER_ITEM_UNEQUIPPED) == 1401); +static_assert(static_cast(MessageType::Game::TOGGLE_PROPERTY_BEHAVIORS) == 1402); +static_assert(static_cast(MessageType::Game::GET_UG_OBJECT_INFO) == 1405); +static_assert(static_cast(MessageType::Game::RESET_PROPERTY_BEHAVIORS) == 1406); +static_assert(static_cast(MessageType::Game::IS_PROPERTY_MODEL_RESET) == 1407); +static_assert(static_cast(MessageType::Game::SET_UG_OBJECT_NAME_AND_DESCRIPTION) == 1408); +static_assert(static_cast(MessageType::Game::SET_CONSUMABLE_ITEM) == 1409); +static_assert(static_cast(MessageType::Game::VEHICLE_GET_CURRENT_LAP) == 1410); +static_assert(static_cast(MessageType::Game::GET_UGID) == 1411); +static_assert(static_cast(MessageType::Game::SET_UGID) == 1412); +static_assert(static_cast(MessageType::Game::UGID_CHANGED) == 1413); +static_assert(static_cast(MessageType::Game::RACING_GET_CURRENT_LAP_FOR_PLAYER) == 1414); +static_assert(static_cast(MessageType::Game::SUB_ITEM_UN_EQUIPPED) == 1415); +static_assert(static_cast(MessageType::Game::SET_CUSTOM_DROP_SHADOW_TEXTURE) == 1416); +static_assert(static_cast(MessageType::Game::GET_PLAYER_KIT_FACTION) == 1418); +static_assert(static_cast(MessageType::Game::USED_INFORMATION_PLAQUE) == 1419); +static_assert(static_cast(MessageType::Game::RACING_ENABLE_WRONG_WAY_RESET) == 1420); +static_assert(static_cast(MessageType::Game::RACING_TOGGLE_RUBBER_BANDING) == 1421); +static_assert(static_cast(MessageType::Game::GET_RACING_CONTROL_DEBUG_INFO) == 1422); +static_assert(static_cast(MessageType::Game::SET_PROPERTY_BOUNDS_VISIBILITY) == 1423); +static_assert(static_cast(MessageType::Game::SET_PROPERTY_VENDOR_VISIBILITY) == 1424); +static_assert(static_cast(MessageType::Game::SET_EQUIP_STATE) == 1425); +static_assert(static_cast(MessageType::Game::NOTIFY_COMBAT_AI_STATE_CHANGE) == 1426); +static_assert(static_cast(MessageType::Game::SET_PROPERTY_MODEL_INTERACTIVE) == 1430); +static_assert(static_cast(MessageType::Game::SERVER_STATE_NOTIFY) == 1431); +static_assert(static_cast(MessageType::Game::GET_SERVER_STATE) == 1432); +static_assert(static_cast(MessageType::Game::GET_ICON_FOR_PROXIMITY) == 1433); +static_assert(static_cast(MessageType::Game::GET_LEGO_CLUB_MEMBERSHIP_STATUS) == 1434); +static_assert(static_cast(MessageType::Game::SET_STATUS_IMMUNITY) == 1435); +static_assert(static_cast(MessageType::Game::GET_STATUS_IMMUNITY) == 1436); +static_assert(static_cast(MessageType::Game::TEAM_IS_MEMBER) == 1437); +static_assert(static_cast(MessageType::Game::ACTIVATE_BRICK_MODE) == 1438); +static_assert(static_cast(MessageType::Game::GET_BUILD_OBJECT_ID) == 1439); +static_assert(static_cast(MessageType::Game::SET_ANIMATION_ENABLED) == 1444); +static_assert(static_cast(MessageType::Game::PAUSE_COOLDOWNS) == 1446); +static_assert(static_cast(MessageType::Game::FORCE_UPDATE_RENDER_NODE) == 1447); +static_assert(static_cast(MessageType::Game::SET_PET_NAME_MODERATED) == 1448); +static_assert(static_cast(MessageType::Game::TOGGLE_STRAFE_MODE) == 1449); +static_assert(static_cast(MessageType::Game::SET_SCHEME_SPEED_SCALE) == 1450); +static_assert(static_cast(MessageType::Game::CANCEL_SKILL_CAST) == 1451); +static_assert(static_cast(MessageType::Game::CHECK_PLAYER_ASSEMBLY_FOR_UNIQUE_MODULE_BY_LOT) == 1454); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_DB_DATA_TO_LUA) == 1455); +static_assert(static_cast(MessageType::Game::IS_ALLY) == 1458); +static_assert(static_cast(MessageType::Game::MODIFY_LEGO_SCORE) == 1459); +static_assert(static_cast(MessageType::Game::GET_LEGO_SCORE) == 1460); +static_assert(static_cast(MessageType::Game::GET_PLAYER_LEVEL) == 1461); +static_assert(static_cast(MessageType::Game::NOTIFY_LEGO_SCORE_UPDATE) == 1462); +static_assert(static_cast(MessageType::Game::SET_LEGO_SCORE) == 1463); +static_assert(static_cast(MessageType::Game::UPDATE_BEHAVIOR_EXECUTION_DETAILS) == 1466); +static_assert(static_cast(MessageType::Game::RESTORE_TO_POST_LOAD_STATS) == 1468); +static_assert(static_cast(MessageType::Game::PICKUP_OBJECT_ERROR) == 1469); +static_assert(static_cast(MessageType::Game::CHECK_AND_SHOW_INVENTORY_FULL_TIP) == 1470); +static_assert(static_cast(MessageType::Game::SET_RAIL_MOVEMENT) == 1471); +static_assert(static_cast(MessageType::Game::START_RAIL_MOVEMENT) == 1472); +static_assert(static_cast(MessageType::Game::SET_UP_VECTOR) == 1473); +static_assert(static_cast(MessageType::Game::CANCEL_RAIL_MOVEMENT) == 1474); +static_assert(static_cast(MessageType::Game::GET_RAIL_INFO) == 1475); +static_assert(static_cast(MessageType::Game::CLIENT_RAIL_MOVEMENT_READY) == 1476); +static_assert(static_cast(MessageType::Game::PLAYER_RAIL_ARRIVED_NOTIFICATION) == 1477); +static_assert(static_cast(MessageType::Game::NOTIFY_RAIL_ACTOVATOR_STATE_CHANGE) == 1478); +static_assert(static_cast(MessageType::Game::REQUEST_RAIL_ACTIVATOR_STATE) == 1479); +static_assert(static_cast(MessageType::Game::NOTIFY_REWARD_MAILED) == 1480); +static_assert(static_cast(MessageType::Game::UPDATE_PLAYER_STATISTIC) == 1481); +static_assert(static_cast(MessageType::Game::IS_IN_COMBAT) == 1482); +static_assert(static_cast(MessageType::Game::IS_PRIMITIVE_MODEL_MSG) == 1483); +static_assert(static_cast(MessageType::Game::SCALE_PRIMITICE_MODEL_MSG) == 1484); +static_assert(static_cast(MessageType::Game::MODIFY_GHOSTING_DISTANCE) == 1485); +static_assert(static_cast(MessageType::Game::PRIMITIVE_MODEL_CHANGED_MSG) == 1487); +static_assert(static_cast(MessageType::Game::GET_PROPRTY_CLONE_ID) == 1488); +static_assert(static_cast(MessageType::Game::REQUEST_LEAVE_PROPERTY) == 1489); +static_assert(static_cast(MessageType::Game::REQUERY_PROPERTY_MODELS) == 1491); +static_assert(static_cast(MessageType::Game::GET_BEHAVIOR_COUNT) == 1492); +static_assert(static_cast(MessageType::Game::UPDATE_BEHAVIOR_CONTROLS) == 1493); +static_assert(static_cast(MessageType::Game::MODULE_ASSEMBLY_LXFML_LOADED) == 1494); +static_assert(static_cast(MessageType::Game::REQUEST_ASSEMBLED_LXFML) == 1495); +static_assert(static_cast(MessageType::Game::ASSEMBLED_LXFML_LOADED) == 1496); +static_assert(static_cast(MessageType::Game::GET_REORIENT_UP_VECTOR) == 1497); +static_assert(static_cast(MessageType::Game::MODULAR_ASSEMBLY_NIF_COMPLETED) == 1498); +static_assert(static_cast(MessageType::Game::CHARACTER_DISCONNECT_BEFORE_CREATE) == 1499); +static_assert(static_cast(MessageType::Game::SEND_LAUNCH_TO_PREVIOUS_ZONE_TO_CLIENT) == 1500); +static_assert(static_cast(MessageType::Game::ROCKETLAUNCH_REQUEST_DEFAULT_MAP_ID) == 1501); +static_assert(static_cast(MessageType::Game::BEGIN_LAUNCH) == 1502); +static_assert(static_cast(MessageType::Game::PROCESS_CLAIM_CODES) == 1503); +static_assert(static_cast(MessageType::Game::GET_LAST_ZONE_ID) == 1504); +static_assert(static_cast(MessageType::Game::ADD_RUN_SPEED_MODIFIER) == 1505); +static_assert(static_cast(MessageType::Game::REMOVE_RUN_SPEED_MODIFIER) == 1506); +static_assert(static_cast(MessageType::Game::SKILL_EVENT_FIRED) == 1507); +static_assert(static_cast(MessageType::Game::SEND_HOT_PROPERTY_DATA) == 1510); +static_assert(static_cast(MessageType::Game::GET_HOT_PROPERTY_DATA) == 1511); +static_assert(static_cast(MessageType::Game::GET_EQUIPPED_ITEMS_IN_SET) == 1512); +static_assert(static_cast(MessageType::Game::IS_ITEM_IN_SET) == 1513); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_TYPE_FOR_LOT) == 1514); +static_assert(static_cast(MessageType::Game::GET_BANK_TYPE_FOR_LOT) == 1515); +static_assert(static_cast(MessageType::Game::NOTIFY_NOT_ENOUGH_INV_SPACE) == 1516); +static_assert(static_cast(MessageType::Game::IMPORT_MODEL_TO_BBB) == 1517); +static_assert(static_cast(MessageType::Game::SEARCH_NEARBY_OBJECTS) == 1518); +static_assert(static_cast(MessageType::Game::SEARCH_NEARBY_OBJECTS_REQUEST_BY_LOT) == 1519); +static_assert(static_cast(MessageType::Game::REQUEST_OBJECT_POSITION_BY_ID) == 1520); +static_assert(static_cast(MessageType::Game::SEARCH_NEARBY_OBJECTS_REQUEST_BY_COMPONENT) == 1521); +static_assert(static_cast(MessageType::Game::SEARCH_NEARBY_OBJECTS_RESPONSE) == 1522); +static_assert(static_cast(MessageType::Game::BROADCAST_NON_STANDARD_COLLISIONS) == 1523); +static_assert(static_cast(MessageType::Game::GET_REGISTERED_NON_STANDARD_COLLISION_GROUP) == 1524); +static_assert(static_cast(MessageType::Game::BROADCAST_CRUSHED_NOTIFICATIONS) == 1525); +static_assert(static_cast(MessageType::Game::GET_REGISTERED_CRUSHED_COLLISION_GROUPS) == 1526); +static_assert(static_cast(MessageType::Game::IS_BEING_CRUSHED) == 1527); +static_assert(static_cast(MessageType::Game::GET_SUPPORTING_OBJECT) == 1528); +static_assert(static_cast(MessageType::Game::TREAT_RIGID_BODY_COLLSIONS_AS_FIXED) == 1529); +static_assert(static_cast(MessageType::Game::BROADCAST_TELEPORTED_WITHIN_NOTIFICATION) == 1530); +static_assert(static_cast(MessageType::Game::GET_REGISTERED_TELEPORTED_WITHIN_OBJECT_GROUP) == 1531); +static_assert(static_cast(MessageType::Game::GET_INTERPENTRATING_INFORMATION) == 1532); +static_assert(static_cast(MessageType::Game::OBJECT_TELEPORTED_WITHIN) == 1533); +static_assert(static_cast(MessageType::Game::SET_PHYSICS_SOLVER_PROPERTIES) == 1534); +static_assert(static_cast(MessageType::Game::HAS_BEHAVIORS) == 1535); +static_assert(static_cast(MessageType::Game::PLAY_BEHAVIOR_SOUND) == 1536); +static_assert(static_cast(MessageType::Game::GET_PLAYER_BEHAVIOR_TIER) == 1537); +static_assert(static_cast(MessageType::Game::GET_EMOTE_ANIMATION_TIME) == 1538); +static_assert(static_cast(MessageType::Game::GET_CHARACTER_STAT_TRACKING) == 1539); +static_assert(static_cast(MessageType::Game::PLAYER_INVENTORY_READY) == 1540); +static_assert(static_cast(MessageType::Game::SET_PRECONDITIONS) == 1541); +static_assert(static_cast(MessageType::Game::DETACH_SHADOW) == 1542); +static_assert(static_cast(MessageType::Game::GET_LOOT_INFO) == 1543); +static_assert(static_cast(MessageType::Game::GET_PLAYERS_ON_PROPERTY) == 1544); +static_assert(static_cast(MessageType::Game::PROPERTY_SPAWN_BY_BEHAVIOR) == 1545); +static_assert(static_cast(MessageType::Game::NOTIFY_PROPERTY_OF_EDIT_MODE) == 1546); +static_assert(static_cast(MessageType::Game::UPDATE_PROPERTY_PERFORMANCE_COST) == 1547); +static_assert(static_cast(MessageType::Game::GET_PROPERTY_PERFORMANCE_COST) == 1548); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_ITEM_WITH_SUBKEY) == 1549); +static_assert(static_cast(MessageType::Game::DISPLAY_PROPERTY_SUMMARY_SCREEN) == 1550); +static_assert(static_cast(MessageType::Game::VALIDATE_BBB_MODEL) == 1551); +static_assert(static_cast(MessageType::Game::BBB_MODEL_VALIDATION) == 1552); +static_assert(static_cast(MessageType::Game::PROPERTY_ENTRANCE_BEGIN) == 1553); +static_assert(static_cast(MessageType::Game::CHECK_LIST_OF_PRECONDITIONS_FROM_LUA) == 1554); +static_assert(static_cast(MessageType::Game::GET_PROPERTYIN_ZONE) == 1555); +static_assert(static_cast(MessageType::Game::GET_ZONE_ID_FROM_MULTI_ZONE_ENTRANCE) == 1556); +static_assert(static_cast(MessageType::Game::TEAM_SET_LEADER) == 1557); +static_assert(static_cast(MessageType::Game::TEAM_INVITE_CONFIRM) == 1558); +static_assert(static_cast(MessageType::Game::TEAM_GET_STATUS_RESPONSE) == 1559); +static_assert(static_cast(MessageType::Game::MINI_GAME_ENABLE_LOCAL_TEAMS) == 1560); +static_assert(static_cast(MessageType::Game::TEAM_INVITE_FINAL_RESPONSE) == 1561); +static_assert(static_cast(MessageType::Game::TEAM_ADD_PLAYER) == 1562); +static_assert(static_cast(MessageType::Game::TEAM_REMOVE_PLAYER) == 1563); +static_assert(static_cast(MessageType::Game::TEAM_CREATE_LOCAL) == 1564); +static_assert(static_cast(MessageType::Game::TEAM_GET_LOOT) == 1565); +static_assert(static_cast(MessageType::Game::TEAM_SET_LOOT) == 1566); +static_assert(static_cast(MessageType::Game::SET_ZERO_IMPULSE_AGAINST_COLLISION_GROUPS) == 1567); +static_assert(static_cast(MessageType::Game::SET_CENTER_OF_MASS_TO_PHYSICAL_CENTER) == 1568); +static_assert(static_cast(MessageType::Game::SET_INERTIA_INVERSE) == 1569); +static_assert(static_cast(MessageType::Game::ADD_REMOVE_CLIMBING_LISTENER) == 1570); +static_assert(static_cast(MessageType::Game::GET_INVENTORYITEM_DETAILS) == 1571); +static_assert(static_cast(MessageType::Game::PERFORM_CLIENT_SIDE_DEATH) == 1572); +static_assert(static_cast(MessageType::Game::LEGO_CLUB_ACCESS_RESULT) == 1573); +static_assert(static_cast(MessageType::Game::VEHICLE_GET_IS_REVERSING) == 1574); +static_assert(static_cast(MessageType::Game::CHECK_CLAIM_CODE) == 1575); +static_assert(static_cast(MessageType::Game::GET_HOLIDAY_EVENT) == 1576); +static_assert(static_cast(MessageType::Game::SET_EMOTES_ENABLED) == 1577); +static_assert(static_cast(MessageType::Game::GET_EMOTES_ENABLED) == 1578); +static_assert(static_cast(MessageType::Game::FREEZE_ANIMATION) == 1579); +static_assert(static_cast(MessageType::Game::LOCALIZED_ANNOUNCEMENT_SERVER_TO_SINGLE_CLIENT) == 1580); +static_assert(static_cast(MessageType::Game::ANCHOR_FX_NODE) == 1581); +static_assert(static_cast(MessageType::Game::WS_GET_FRIEND_LIST_MESSAGE) == 1582); +static_assert(static_cast(MessageType::Game::WS_ADD_FRIEND_RESPONSE) == 1583); +static_assert(static_cast(MessageType::Game::WS_REMOVE_FRIEND_REPSONSE) == 1584); +static_assert(static_cast(MessageType::Game::WS_UPDATE_FRIEND_STATUS) == 1585); +static_assert(static_cast(MessageType::Game::WS_UPDATE_FRIEND_NAME) == 1586); +static_assert(static_cast(MessageType::Game::IS_BEST_FRIEND) == 1587); +static_assert(static_cast(MessageType::Game::TEAM_NOTIFY_UPDATE_MISSION_TASK) == 1588); +static_assert(static_cast(MessageType::Game::VEHICLE_ADD_SLIPPERY_ACTION) == 1589); +static_assert(static_cast(MessageType::Game::VEHICLE_REMOVE_SLIPPERY_ACTION) == 1590); +static_assert(static_cast(MessageType::Game::SET_RESURRECT_RESTORE_VALUES) == 1591); +static_assert(static_cast(MessageType::Game::GET_MASS) == 1592); +static_assert(static_cast(MessageType::Game::SET_PROPERTY_MODERATION_STATUS) == 1593); +static_assert(static_cast(MessageType::Game::UPDATE_PROPERTY_MODEL_DEFAULTS) == 1594); +static_assert(static_cast(MessageType::Game::UPDATE_PROPERTYMODEL_COUNT) == 1595); +static_assert(static_cast(MessageType::Game::GET_PROPERTY_MODEL_COUNT) == 1596); +static_assert(static_cast(MessageType::Game::IS_PLAYER_LOADED) == 1597); +static_assert(static_cast(MessageType::Game::ATTACH_RENDER_EFFECT_FROM_LUA) == 1598); +static_assert(static_cast(MessageType::Game::DETACH_RENDER_EFFECT_FROM_LUA) == 1599); +static_assert(static_cast(MessageType::Game::TEAM_IS_LOCAL) == 1600); +static_assert(static_cast(MessageType::Game::CREATE_CAMERA_PARTICLES) == 1602); +static_assert(static_cast(MessageType::Game::SET_SMASHABLE_GRAVITY_FACTOR) == 1603); +static_assert(static_cast(MessageType::Game::VEHICLE_SET_SURFACE_TYPE_OVERRIDE) == 1604); +static_assert(static_cast(MessageType::Game::VEHICLE_NOTIFY_HIT_IMAGINATION) == 1605); +static_assert(static_cast(MessageType::Game::VEHICLE_NOTIFY_HIT_IMAGINATION_SERVER) == 1606); +static_assert(static_cast(MessageType::Game::GET_SPAWNED_OBJECT_SPAWNER_INFO) == 1607); +static_assert(static_cast(MessageType::Game::SAVE_PROPERTY) == 1608); +static_assert(static_cast(MessageType::Game::SET_PROPERTY_DIRTY) == 1609); +static_assert(static_cast(MessageType::Game::GET_PROPERTY_DIRTY) == 1610); +static_assert(static_cast(MessageType::Game::GET_MODEL_LIST_FROM_PLAQUE) == 1611); +static_assert(static_cast(MessageType::Game::GET_ORIGINAL_POSITION_AND_ROTATION) == 1612); +static_assert(static_cast(MessageType::Game::VEHICLE_SET_MASS_FOR_COLLISION) == 1613); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_GROUP_COUNT) == 1614); +static_assert(static_cast(MessageType::Game::GET_LATEST_CHAT_CHANNEL_USED) == 1615); +static_assert(static_cast(MessageType::Game::SET_SUGGEST_LIST_LANGUAGE) == 1616); +static_assert(static_cast(MessageType::Game::VEHICLE_STOP_BOOST) == 1617); +static_assert(static_cast(MessageType::Game::START_CELEBRATION_EFFECT) == 1618); +static_assert(static_cast(MessageType::Game::LOCK_PLAYER) == 1619); +static_assert(static_cast(MessageType::Game::VEHICLE_IS_INPUT_LOCKED) == 1620); +static_assert(static_cast(MessageType::Game::GET_MULTI_NODE) == 1621); +static_assert(static_cast(MessageType::Game::RENEW_PROPERTY) == 1622); +static_assert(static_cast(MessageType::Game::RENEW_PROPERTY_RESULT) == 1623); +static_assert(static_cast(MessageType::Game::CHARGE_ACTIVITY_COST) == 1624); +static_assert(static_cast(MessageType::Game::CAN_RECEIVE_LOOT) == 1625); +static_assert(static_cast(MessageType::Game::JOIN_PLAYER_FACTION) == 1626); +static_assert(static_cast(MessageType::Game::SET_PROXIMITY_UPDATE_RATE) == 1627); +static_assert(static_cast(MessageType::Game::BBB_MODELS_TO_SAVE) == 1628); +static_assert(static_cast(MessageType::Game::BELONGS_TO_FACTION) == 1629); +static_assert(static_cast(MessageType::Game::MODIFY_FACTION) == 1630); +static_assert(static_cast(MessageType::Game::FACTION_UPDATE) == 1631); +static_assert(static_cast(MessageType::Game::CELEBRATION_COMPLETED) == 1632); +static_assert(static_cast(MessageType::Game::PLAY_PRIMARY_MODULE_SOUNDS) == 1633); +static_assert(static_cast(MessageType::Game::STOP_PRIMARY_MODULE_SOUNDS) == 1634); +static_assert(static_cast(MessageType::Game::REQUEST_TEAM_PLAYER_UI_UPDATE) == 1635); +static_assert(static_cast(MessageType::Game::SET_LOCAL_TEAM) == 1636); +static_assert(static_cast(MessageType::Game::TEAM_GET_WORLD_MEMBERS_IN_RADIUS) == 1637); +static_assert(static_cast(MessageType::Game::GET_PARENTAL_LEVEL) == 1638); +static_assert(static_cast(MessageType::Game::GET_OBJECTS_MESSAGE_HANDLERS) == 1639); +static_assert(static_cast(MessageType::Game::PROPERTY_FEATURED) == 1640); +static_assert(static_cast(MessageType::Game::PROPERTY_NOTIFY_MODEL_SPAWNED) == 1641); +static_assert(static_cast(MessageType::Game::SERVER_DONE_LOADING_ALL_OBJECTS) == 1642); +static_assert(static_cast(MessageType::Game::GET_DONATION_TOTAL) == 1643); +static_assert(static_cast(MessageType::Game::UPDATE_DONATION_VALUES) == 1644); +static_assert(static_cast(MessageType::Game::DELAYED_DELETE_DROP_EFFECT_BRICK) == 1645); +static_assert(static_cast(MessageType::Game::SET_CAMERA_UNLOCK_ROTATION_STATE) == 1646); +static_assert(static_cast(MessageType::Game::ADD_BUFF) == 1647); +static_assert(static_cast(MessageType::Game::REMOVE_BUFF) == 1648); +static_assert(static_cast(MessageType::Game::CHECK_FOR_BUFF) == 1649); +static_assert(static_cast(MessageType::Game::TEAM_MEMBERS_DISOWNS_LOOT) == 1650); +static_assert(static_cast(MessageType::Game::GET_WHEEL_TEMPLATE) == 1651); +static_assert(static_cast(MessageType::Game::ADD_SKILL_IN_PROGRESS) == 1652); +static_assert(static_cast(MessageType::Game::REMOVE_SKILL_IN_PROGRESS) == 1653); +static_assert(static_cast(MessageType::Game::SET_OVERHEAD_ICON_OFFSET) == 1654); +static_assert(static_cast(MessageType::Game::SET_BILLBOARD_OFFSET) == 1655); +static_assert(static_cast(MessageType::Game::SET_CHAT_BUBBLE_OFFSET) == 1656); +static_assert(static_cast(MessageType::Game::SET_NO_TEAM_INVITES) == 1657); +static_assert(static_cast(MessageType::Game::RESET_MODEL_TO_DEFAULTS) == 1658); +static_assert(static_cast(MessageType::Game::IS_PROPERTY_IN_EDIT_MODE) == 1659); +static_assert(static_cast(MessageType::Game::GET_OBJECTS_IN_PHYSICS_BOUNDS) == 1660); +static_assert(static_cast(MessageType::Game::ENABLE_LU_REMOTE) == 1661); +static_assert(static_cast(MessageType::Game::SET_IS_USING_FREE_TRIAL) == 1662); +static_assert(static_cast(MessageType::Game::GET_IS_USING_FREE_TRIAL) == 1663); +static_assert(static_cast(MessageType::Game::GET_ACCOUNT_FREE_TRIAL_MODE) == 1664); +static_assert(static_cast(MessageType::Game::TOGGLE_INVENTORY_ITEM_LOCK) == 1665); +static_assert(static_cast(MessageType::Game::REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES) == 1666); +static_assert(static_cast(MessageType::Game::RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES) == 1667); +static_assert(static_cast(MessageType::Game::REMOVE_SUB_COMPONENT) == 1668); +static_assert(static_cast(MessageType::Game::TEAM_GET_LOOT_MEMBERS) == 1669); +static_assert(static_cast(MessageType::Game::GET_FACTION_TOKEN_TYPE) == 1670); +static_assert(static_cast(MessageType::Game::GET_SUBSCRIPTION_PRICING) == 1671); +static_assert(static_cast(MessageType::Game::INFORM_AFK) == 1672); +static_assert(static_cast(MessageType::Game::OVERHEAD_INDICATOR_CREATED) == 1673); +static_assert(static_cast(MessageType::Game::SET_OVERHEAD_INDICATOR_GRID_LOCATION) == 1674); +static_assert(static_cast(MessageType::Game::PLAYSTREAM_LOAD_PENDING) == 1675); +static_assert(static_cast(MessageType::Game::PLAYER_SET_CAMERA_CYCLING_MODE) == 1676); +static_assert(static_cast(MessageType::Game::PLAYER_GET_CAMERA_CYCLING_MODE) == 1677); +static_assert(static_cast(MessageType::Game::FORCE_CAMERA_TARGET_CYCLE) == 1678); +static_assert(static_cast(MessageType::Game::GET_OBJECT_CONFIG_DATA) == 1679); +static_assert(static_cast(MessageType::Game::GET_OBJECT_CONFIG_DATA_NON_CONST) == 1680); +static_assert(static_cast(MessageType::Game::SCOPE_CHANGED) == 1681); +static_assert(static_cast(MessageType::Game::SET_ALLOW_JUMP_WITHOUT_SUPPORT) == 1682); +static_assert(static_cast(MessageType::Game::GET_ALLOW_JUMP_WITHOUT_SUPPORT) == 1683); +static_assert(static_cast(MessageType::Game::SET_JUMP_HEIGHT_SCALE) == 1684); +static_assert(static_cast(MessageType::Game::GET_JUMP_HEIGHT_SCALE) == 1685); +static_assert(static_cast(MessageType::Game::SET_VELOCITY_RESISTANCE) == 1686); +static_assert(static_cast(MessageType::Game::GET_VELOCITY_RESISTANCE) == 1687); +static_assert(static_cast(MessageType::Game::GATE_RUSH_VEHICLE_HIT_GATE) == 1688); +static_assert(static_cast(MessageType::Game::GATE_RUSH_PLAYER_COLLECTED_GATE) == 1689); +static_assert(static_cast(MessageType::Game::GATE_RUSH_ADD_GATE) == 1690); +static_assert(static_cast(MessageType::Game::GATE_RUSH_REMOVE_GATE) == 1691); +static_assert(static_cast(MessageType::Game::NOTIFY_VEHICLE_UPDATED) == 1692); +static_assert(static_cast(MessageType::Game::VEHICLE_NOTIFY_HIT_WEAPON_POWERUP) == 1693); +static_assert(static_cast(MessageType::Game::VEHICLE_NOTIFY_HIT_WEAPON_POWERUP_SERVER) == 1694); +static_assert(static_cast(MessageType::Game::LOCAL_PLAYER_TARGETED) == 1696); +static_assert(static_cast(MessageType::Game::SKILL_COUNT_CHANGED) == 1697); +static_assert(static_cast(MessageType::Game::DO_YAW_ROTATION) == 1698); +static_assert(static_cast(MessageType::Game::DO_PITCH_ROTATION) == 1699); +static_assert(static_cast(MessageType::Game::DO_ROLL_ROTATION) == 1700); +static_assert(static_cast(MessageType::Game::GET_CURRENT_LOOT_MATRIX) == 1701); +static_assert(static_cast(MessageType::Game::SEND_MULTI_MISSION_OFFER_UPDATE_I_DS) == 1702); +static_assert(static_cast(MessageType::Game::SET_AIR_SPEED_VALUES) == 1703); +static_assert(static_cast(MessageType::Game::USE_LAUNCHER) == 1704); +static_assert(static_cast(MessageType::Game::START_LAUNCHER) == 1705); +static_assert(static_cast(MessageType::Game::STOP_LAUNCHER) == 1706); +static_assert(static_cast(MessageType::Game::CAN_USE_JET_PACK) == 1707); +static_assert(static_cast(MessageType::Game::JET_PACK_STATE_CHANGED) == 1708); +static_assert(static_cast(MessageType::Game::TURN_OFF_JET_PACK) == 1709); +static_assert(static_cast(MessageType::Game::ADD_PLAYER_JET_PACK_PAD) == 1710); +static_assert(static_cast(MessageType::Game::SET_JET_PACK_WARNING) == 1711); +static_assert(static_cast(MessageType::Game::JET_PACK_DISABLED) == 1712); +static_assert(static_cast(MessageType::Game::JET_PACK_PAD_ENTERED) == 1713); +static_assert(static_cast(MessageType::Game::UPDATE_RENDER_POSSESSION_FLAG) == 1714); +static_assert(static_cast(MessageType::Game::POSSESSABLE_GET_ATTACH_OFFSET) == 1715); +static_assert(static_cast(MessageType::Game::ATTEMPT_TO_CRAFT_ITEM) == 1718); +static_assert(static_cast(MessageType::Game::CRAFT_ATTEMPT_RESPONSE) == 1719); +static_assert(static_cast(MessageType::Game::SET_C_SCORE) == 1720); +static_assert(static_cast(MessageType::Game::FILL_IN_RENDERER) == 1721); +static_assert(static_cast(MessageType::Game::TOGGLE_CRAFTING_WINDOW) == 1722); +static_assert(static_cast(MessageType::Game::REMOVE_TEAM_BUFFS) == 1724); +static_assert(static_cast(MessageType::Game::REQUEST_FREE_TRIAL_STATUS_REFRESH) == 1725); +static_assert(static_cast(MessageType::Game::REMOVE_BUFFS_APPLIED_BY_OBJECT) == 1726); +static_assert(static_cast(MessageType::Game::SET_MOUNT_INVENTORY_ID) == 1727); +static_assert(static_cast(MessageType::Game::GET_MOUNT_INVENTORY_ID) == 1728); +static_assert(static_cast(MessageType::Game::GET_BUILD_CINEMATIC_TIME_REMAINING) == 1730); +static_assert(static_cast(MessageType::Game::JET_PACK_FLYING) == 1731); +static_assert(static_cast(MessageType::Game::NOTIFY_SERVER_LEVEL_PROCESSING_COMPLETE) == 1734); +static_assert(static_cast(MessageType::Game::NOTIFY_LEVEL_REWARDS) == 1735); +static_assert(static_cast(MessageType::Game::CHARACTER_VERSION_CHANGED) == 1736); +static_assert(static_cast(MessageType::Game::SET_FREE_TRIAL_RENAME_AVAILABLE) == 1737); +static_assert(static_cast(MessageType::Game::SET_PROJECTILE_LAUNCHER_PARAMS) == 1738); +static_assert(static_cast(MessageType::Game::RACE_PRECOUNTDOWN_DONE) == 1739); +static_assert(static_cast(MessageType::Game::CHECK_INVITE_SPAMMING) == 1740); +static_assert(static_cast(MessageType::Game::GET_RESPAWN_VOLUME_INFO) == 1741); +static_assert(static_cast(MessageType::Game::INVITE_ACCEPTED) == 1742); +static_assert(static_cast(MessageType::Game::TELEPORT_TO_NEAREST_RESPAWN) == 1743); +static_assert(static_cast(MessageType::Game::SET_SKILL_CANCEL_ON_MOVE) == 1744); +static_assert(static_cast(MessageType::Game::CANCEL_MOVE_SKILL) == 1745); +static_assert(static_cast(MessageType::Game::SERVER_CANCEL_MOVE_SKILL) == 1746); +static_assert(static_cast(MessageType::Game::CLIENT_CANCEL_MOVE_SKILL) == 1747); +static_assert(static_cast(MessageType::Game::END_LAUNCH_SEQUENCE) == 1748); +static_assert(static_cast(MessageType::Game::CANCEL_QUEUE) == 1749); +static_assert(static_cast(MessageType::Game::UPDATE_PROJECTILE_LAUNCHER_ROTATION) == 1750); +static_assert(static_cast(MessageType::Game::GET_CHARACTER_VERSION_INFO) == 1751); +static_assert(static_cast(MessageType::Game::GET_CON_INFO) == 1753); +static_assert(static_cast(MessageType::Game::GET_SKILLS_FOR_LOT) == 1755); +static_assert(static_cast(MessageType::Game::DISMOUNT_COMPLETE) == 1756); +static_assert(static_cast(MessageType::Game::MOUNT_FAILURE_RESPONSE) == 1757); +static_assert(static_cast(MessageType::Game::CLEAR_BILLBOARD_OFFSET) == 1758); +static_assert(static_cast(MessageType::Game::GET_INVENTORY_ITEM_ANIMATION_FLAG) == 1759); +static_assert(static_cast(MessageType::Game::SET_JET_PACK_ALLOWED) == 1760); +static_assert(static_cast(MessageType::Game::GET_BUILD_TIME_DETAILS) == 1761); +static_assert(static_cast(MessageType::Game::USE_SKILL_SET) == 1762); +static_assert(static_cast(MessageType::Game::SET_SKILL_SET_POSSESSOR) == 1763); +static_assert(static_cast(MessageType::Game::POPULATE_ACTION_BAR) == 1764); +static_assert(static_cast(MessageType::Game::GET_COMPONENT_TEMPLATE_ID) == 1765); +static_assert(static_cast(MessageType::Game::GET_POSSESSABLE_SKILL_SET) == 1766); +static_assert(static_cast(MessageType::Game::MARK_INVENTORY_ITEM_AS_ACTIVE) == 1767); +static_assert(static_cast(MessageType::Game::UPDATE_FORGED_ITEM) == 1768); +static_assert(static_cast(MessageType::Game::CAN_ITEMS_BE_REFORGED) == 1769); +static_assert(static_cast(MessageType::Game::NOTIFY_CLIENT_RAIL_START_FAILED) == 1771); +static_assert(static_cast(MessageType::Game::GET_IS_ON_RAIL) == 1772); + +// MessageType::Master: 19 enumerators +static_assert(static_cast(MessageType::Master::REQUEST_ZONE_TRANSFER) == 1); +static_assert(static_cast(MessageType::Master::REQUEST_ZONE_TRANSFER_RESPONSE) == 2); +static_assert(static_cast(MessageType::Master::SERVER_INFO) == 3); +static_assert(static_cast(MessageType::Master::REQUEST_SESSION_KEY) == 4); +static_assert(static_cast(MessageType::Master::SET_SESSION_KEY) == 5); +static_assert(static_cast(MessageType::Master::SESSION_KEY_RESPONSE) == 6); +static_assert(static_cast(MessageType::Master::PLAYER_ADDED) == 7); +static_assert(static_cast(MessageType::Master::PLAYER_REMOVED) == 8); +static_assert(static_cast(MessageType::Master::CREATE_PRIVATE_ZONE) == 9); +static_assert(static_cast(MessageType::Master::REQUEST_PRIVATE_ZONE) == 10); +static_assert(static_cast(MessageType::Master::WORLD_READY) == 11); +static_assert(static_cast(MessageType::Master::PREP_ZONE) == 12); +static_assert(static_cast(MessageType::Master::SHUTDOWN) == 13); +static_assert(static_cast(MessageType::Master::SHUTDOWN_RESPONSE) == 14); +static_assert(static_cast(MessageType::Master::SHUTDOWN_IMMEDIATE) == 15); +static_assert(static_cast(MessageType::Master::SHUTDOWN_UNIVERSE) == 16); +static_assert(static_cast(MessageType::Master::AFFIRM_TRANSFER_REQUEST) == 17); +static_assert(static_cast(MessageType::Master::AFFIRM_TRANSFER_RESPONSE) == 18); +static_assert(static_cast(MessageType::Master::NEW_SESSION_ALERT) == 19); + +// MessageType::Server: 3 enumerators +static_assert(static_cast(MessageType::Server::VERSION_CONFIRM) == 0); +static_assert(static_cast(MessageType::Server::DISCONNECT_NOTIFY) == 1); +static_assert(static_cast(MessageType::Server::GENERAL_NOTIFY) == 2); + +// MessageType::World: 34 enumerators +static_assert(static_cast(MessageType::World::VALIDATION) == 1); +static_assert(static_cast(MessageType::World::CHARACTER_LIST_REQUEST) == 2); +static_assert(static_cast(MessageType::World::CHARACTER_CREATE_REQUEST) == 3); +static_assert(static_cast(MessageType::World::LOGIN_REQUEST) == 4); +static_assert(static_cast(MessageType::World::GAME_MSG) == 5); +static_assert(static_cast(MessageType::World::CHARACTER_DELETE_REQUEST) == 6); +static_assert(static_cast(MessageType::World::CHARACTER_RENAME_REQUEST) == 7); +static_assert(static_cast(MessageType::World::HAPPY_FLOWER_MODE_NOTIFY) == 8); +static_assert(static_cast(MessageType::World::SLASH_RELOAD_MAP) == 9); +static_assert(static_cast(MessageType::World::SLASH_PUSH_MAP_REQUEST) == 10); +static_assert(static_cast(MessageType::World::SLASH_PUSH_MAP) == 11); +static_assert(static_cast(MessageType::World::SLASH_PULL_MAP) == 12); +static_assert(static_cast(MessageType::World::LOCK_MAP_REQUEST) == 13); +static_assert(static_cast(MessageType::World::GENERAL_CHAT_MESSAGE) == 14); +static_assert(static_cast(MessageType::World::HTTP_MONITOR_INFO_REQUEST) == 15); +static_assert(static_cast(MessageType::World::SLASH_DEBUG_SCRIPTS) == 16); +static_assert(static_cast(MessageType::World::MODELS_CLEAR) == 17); +static_assert(static_cast(MessageType::World::EXHIBIT_INSERT_MODEL) == 18); +static_assert(static_cast(MessageType::World::LEVEL_LOAD_COMPLETE) == 19); +static_assert(static_cast(MessageType::World::TMP_GUILD_CREATE) == 20); +static_assert(static_cast(MessageType::World::ROUTE_PACKET) == 21); +static_assert(static_cast(MessageType::World::POSITION_UPDATE) == 22); +static_assert(static_cast(MessageType::World::MAIL) == 23); +static_assert(static_cast(MessageType::World::WORD_CHECK) == 24); +static_assert(static_cast(MessageType::World::STRING_CHECK) == 25); +static_assert(static_cast(MessageType::World::GET_PLAYERS_IN_ZONE) == 26); +static_assert(static_cast(MessageType::World::REQUEST_UGC_MANIFEST_INFO) == 27); +static_assert(static_cast(MessageType::World::BLUEPRINT_GET_ALL_DATA_REQUEST) == 28); +static_assert(static_cast(MessageType::World::CANCEL_MAP_QUEUE) == 29); +static_assert(static_cast(MessageType::World::HANDLE_FUNNESS) == 30); +static_assert(static_cast(MessageType::World::FAKE_PRG_CSR_MESSAGE) == 31); +static_assert(static_cast(MessageType::World::REQUEST_FREE_TRIAL_REFRESH) == 32); +static_assert(static_cast(MessageType::World::GM_SET_FREE_TRIAL_STATUS) == 33); +static_assert(static_cast(MessageType::World::UI_HELP_TOP_5) == 91); + +// ServiceType: 7 enumerators +static_assert(static_cast(ServiceType::COMMON) == 0); +static_assert(static_cast(ServiceType::AUTH) == 1); +static_assert(static_cast(ServiceType::CHAT) == 2); +static_assert(static_cast(ServiceType::WORLD) == 4); +static_assert(static_cast(ServiceType::CLIENT) == 5); +static_assert(static_cast(ServiceType::MASTER) == 6); +static_assert(static_cast(ServiceType::UNKNOWN) == 7); + +// The asserts above are compile time; this test only makes the file show up in test runs. +TEST(MessageIdPinTests, MessageTypeValuesArePinned) { SUCCEED(); } diff --git a/tests/dCommonTests/TestBitStreamUtils.cpp b/tests/dCommonTests/TestBitStreamUtils.cpp new file mode 100644 index 000000000..816f1c0fe --- /dev/null +++ b/tests/dCommonTests/TestBitStreamUtils.cpp @@ -0,0 +1,114 @@ +#include + +#include "BitStreamUtils.h" + +#include + +namespace { + std::vector Bytes(RakNet::BitStream& bitStream) { + return { bitStream.GetData(), bitStream.GetData() + bitStream.GetNumberOfBytesUsed() }; + } +} + +// The helper must produce exactly what the hand written "size then one char at a time" loops produce. +TEST(BitStreamUtilsTests, WriteLengthPrefixedU16MatchesPerCharacterLoop) { + const std::u16string value = u"sfx/countdown"; + + RakNet::BitStream expected; + expected.Write(true); // misalign the stream by one bit, like a leading bool field would + expected.Write(value.size()); + for (const auto character : value) expected.Write(character); + + RakNet::BitStream actual; + actual.Write(true); + BitStreamUtils::WriteLengthPrefixed(actual, value); + + ASSERT_EQ(actual.GetNumberOfBitsUsed(), expected.GetNumberOfBitsUsed()); + ASSERT_EQ(Bytes(actual), Bytes(expected)); +} + +TEST(BitStreamUtilsTests, WriteLengthPrefixedStringGolden) { + RakNet::BitStream bitStream; + BitStreamUtils::WriteLengthPrefixed(bitStream, std::string("ab")); + const std::vector golden = { 0x02, 0x00, 'a', 'b' }; + ASSERT_EQ(Bytes(bitStream), golden); +} + +TEST(BitStreamUtilsTests, LengthPrefixedRoundTrip) { + const std::u16string value = u"Hello ΓΌ"; + RakNet::BitStream bitStream; + bitStream.Write(false); + BitStreamUtils::WriteLengthPrefixed(bitStream, value); + BitStreamUtils::WriteLengthPrefixed(bitStream, std::u16string()); + + bool leading = true; + std::u16string read = u"garbage"; + std::u16string empty = u"garbage"; + ASSERT_TRUE(bitStream.Read(leading)); + ASSERT_TRUE(BitStreamUtils::ReadLengthPrefixed(bitStream, read)); + ASSERT_TRUE(BitStreamUtils::ReadLengthPrefixed(bitStream, empty)); + EXPECT_FALSE(leading); + EXPECT_EQ(read, value); + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(bitStream.GetNumberOfUnreadBits(), 0); +} + +TEST(BitStreamUtilsTests, ReadLengthPrefixedRejectsBadLengths) { + { + RakNet::BitStream bitStream; + bitStream.Write(-1); + std::u16string out; + EXPECT_FALSE(BitStreamUtils::ReadLengthPrefixed(bitStream, out)); + } + { + RakNet::BitStream bitStream; + bitStream.Write(11); + std::string out; + EXPECT_FALSE(BitStreamUtils::ReadLengthPrefixed(bitStream, out, 10)); + } + { + // Claims 4 characters but only has 1. + RakNet::BitStream bitStream; + bitStream.Write(4); + bitStream.Write(u'a'); + std::u16string out; + EXPECT_FALSE(BitStreamUtils::ReadLengthPrefixed(bitStream, out)); + } +} + +// WriteOptional must match the hand written "flag, then value if not default" pattern. +TEST(BitStreamUtilsTests, WriteOptionalMatchesHandWrittenPattern) { + for (const int32_t value : { 0, -1, 7 }) { + RakNet::BitStream expected; + expected.Write(value != -1); + if (value != -1) expected.Write(value); + + RakNet::BitStream actual; + BitStreamUtils::WriteOptional(actual, value, -1); + ASSERT_EQ(actual.GetNumberOfBitsUsed(), expected.GetNumberOfBitsUsed()); + ASSERT_EQ(Bytes(actual), Bytes(expected)); + + int32_t read = 12345; + ASSERT_TRUE(BitStreamUtils::ReadOptional(actual, read, -1)); + EXPECT_EQ(read, value); + EXPECT_EQ(actual.GetNumberOfUnreadBits(), 0); + } +} + +TEST(BitStreamUtilsTests, WriteOptionalGolden) { + RakNet::BitStream bitStream; + BitStreamUtils::WriteOptional(bitStream, 3.0f, 3.0f); // default: a single 0 bit + BitStreamUtils::WriteOptional(bitStream, 1.0f, 3.0f); // 1 bit, then 00 00 80 3f + // 0 1 00000000 00000000 10000000 00111111 (MSB first) padded + const std::vector golden = { 0x40, 0x00, 0x20, 0x0f, 0xc0 }; + ASSERT_EQ(bitStream.GetNumberOfBitsUsed(), 34); + ASSERT_EQ(Bytes(bitStream), golden); +} + +TEST(BitStreamUtilsTests, ReadOptionalFailsOnTruncatedValue) { + RakNet::BitStream bitStream; + bitStream.Write(true); + bitStream.Write(1); + uint32_t out{}; + EXPECT_FALSE(BitStreamUtils::ReadOptional(bitStream, out, 0)); +} diff --git a/tests/dGameTests/CMakeLists.txt b/tests/dGameTests/CMakeLists.txt index f4749ce8c..375187eaa 100644 --- a/tests/dGameTests/CMakeLists.txt +++ b/tests/dGameTests/CMakeLists.txt @@ -1,5 +1,7 @@ set(DGAMETEST_SOURCES "GameDependencies.cpp" + "LUBitStreamTests.cpp" + "MailIdPinTests.cpp" ) add_subdirectory(dComponentsTests) diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 480d1387f..bd16fb3ee 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -12,17 +12,42 @@ #include "GameDatabase/TestSQL/TestSQLDatabase.h" #include "Database.h" #include +#include class dZoneManager; class AssetManager; +// A packet captured by dServerMock::Send. The bytes are copied, so the capture stays valid +// after the sender's local BitStream goes out of scope. +struct CapturedPacket { + std::vector bytes; + uint32_t bits = 0; + SystemAddress sysAddr = UNASSIGNED_SYSTEM_ADDRESS; + bool broadcast = false; +}; + class dServerMock : public dServer { - RakNet::BitStream* sentBitStream = nullptr; + std::vector sentPackets; + RakNet::BitStream mostRecent; public: dServerMock() {}; ~dServerMock() {}; - RakNet::BitStream* GetMostRecentBitStream() { return sentBitStream; }; - void Send(RakNet::BitStream& bitStream, const SystemAddress& sysAddr, bool broadcast) override { sentBitStream = &bitStream; }; + + // Returns a copy of the most recently sent packet, with its read pointer at the start, or nullptr if nothing was sent. + RakNet::BitStream* GetMostRecentBitStream() { return sentPackets.empty() ? nullptr : &mostRecent; }; + const std::vector& GetSentPackets() const { return sentPackets; } + void ClearSentPackets() { sentPackets.clear(); mostRecent.Reset(); } + + void Send(RakNet::BitStream& bitStream, const SystemAddress& sysAddr, bool broadcast) override { + CapturedPacket& packet = sentPackets.emplace_back(); + packet.bits = bitStream.GetNumberOfBitsUsed(); + packet.bytes.assign(bitStream.GetData(), bitStream.GetData() + bitStream.GetNumberOfBytesUsed()); + packet.sysAddr = sysAddr; + packet.broadcast = broadcast; + + mostRecent.Reset(); + mostRecent.WriteBits(packet.bytes.data(), packet.bits, false); + }; void SetZoneId(unsigned int zoneId) { mZoneID = zoneId; } }; diff --git a/tests/dGameTests/LUBitStreamTests.cpp b/tests/dGameTests/LUBitStreamTests.cpp new file mode 100644 index 000000000..15afedc43 --- /dev/null +++ b/tests/dGameTests/LUBitStreamTests.cpp @@ -0,0 +1,56 @@ +#include + +#include "BitStreamUtils.h" +#include "GameDependencies.h" +#include "PacketTestUtils.h" + +#include + +namespace { + std::vector Bytes(RakNet::BitStream& bitStream) { + return { bitStream.GetData(), bitStream.GetData() + bitStream.GetNumberOfBytesUsed() }; + } +} + +namespace { + struct TestPacket : public LUBitStream { + uint32_t value = 0; + TestPacket() : LUBitStream(ServiceType::CHAT, 0x1234u) {} + void Serialize(RakNet::BitStream& bitStream) const override { bitStream.Write(value); } + bool Deserialize(RakNet::BitStream& bitStream) override { return bitStream.Read(value); } + }; +} + +TEST(LUBitStreamStructTests, WritePacketGoldenAndRoundTrip) { + TestPacket packet; + packet.value = 0xAABBCCDD; + RakNet::BitStream bitStream; + packet.WritePacket(bitStream); + // 0x53 | service u16 | packet id u32 | pad u8 | payload + const std::vector golden = { 0x53, 0x02, 0x00, 0x34, 0x12, 0x00, 0x00, 0x00, 0xDD, 0xCC, 0xBB, 0xAA }; + ASSERT_EQ(Bytes(bitStream), golden); + + TestPacket read; + ASSERT_TRUE(read.ReadHeader(bitStream)); + EXPECT_EQ(read.connectionType, ServiceType::CHAT); + EXPECT_EQ(read.internalPacketID, 0x1234u); + ASSERT_TRUE(read.Deserialize(bitStream)); + EXPECT_EQ(read.value, 0xAABBCCDD); +} + +class LUBitStreamTests : public GameDependenciesTest { +protected: + void SetUp() override { SetUpDependencies(); } + void TearDown() override { TearDownDependencies(); } +}; + +TEST_F(LUBitStreamTests, SendWritesWhatWritePacketWrites) { + TestPacket packet; + packet.value = 7; + RakNet::BitStream expected; + packet.WritePacket(expected); + const auto sent = PacketTestUtils::Capture([&] { packet.Send(UNASSIGNED_SYSTEM_ADDRESS); }); + ASSERT_EQ(sent.size(), 1); + EXPECT_TRUE(sent[0].broadcast); + EXPECT_PACKET_EQ(PacketTestUtils::FromBitStream(expected), PacketTestUtils::FromCapture(sent[0])); +} diff --git a/tests/dGameTests/MailIdPinTests.cpp b/tests/dGameTests/MailIdPinTests.cpp new file mode 100644 index 000000000..aa006d875 --- /dev/null +++ b/tests/dGameTests/MailIdPinTests.cpp @@ -0,0 +1,94 @@ +// GENERATED by a one-off script from the enum definitions at the time this file was added. +// Message IDs are sent on the wire and are append-only: never renumber, reuse or remove one. +// If one of these fails to compile, the change to the enum is wrong, not this file. +// New enumerators may be added freely; add a pin for them here too. + +#include "Mail.h" +#include +#include + +// Mail::eMessageID: 21 enumerators +static_assert(static_cast(Mail::eMessageID::SendRequest) == 0); +static_assert(static_cast(Mail::eMessageID::SendResponse) == 1); +static_assert(static_cast(Mail::eMessageID::NotificationResponse) == 2); +static_assert(static_cast(Mail::eMessageID::DataRequest) == 3); +static_assert(static_cast(Mail::eMessageID::DataResponse) == 4); +static_assert(static_cast(Mail::eMessageID::AttachmentCollectRequest) == 5); +static_assert(static_cast(Mail::eMessageID::AttachmentCollectResponse) == 6); +static_assert(static_cast(Mail::eMessageID::DeleteRequest) == 7); +static_assert(static_cast(Mail::eMessageID::DeleteResponse) == 8); +static_assert(static_cast(Mail::eMessageID::ReadRequest) == 9); +static_assert(static_cast(Mail::eMessageID::ReadResponse) == 10); +static_assert(static_cast(Mail::eMessageID::NotificationRequest) == 11); +static_assert(static_cast(Mail::eMessageID::AuctionCreate) == 12); +static_assert(static_cast(Mail::eMessageID::AuctionCreationResponse) == 13); +static_assert(static_cast(Mail::eMessageID::AuctionCancel) == 14); +static_assert(static_cast(Mail::eMessageID::AuctionCancelResponse) == 15); +static_assert(static_cast(Mail::eMessageID::AuctionList) == 16); +static_assert(static_cast(Mail::eMessageID::AuctionListResponse) == 17); +static_assert(static_cast(Mail::eMessageID::AuctionBid) == 18); +static_assert(static_cast(Mail::eMessageID::AuctionBidResponse) == 19); +static_assert(static_cast(Mail::eMessageID::UnknownError) == 20); + +// Mail::eSendResponse: 15 enumerators +static_assert(static_cast(Mail::eSendResponse::Success) == 0); +static_assert(static_cast(Mail::eSendResponse::NotEnoughCoins) == 1); +static_assert(static_cast(Mail::eSendResponse::AttachmentNotFound) == 2); +static_assert(static_cast(Mail::eSendResponse::ItemCannotBeMailed) == 3); +static_assert(static_cast(Mail::eSendResponse::CannotMailSelf) == 4); +static_assert(static_cast(Mail::eSendResponse::RecipientNotFound) == 5); +static_assert(static_cast(Mail::eSendResponse::RecipientDifferentFaction) == 6); +static_assert(static_cast(Mail::eSendResponse::UnHandled7) == 7); +static_assert(static_cast(Mail::eSendResponse::ModerationFailure) == 8); +static_assert(static_cast(Mail::eSendResponse::SenderAccountIsMuted) == 9); +static_assert(static_cast(Mail::eSendResponse::UnHandled10) == 10); +static_assert(static_cast(Mail::eSendResponse::RecipientIsIgnored) == 11); +static_assert(static_cast(Mail::eSendResponse::UnHandled12) == 12); +static_assert(static_cast(Mail::eSendResponse::RecipientIsFTP) == 13); +static_assert(static_cast(Mail::eSendResponse::UnknownError) == 14); + +// Mail::eDeleteResponse: 5 enumerators +static_assert(static_cast(Mail::eDeleteResponse::Success) == 0); +static_assert(static_cast(Mail::eDeleteResponse::HasAttachments) == 1); +static_assert(static_cast(Mail::eDeleteResponse::NotFound) == 2); +static_assert(static_cast(Mail::eDeleteResponse::Throttled) == 3); +static_assert(static_cast(Mail::eDeleteResponse::UnknownError) == 4); + +// Mail::eAttachmentCollectResponse: 6 enumerators +static_assert(static_cast(Mail::eAttachmentCollectResponse::Success) == 0); +static_assert(static_cast(Mail::eAttachmentCollectResponse::AttachmentNotFound) == 1); +static_assert(static_cast(Mail::eAttachmentCollectResponse::NoSpaceInInventory) == 2); +static_assert(static_cast(Mail::eAttachmentCollectResponse::MailNotFound) == 3); +static_assert(static_cast(Mail::eAttachmentCollectResponse::Throttled) == 4); +static_assert(static_cast(Mail::eAttachmentCollectResponse::UnknownError) == 5); + +// Mail::eNotificationResponse: 9 enumerators +static_assert(static_cast(Mail::eNotificationResponse::NewMail) == 0); +static_assert(static_cast(Mail::eNotificationResponse::UnHandled) == 1); +static_assert(static_cast(Mail::eNotificationResponse::AuctionWon) == 2); +static_assert(static_cast(Mail::eNotificationResponse::AuctionSold) == 3); +static_assert(static_cast(Mail::eNotificationResponse::AuctionOutbided) == 4); +static_assert(static_cast(Mail::eNotificationResponse::AuctionExpired) == 5); +static_assert(static_cast(Mail::eNotificationResponse::AuctionCancelled) == 6); +static_assert(static_cast(Mail::eNotificationResponse::AuctionUpdated) == 7); +static_assert(static_cast(Mail::eNotificationResponse::UnknownError) == 8); + +// Mail::eReadResponse: 2 enumerators +static_assert(static_cast(Mail::eReadResponse::Success) == 0); +static_assert(static_cast(Mail::eReadResponse::UnknownError) == 1); + +// Mail::eAuctionCreateResponse: 5 enumerators +static_assert(static_cast(Mail::eAuctionCreateResponse::Success) == 0); +static_assert(static_cast(Mail::eAuctionCreateResponse::NotEnoughMoney) == 1); +static_assert(static_cast(Mail::eAuctionCreateResponse::ItemNotFound) == 2); +static_assert(static_cast(Mail::eAuctionCreateResponse::ItemNotSellable) == 3); +static_assert(static_cast(Mail::eAuctionCreateResponse::UnknownError) == 4); + +// Mail::eAuctionCancelResponse: 5 enumerators +static_assert(static_cast(Mail::eAuctionCancelResponse::NotFound) == 0); +static_assert(static_cast(Mail::eAuctionCancelResponse::NotYours) == 1); +static_assert(static_cast(Mail::eAuctionCancelResponse::HasBid) == 2); +static_assert(static_cast(Mail::eAuctionCancelResponse::NoLongerExists) == 3); +static_assert(static_cast(Mail::eAuctionCancelResponse::UnknownError) == 4); + +TEST(MailIdPinTests, MailEnumValuesArePinned) { SUCCEED(); } diff --git a/tests/dGameTests/PacketTestUtils.h b/tests/dGameTests/PacketTestUtils.h new file mode 100644 index 000000000..b631b71a6 --- /dev/null +++ b/tests/dGameTests/PacketTestUtils.h @@ -0,0 +1,76 @@ +#ifndef PACKETTESTUTILS_H +#define PACKETTESTUTILS_H + +// Helpers for byte-for-byte packet comparisons used while migrating packets / game messages +// to the struct based architecture (see docs/PacketArchitecture.md). + +#include "BitStream.h" +#include "GameDependencies.h" + +#include +#include +#include +#include + +#include + +namespace PacketTestUtils { + struct PacketBytes { + std::vector bytes; + uint32_t bits = 0; + }; + + inline PacketBytes FromBitStream(const RakNet::BitStream& bitStream) { + auto& nonConst = const_cast(bitStream); // GetData is not const in RakNet + return { { nonConst.GetData(), nonConst.GetData() + nonConst.GetNumberOfBytesUsed() }, static_cast(nonConst.GetNumberOfBitsUsed()) }; + } + + inline PacketBytes FromCapture(const CapturedPacket& packet) { + return { packet.bytes, packet.bits }; + } + + inline std::string ToHex(const PacketBytes& packet) { + std::string out; + char buf[4]; + for (size_t i = 0; i < packet.bytes.size(); i++) { + std::snprintf(buf, sizeof(buf), "%02x", packet.bytes[i]); + if (i != 0) out += ' '; + out += buf; + } + return out + " (" + std::to_string(packet.bits) + " bits)"; + } + + inline PacketBytes FromHex(const std::string& hex, uint32_t bits = 0) { + PacketBytes packet; + for (size_t i = 0; i + 1 < hex.size();) { + if (hex[i] == ' ') { i++; continue; } + packet.bytes.push_back(static_cast(std::stoul(hex.substr(i, 2), nullptr, 16))); + i += 2; + } + packet.bits = bits == 0 ? static_cast(packet.bytes.size() * 8) : bits; + return packet; + } + + // Compares the exact number of bits and every byte, printing both packets as hex on failure. + inline ::testing::AssertionResult PacketsEqual(const PacketBytes& expected, const PacketBytes& actual) { + if (expected.bits == actual.bits && expected.bytes == actual.bytes) return ::testing::AssertionSuccess(); + return ::testing::AssertionFailure() + << "\n expected: " << ToHex(expected) + << "\n actual: " << ToHex(actual); + } + + // Runs sendFunction against the mock server and returns every packet it sent. + inline std::vector Capture(const std::function& sendFunction) { + auto* server = static_cast(Game::server); + server->ClearSentPackets(); + sendFunction(); + auto packets = server->GetSentPackets(); + server->ClearSentPackets(); + return packets; + } +} + +#define EXPECT_PACKET_EQ(expected, actual) EXPECT_TRUE(PacketTestUtils::PacketsEqual(expected, actual)) +#define ASSERT_PACKET_EQ(expected, actual) ASSERT_TRUE(PacketTestUtils::PacketsEqual(expected, actual)) + +#endif // PACKETTESTUTILS_H diff --git a/tests/dGameTests/dGameMessagesTests/CMakeLists.txt b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt index e1c4884cc..253539ab9 100644 --- a/tests/dGameTests/dGameMessagesTests/CMakeLists.txt +++ b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt @@ -1,5 +1,6 @@ SET(DGAMEMESSAGES_TESTS "GameMessageTests.cpp" + "GameMsgSplitTests.cpp" "LegacyGameMessageTests.cpp") # Get the folder name and prepend it to the files above diff --git a/tests/dGameTests/dGameMessagesTests/GameMsgSplitTests.cpp b/tests/dGameTests/dGameMessagesTests/GameMsgSplitTests.cpp new file mode 100644 index 000000000..e4fc00a39 --- /dev/null +++ b/tests/dGameTests/dGameMessagesTests/GameMsgSplitTests.cpp @@ -0,0 +1,91 @@ +#include "GameMessages.h" +#include "GameDependencies.h" +#include "PacketTestUtils.h" +#include "Entity.h" +#include "EntityManager.h" + +#include + +#include + +// Wire messages (NetGameMsg) and server-internal events (GameMsg) are separate types, so a message can only be +// sent where it belongs. These checks fail to compile if the split is undone. +namespace { + template + concept CanSendLocally = requires(T msg) { msg.Send(); msg.Send(LWOOBJID{}); }; + + template + concept CanSendToClient = requires(const T msg) { msg.Send(UNASSIGNED_SYSTEM_ADDRESS); }; + + template + concept CanHandleLocally = requires(Entity & entity, T msg) { entity.HandleMsg(msg); }; + + static_assert(!std::is_base_of_v); + static_assert(!std::is_base_of_v); + + // A wire message can go to a client, never to local handlers. + static_assert(CanSendToClient); + static_assert(!CanSendLocally); + static_assert(!CanHandleLocally); + + // A local event can go to local handlers, never to a client. + static_assert(CanSendLocally); + static_assert(!CanSendToClient); + static_assert(CanHandleLocally); + + // A wire message wrapped for local delivery is a local event. + static_assert(CanSendLocally); + static_assert(!CanSendToClient); +} + +class GameMsgSplitTests : public GameDependenciesTest { +protected: + void SetUp() override { SetUpDependencies(); } + void TearDown() override { TearDownDependencies(); } +}; + +TEST_F(GameMsgSplitTests, EventCarriesACopyWithTheTarget) { + auto entity = std::make_unique(15, info); + + LWOOBJID seenTarget = LWOOBJID_EMPTY; + LOT seenItem = LOT_NULL; + entity->RegisterMsg(MessageType::Game::DROP_CLIENT_LOOT, [&](GameMessages::GameMsg& msg) { + auto& event = static_cast(msg); + seenTarget = event.target; + seenItem = event.msg.item; + event.msg.item = 1; // handlers only modify the copy + return true; + }); + + GameMessages::DropClientLoot loot; + loot.target = 15; + loot.item = 1234; + + GameMessages::DropClientLootEvent event(loot); + EXPECT_EQ(event.msgId, MessageType::Game::DROP_CLIENT_LOOT); + const auto sent = PacketTestUtils::Capture([&] { EXPECT_TRUE(entity->HandleMsg(event)); }); + EXPECT_TRUE(sent.empty()); // nothing went on the wire + EXPECT_EQ(seenTarget, 15); + EXPECT_EQ(seenItem, 1234); + EXPECT_EQ(loot.item, 1234); +} + +TEST_F(GameMsgSplitTests, DeliverLocallyNeverSendsToAClient) { + GameMessages::DropClientLoot loot; + loot.target = 0x7777; // no such entity + const auto sent = PacketTestUtils::Capture([&] { EXPECT_FALSE(GameMessages::DeliverLocally(loot)); }); + EXPECT_TRUE(sent.empty()); +} + +TEST_F(GameMsgSplitTests, SendToClientNeverBroadcasts) { + GameMessages::DropClientLoot loot; + for (const auto& address : { SystemAddress(), UNASSIGNED_SYSTEM_ADDRESS }) { + const auto sent = PacketTestUtils::Capture([&] { loot.SendToClient(address); }); + ASSERT_EQ(sent.size(), 1); + EXPECT_FALSE(sent[0].broadcast); + EXPECT_EQ(sent[0].sysAddr, address); + } + const auto broadcast = PacketTestUtils::Capture([&] { loot.Send(UNASSIGNED_SYSTEM_ADDRESS); }); + ASSERT_EQ(broadcast.size(), 1); + EXPECT_TRUE(broadcast[0].broadcast); +}