mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-01-21 04:07:01 +00:00
add msg handling (#1737)
This commit is contained in:
parent
1b3cdc6d9c
commit
e4c2eecbc7
@ -40,6 +40,7 @@ public:
|
|||||||
// AMFValue template class instantiations
|
// AMFValue template class instantiations
|
||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
class AMFValue : public AMFBaseValue {
|
class AMFValue : public AMFBaseValue {
|
||||||
|
static_assert(!std::is_same_v<ValueType, std::string_view>, "AMFValue cannot be instantiated with std::string_view");
|
||||||
public:
|
public:
|
||||||
AMFValue() = default;
|
AMFValue() = default;
|
||||||
AMFValue(const ValueType value) : m_Data{ value } {}
|
AMFValue(const ValueType value) : m_Data{ value } {}
|
||||||
@ -52,6 +53,15 @@ public:
|
|||||||
|
|
||||||
void SetValue(const ValueType value) { m_Data = value; }
|
void SetValue(const ValueType value) { m_Data = value; }
|
||||||
|
|
||||||
|
AMFValue<ValueType>& operator=(const AMFValue<ValueType>& other) {
|
||||||
|
return operator=(other.m_Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
AMFValue<ValueType>& operator=(const ValueType& other) {
|
||||||
|
m_Data = other;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValueType m_Data;
|
ValueType m_Data;
|
||||||
};
|
};
|
||||||
@ -211,13 +221,17 @@ public:
|
|||||||
* @param key The key to associate with the value
|
* @param key The key to associate with the value
|
||||||
* @param value The value to insert
|
* @param value The value to insert
|
||||||
*/
|
*/
|
||||||
void Insert(const std::string_view key, std::unique_ptr<AMFBaseValue> value) {
|
template<typename AmfType>
|
||||||
|
AmfType& Insert(const std::string_view key, std::unique_ptr<AmfType> value) {
|
||||||
const auto element = m_Associative.find(key);
|
const auto element = m_Associative.find(key);
|
||||||
|
auto& toReturn = *value;
|
||||||
if (element != m_Associative.cend() && element->second) {
|
if (element != m_Associative.cend() && element->second) {
|
||||||
element->second = std::move(value);
|
element->second = std::move(value);
|
||||||
} else {
|
} else {
|
||||||
m_Associative.emplace(key, std::move(value));
|
m_Associative.emplace(key, std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,11 +243,15 @@ public:
|
|||||||
* @param key The key to associate with the value
|
* @param key The key to associate with the value
|
||||||
* @param value The value to insert
|
* @param value The value to insert
|
||||||
*/
|
*/
|
||||||
void Insert(const size_t index, std::unique_ptr<AMFBaseValue> value) {
|
template<typename AmfType>
|
||||||
|
AmfType& Insert(const size_t index, std::unique_ptr<AmfType> value) {
|
||||||
|
auto& toReturn = *value;
|
||||||
if (index >= m_Dense.size()) {
|
if (index >= m_Dense.size()) {
|
||||||
m_Dense.resize(index + 1);
|
m_Dense.resize(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Dense.at(index) = std::move(value);
|
m_Dense.at(index) = std::move(value);
|
||||||
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -349,6 +367,13 @@ public:
|
|||||||
m_Dense.clear();
|
m_Dense.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename AmfType = AMFArrayValue>
|
||||||
|
AmfType& PushDebug(const std::string_view name) {
|
||||||
|
auto* value = PushArray();
|
||||||
|
value->Insert("name", name.data());
|
||||||
|
return value->Insert<AmfType>("value", std::make_unique<AmfType>());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* The associative portion. These values are key'd with strings to an AMFValue.
|
* The associative portion. These values are key'd with strings to an AMFValue.
|
||||||
|
@ -2216,3 +2216,17 @@ int32_t Entity::GetCollisionGroup() const {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Entity::HandleMsg(GameMessages::GameMsg& msg) const {
|
||||||
|
bool handled = false;
|
||||||
|
const auto [beg, end] = m_MsgHandlers.equal_range(msg.msgId);
|
||||||
|
for (auto it = beg; it != end; ++it) {
|
||||||
|
if (it->second) handled |= it->second(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::RegisterMsg(const MessageType::Game msgId, std::function<bool(GameMessages::GameMsg&)> handler) {
|
||||||
|
m_MsgHandlers.emplace(msgId, handler);
|
||||||
|
}
|
||||||
|
@ -14,12 +14,17 @@
|
|||||||
#include "Observable.h"
|
#include "Observable.h"
|
||||||
|
|
||||||
namespace GameMessages {
|
namespace GameMessages {
|
||||||
|
struct GameMsg;
|
||||||
struct ActivityNotify;
|
struct ActivityNotify;
|
||||||
struct ShootingGalleryFire;
|
struct ShootingGalleryFire;
|
||||||
struct ChildLoaded;
|
struct ChildLoaded;
|
||||||
struct PlayerResurrectionFinished;
|
struct PlayerResurrectionFinished;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace MessageType {
|
||||||
|
enum class Game : uint16_t;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Loot {
|
namespace Loot {
|
||||||
class Info;
|
class Info;
|
||||||
};
|
};
|
||||||
@ -316,6 +321,10 @@ public:
|
|||||||
// Scale will only be communicated to the client when the construction packet is sent
|
// Scale will only be communicated to the client when the construction packet is sent
|
||||||
void SetScale(const float scale) { m_Scale = scale; };
|
void SetScale(const float scale) { m_Scale = scale; };
|
||||||
|
|
||||||
|
void RegisterMsg(const MessageType::Game msgId, std::function<bool(GameMessages::GameMsg&)> handler);
|
||||||
|
|
||||||
|
bool HandleMsg(GameMessages::GameMsg& msg) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The observable for player entity position updates.
|
* @brief The observable for player entity position updates.
|
||||||
*/
|
*/
|
||||||
@ -377,6 +386,8 @@ protected:
|
|||||||
|
|
||||||
// objectID of receiver and map of notification name to script
|
// objectID of receiver and map of notification name to script
|
||||||
std::map<LWOOBJID, std::map<std::string, CppScripts::Script*>> m_Subscriptions;
|
std::map<LWOOBJID, std::map<std::string, CppScripts::Script*>> m_Subscriptions;
|
||||||
|
|
||||||
|
std::multimap<MessageType::Game, std::function<bool(GameMessages::GameMsg&)>> m_MsgHandlers;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "Mail.h"
|
#include "Mail.h"
|
||||||
#include "ZoneInstanceManager.h"
|
#include "ZoneInstanceManager.h"
|
||||||
#include "WorldPackets.h"
|
#include "WorldPackets.h"
|
||||||
|
#include "MessageType/Game.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
CharacterComponent::CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress) : Component(parent) {
|
CharacterComponent::CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress) : Component(parent) {
|
||||||
@ -47,6 +48,45 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character, con
|
|||||||
m_CountryCode = 0;
|
m_CountryCode = 0;
|
||||||
m_LastUpdateTimestamp = std::time(nullptr);
|
m_LastUpdateTimestamp = std::time(nullptr);
|
||||||
m_SystemAddress = systemAddress;
|
m_SystemAddress = systemAddress;
|
||||||
|
|
||||||
|
RegisterMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, this, &CharacterComponent::OnRequestServerObjectInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CharacterComponent::OnRequestServerObjectInfo(GameMessages::GameMsg& msg) {
|
||||||
|
auto& request = static_cast<GameMessages::RequestServerObjectInfo&>(msg);
|
||||||
|
AMFArrayValue response;
|
||||||
|
|
||||||
|
response.Insert("visible", true);
|
||||||
|
response.Insert("objectID", std::to_string(request.targetForReport));
|
||||||
|
response.Insert("serverInfo", true);
|
||||||
|
|
||||||
|
auto& data = *response.InsertArray("data");
|
||||||
|
auto& cmptType = data.PushDebug("Character");
|
||||||
|
|
||||||
|
cmptType.PushDebug<AMFIntValue>("Component ID") = GeneralUtils::ToUnderlying(ComponentType);
|
||||||
|
cmptType.PushDebug<AMFIntValue>("Character's account ID") = m_Character->GetParentUser()->GetAccountID();
|
||||||
|
cmptType.PushDebug<AMFBoolValue>("Last log out time") = m_Character->GetLastLogin();
|
||||||
|
cmptType.PushDebug<AMFDoubleValue>("Seconds played this session") = 0;
|
||||||
|
cmptType.PushDebug<AMFBoolValue>("Editor enabled") = false;
|
||||||
|
cmptType.PushDebug<AMFDoubleValue>("Total number of seconds played") = m_TotalTimePlayed;
|
||||||
|
cmptType.PushDebug<AMFStringValue>("Total currency") = std::to_string(m_Character->GetCoins());
|
||||||
|
cmptType.PushDebug<AMFStringValue>("Currency able to be picked up") = std::to_string(m_DroppedCoins);
|
||||||
|
cmptType.PushDebug<AMFStringValue>("Tooltip flags value") = "0";
|
||||||
|
// visited locations
|
||||||
|
cmptType.PushDebug<AMFBoolValue>("is a GM") = m_GMLevel > eGameMasterLevel::CIVILIAN;
|
||||||
|
cmptType.PushDebug<AMFBoolValue>("Has PVP flag turned on") = m_PvpEnabled;
|
||||||
|
cmptType.PushDebug<AMFIntValue>("GM Level") = GeneralUtils::ToUnderlying(m_GMLevel);
|
||||||
|
cmptType.PushDebug<AMFIntValue>("Editor level") = GeneralUtils::ToUnderlying(m_EditorLevel);
|
||||||
|
cmptType.PushDebug<AMFStringValue>("Guild ID") = "0";
|
||||||
|
cmptType.PushDebug<AMFStringValue>("Guild Name") = "";
|
||||||
|
cmptType.PushDebug<AMFDoubleValue>("Reputation") = m_Reputation;
|
||||||
|
cmptType.PushDebug<AMFIntValue>("Current Activity Type") = GeneralUtils::ToUnderlying(m_CurrentActivity);
|
||||||
|
cmptType.PushDebug<AMFDoubleValue>("Property Clone ID") = m_Character->GetPropertyCloneID();
|
||||||
|
|
||||||
|
GameMessages::SendUIMessageServerToSingleClient("ToggleObjectDebugger", response, m_Parent->GetSystemAddress());
|
||||||
|
|
||||||
|
LOG("Handled!");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CharacterComponent::LandingAnimDisabled(int zoneID) {
|
bool CharacterComponent::LandingAnimDisabled(int zoneID) {
|
||||||
@ -81,6 +121,8 @@ CharacterComponent::~CharacterComponent() {
|
|||||||
void CharacterComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
void CharacterComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||||
|
|
||||||
if (bIsInitialUpdate) {
|
if (bIsInitialUpdate) {
|
||||||
|
if (!m_Character || !m_Character->GetParentUser()) return;
|
||||||
|
|
||||||
outBitStream.Write(m_ClaimCodes[0] != 0);
|
outBitStream.Write(m_ClaimCodes[0] != 0);
|
||||||
if (m_ClaimCodes[0] != 0) outBitStream.Write(m_ClaimCodes[0]);
|
if (m_ClaimCodes[0] != 0) outBitStream.Write(m_ClaimCodes[0]);
|
||||||
outBitStream.Write(m_ClaimCodes[1] != 0);
|
outBitStream.Write(m_ClaimCodes[1] != 0);
|
||||||
@ -100,7 +142,7 @@ void CharacterComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInit
|
|||||||
outBitStream.Write(m_Character->GetEyebrows());
|
outBitStream.Write(m_Character->GetEyebrows());
|
||||||
outBitStream.Write(m_Character->GetEyes());
|
outBitStream.Write(m_Character->GetEyes());
|
||||||
outBitStream.Write(m_Character->GetMouth());
|
outBitStream.Write(m_Character->GetMouth());
|
||||||
outBitStream.Write<uint64_t>(0); //AccountID, trying out if 0 works.
|
outBitStream.Write<uint64_t>(m_Character->GetParentUser()->GetAccountID());
|
||||||
outBitStream.Write(m_Character->GetLastLogin()); //Last login
|
outBitStream.Write(m_Character->GetLastLogin()); //Last login
|
||||||
outBitStream.Write<uint64_t>(0); //"prop mod last display time"
|
outBitStream.Write<uint64_t>(0); //"prop mod last display time"
|
||||||
outBitStream.Write<uint64_t>(m_Uscore); //u-score
|
outBitStream.Write<uint64_t>(m_Uscore); //u-score
|
||||||
|
@ -323,6 +323,8 @@ public:
|
|||||||
Character* m_Character;
|
Character* m_Character;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool OnRequestServerObjectInfo(GameMessages::GameMsg& msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The map of active venture vision effects
|
* The map of active venture vision effects
|
||||||
*/
|
*/
|
||||||
|
@ -8,6 +8,10 @@ namespace RakNet {
|
|||||||
class BitStream;
|
class BitStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace GameMessages {
|
||||||
|
struct GameMsg;
|
||||||
|
}
|
||||||
|
|
||||||
class Entity;
|
class Entity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,6 +56,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
|
||||||
|
m_Parent->RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The entity that owns this component
|
* The entity that owns this component
|
||||||
*/
|
*/
|
||||||
|
@ -37,8 +37,19 @@
|
|||||||
#include "ePlayerFlag.h"
|
#include "ePlayerFlag.h"
|
||||||
#include "dConfig.h"
|
#include "dConfig.h"
|
||||||
#include "GhostComponent.h"
|
#include "GhostComponent.h"
|
||||||
|
#include "eGameMasterLevel.h"
|
||||||
#include "StringifiedEnum.h"
|
#include "StringifiedEnum.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using enum MessageType::Game;
|
||||||
|
using namespace GameMessages;
|
||||||
|
using MessageCreator = std::function<std::unique_ptr<GameMessages::GameMsg>()>;
|
||||||
|
std::map<MessageType::Game, MessageCreator> g_MessageHandlers = {
|
||||||
|
{ REQUEST_SERVER_OBJECT_INFO, []() { return std::make_unique<RequestServerObjectInfo>(); } },
|
||||||
|
{ SHOOTING_GALLERY_FIRE, []() { return std::make_unique<ShootingGalleryFire>(); } },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const SystemAddress& sysAddr, LWOOBJID objectID, MessageType::Game messageID) {
|
void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const SystemAddress& sysAddr, LWOOBJID objectID, MessageType::Game messageID) {
|
||||||
|
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
@ -55,6 +66,24 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
|
|||||||
|
|
||||||
if (messageID != MessageType::Game::READY_FOR_UPDATES) LOG_DEBUG("Received GM with ID and name: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
if (messageID != MessageType::Game::READY_FOR_UPDATES) LOG_DEBUG("Received GM with ID and name: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
||||||
|
|
||||||
|
auto handler = g_MessageHandlers.find(messageID);
|
||||||
|
if (handler != g_MessageHandlers.end()) {
|
||||||
|
auto msg = handler->second();
|
||||||
|
|
||||||
|
// Verify that the system address user is able to use this message.
|
||||||
|
if (msg->requiredGmLevel > eGameMasterLevel::CIVILIAN) {
|
||||||
|
auto* usingEntity = Game::entityManager->GetEntity(usr->GetLoggedInChar());
|
||||||
|
if (!usingEntity || usingEntity->GetGMLevel() < msg->requiredGmLevel) {
|
||||||
|
LOG("User %s (%llu) does not have the required GM level to execute this command.", usingEntity->GetCharacter()->GetName().c_str(), usingEntity->GetObjectID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->Deserialize(inStream);
|
||||||
|
msg->Handle(*entity, sysAddr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (messageID) {
|
switch (messageID) {
|
||||||
|
|
||||||
case MessageType::Game::UN_USE_BBB_MODEL: {
|
case MessageType::Game::UN_USE_BBB_MODEL: {
|
||||||
@ -104,13 +133,13 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently not actually used for our implementation, however its used right now to get around invisible inventory items in the client.
|
// Currently not actually used for our implementation, however its used right now to get around invisible inventory items in the client.
|
||||||
case MessageType::Game::SELECT_SKILL: {
|
case MessageType::Game::SELECT_SKILL: {
|
||||||
auto var = entity->GetVar<bool>(u"dlu_first_time_load");
|
auto var = entity->GetVar<bool>(u"dlu_first_time_load");
|
||||||
if (var) {
|
if (var) {
|
||||||
entity->SetVar<bool>(u"dlu_first_time_load", false);
|
entity->SetVar<bool>(u"dlu_first_time_load", false);
|
||||||
InventoryComponent* inventoryComponent = entity->GetComponent<InventoryComponent>();
|
InventoryComponent* inventoryComponent = entity->GetComponent<InventoryComponent>();
|
||||||
|
|
||||||
if (inventoryComponent) inventoryComponent->FixInvisibleItems();
|
if (inventoryComponent) inventoryComponent->FixInvisibleItems();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -704,12 +733,6 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
|
|||||||
case MessageType::Game::UPDATE_INVENTORY_GROUP_CONTENTS:
|
case MessageType::Game::UPDATE_INVENTORY_GROUP_CONTENTS:
|
||||||
GameMessages::HandleUpdateInventoryGroupContents(inStream, entity, sysAddr);
|
GameMessages::HandleUpdateInventoryGroupContents(inStream, entity, sysAddr);
|
||||||
break;
|
break;
|
||||||
case MessageType::Game::SHOOTING_GALLERY_FIRE: {
|
|
||||||
GameMessages::ShootingGalleryFire fire{};
|
|
||||||
fire.Deserialize(inStream);
|
|
||||||
fire.Handle(*entity, sysAddr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_DEBUG("Received Unknown GM with ID: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
LOG_DEBUG("Received Unknown GM with ID: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
||||||
|
@ -6431,4 +6431,16 @@ namespace GameMessages {
|
|||||||
void ShootingGalleryFire::Handle(Entity& entity, const SystemAddress& sysAddr) {
|
void ShootingGalleryFire::Handle(Entity& entity, const SystemAddress& sysAddr) {
|
||||||
entity.OnShootingGalleryFire(*this);
|
entity.OnShootingGalleryFire(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RequestServerObjectInfo::Deserialize(RakNet::BitStream& bitStream) {
|
||||||
|
if (!bitStream.Read(bVerbose)) return false;
|
||||||
|
if (!bitStream.Read(clientId)) return false;
|
||||||
|
if (!bitStream.Read(targetForReport)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestServerObjectInfo::Handle(Entity& entity, const SystemAddress& sysAddr) {
|
||||||
|
auto* handlingEntity = Game::entityManager->GetEntity(targetForReport);
|
||||||
|
if (handlingEntity) handlingEntity->HandleMsg(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "eLootSourceType.h"
|
#include "eLootSourceType.h"
|
||||||
#include "Brick.h"
|
#include "Brick.h"
|
||||||
#include "MessageType/Game.h"
|
#include "MessageType/Game.h"
|
||||||
|
#include "eGameMasterLevel.h"
|
||||||
|
|
||||||
class AMFBaseValue;
|
class AMFBaseValue;
|
||||||
class Entity;
|
class Entity;
|
||||||
@ -50,7 +51,8 @@ enum class eCameraTargetCyclingMode : int32_t {
|
|||||||
|
|
||||||
namespace GameMessages {
|
namespace GameMessages {
|
||||||
struct GameMsg {
|
struct GameMsg {
|
||||||
GameMsg(MessageType::Game gmId) : msgId{ gmId } {}
|
GameMsg(MessageType::Game gmId, eGameMasterLevel lvl) : msgId{ gmId }, requiredGmLevel{ lvl } {}
|
||||||
|
GameMsg(MessageType::Game gmId) : GameMsg(gmId, eGameMasterLevel::CIVILIAN) {}
|
||||||
virtual ~GameMsg() = default;
|
virtual ~GameMsg() = default;
|
||||||
void Send(const SystemAddress& sysAddr) const;
|
void Send(const SystemAddress& sysAddr) const;
|
||||||
virtual void Serialize(RakNet::BitStream& bitStream) const {}
|
virtual void Serialize(RakNet::BitStream& bitStream) const {}
|
||||||
@ -58,6 +60,7 @@ namespace GameMessages {
|
|||||||
virtual void Handle(Entity& entity, const SystemAddress& sysAddr) {};
|
virtual void Handle(Entity& entity, const SystemAddress& sysAddr) {};
|
||||||
MessageType::Game msgId;
|
MessageType::Game msgId;
|
||||||
LWOOBJID target{ LWOOBJID_EMPTY };
|
LWOOBJID target{ LWOOBJID_EMPTY };
|
||||||
|
eGameMasterLevel requiredGmLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PropertyDataMessage;
|
class PropertyDataMessage;
|
||||||
@ -769,6 +772,16 @@ namespace GameMessages {
|
|||||||
struct PlayerResurrectionFinished : public GameMsg {
|
struct PlayerResurrectionFinished : public GameMsg {
|
||||||
PlayerResurrectionFinished() : GameMsg(MessageType::Game::PLAYER_RESURRECTION_FINISHED) {}
|
PlayerResurrectionFinished() : GameMsg(MessageType::Game::PLAYER_RESURRECTION_FINISHED) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RequestServerObjectInfo : public GameMsg {
|
||||||
|
bool bVerbose{};
|
||||||
|
LWOOBJID clientId{};
|
||||||
|
LWOOBJID targetForReport{};
|
||||||
|
|
||||||
|
RequestServerObjectInfo() : GameMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, eGameMasterLevel::DEVELOPER) {}
|
||||||
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||||
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GAMEMESSAGES_H
|
#endif // GAMEMESSAGES_H
|
||||||
|
@ -68,7 +68,7 @@ TEST(dCommonTests, AMF3InsertionAssociativeTest) {
|
|||||||
array.Insert<int32_t>("Integer", 42U);
|
array.Insert<int32_t>("Integer", 42U);
|
||||||
array.Insert("Double", 42.0);
|
array.Insert("Double", 42.0);
|
||||||
array.InsertArray("Array");
|
array.InsertArray("Array");
|
||||||
array.Insert<std::vector<uint32_t>>("Undefined", {});
|
array.Insert<std::vector<uint32_t>>("Undefined", std::vector<uint32_t>{});
|
||||||
array.Insert("Null", nullptr);
|
array.Insert("Null", nullptr);
|
||||||
|
|
||||||
ASSERT_EQ(array.Get<const char*>("CString")->GetValueType(), eAmf::String);
|
ASSERT_EQ(array.Get<const char*>("CString")->GetValueType(), eAmf::String);
|
||||||
|
Loading…
Reference in New Issue
Block a user