Merge remote-tracking branch 'upstream/main' into more-cdclient-cleanup

This commit is contained in:
David Markowitz 2023-03-26 03:00:21 -07:00
commit 1e4e1b914c
52 changed files with 721 additions and 309 deletions

View File

@ -12,6 +12,7 @@
#include "dConfig.h" #include "dConfig.h"
#include "Database.h" #include "Database.h"
#include "Game.h" #include "Game.h"
#include "eGameMasterLevel.h"
using namespace dChatFilterDCF; using namespace dChatFilterDCF;
@ -108,8 +109,8 @@ void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool whiteLis
} }
} }
std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList) { std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList) {
if (gmLevel > GAME_MASTER_LEVEL_FORUM_MODERATOR) return { }; //If anything but a forum mod, return true. if (gmLevel > eGameMasterLevel::FORUM_MODERATOR) return { }; //If anything but a forum mod, return true.
if (message.empty()) return { }; if (message.empty()) return { };
if (!whiteList && m_DeniedWords.empty()) return { { 0, message.length() } }; if (!whiteList && m_DeniedWords.empty()) return { { 0, message.length() } };

View File

@ -4,6 +4,7 @@
#include "dCommonVars.h" #include "dCommonVars.h"
enum class eGameMasterLevel : uint8_t;
namespace dChatFilterDCF { namespace dChatFilterDCF {
static const uint32_t header = ('D' + ('C' << 8) + ('F' << 16) + ('B' << 24)); static const uint32_t header = ('D' + ('C' << 8) + ('F' << 16) + ('B' << 24));
static const uint32_t formatVersion = 2; static const uint32_t formatVersion = 2;
@ -23,7 +24,7 @@ public:
void ReadWordlistPlaintext(const std::string& filepath, bool whiteList); void ReadWordlistPlaintext(const std::string& filepath, bool whiteList);
bool ReadWordlistDCF(const std::string& filepath, bool whiteList); bool ReadWordlistDCF(const std::string& filepath, bool whiteList);
void ExportWordlistToDCF(const std::string& filepath, bool whiteList); void ExportWordlistToDCF(const std::string& filepath, bool whiteList);
std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList = true); std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList = true);
private: private:
bool m_DontGenerateDCF; bool m_DontGenerateDCF;

View File

@ -319,3 +319,7 @@ std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::stri
return sortedFiles; return sortedFiles;
} }
bool GeneralUtils::TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst) {
return TryParse<float>(x.c_str(), dst.x) && TryParse<float>(y.c_str(), dst.y) && TryParse<float>(z.c_str(), dst.z);
}

View File

@ -10,6 +10,7 @@
#include <type_traits> #include <type_traits>
#include <stdexcept> #include <stdexcept>
#include <BitStream.h> #include <BitStream.h>
#include "NiPoint3.h"
#include "Game.h" #include "Game.h"
#include "dLogger.h" #include "dLogger.h"
@ -208,6 +209,8 @@ namespace GeneralUtils {
return TryParse<T>(value.c_str(), dst); return TryParse<T>(value.c_str(), dst);
} }
bool TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst);
template<typename T> template<typename T>
std::u16string to_u16string(T value) { std::u16string to_u16string(T value) {
return GeneralUtils::ASCIIToUTF16(std::to_string(value)); return GeneralUtils::ASCIIToUTF16(std::to_string(value));

View File

@ -128,6 +128,12 @@ NiPoint3 NiPoint3::operator+(const NiPoint3& point) const {
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z); return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
} }
//! Operator for addition of vectors
NiPoint3 NiPoint3::operator+=(const NiPoint3& point) const {
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
}
//! Operator for subtraction of vectors //! Operator for subtraction of vectors
NiPoint3 NiPoint3::operator-(const NiPoint3& point) const { NiPoint3 NiPoint3::operator-(const NiPoint3& point) const {
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z); return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);

View File

@ -135,6 +135,9 @@ public:
//! Operator for addition of vectors //! Operator for addition of vectors
NiPoint3 operator+(const NiPoint3& point) const; NiPoint3 operator+(const NiPoint3& point) const;
//! Operator for addition of vectors
NiPoint3 operator+=(const NiPoint3& point) const;
//! Operator for subtraction of vectors //! Operator for subtraction of vectors
NiPoint3 operator-(const NiPoint3& point) const; NiPoint3 operator-(const NiPoint3& point) const;

View File

@ -175,21 +175,6 @@ union suchar {
char svalue; char svalue;
}; };
//=========== DLU ENUMS ============
enum eGameMasterLevel : int32_t {
GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player.
GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers.
GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs.
GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items.
GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban.
GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties.
GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live.
GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions.
GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live.
GAME_MASTER_LEVEL_OPERATOR = 9 // Can shutdown server for restarts & updates.
};
//=========== LU ENUMS ============ //=========== LU ENUMS ============
//! An enum for object ID bits //! An enum for object ID bits

View File

@ -445,6 +445,7 @@ enum GAME_MSG : unsigned short {
GAME_MSG_BBB_SAVE_RESPONSE = 1006, GAME_MSG_BBB_SAVE_RESPONSE = 1006,
GAME_MSG_NOTIFY_CLIENT_OBJECT = 1042, GAME_MSG_NOTIFY_CLIENT_OBJECT = 1042,
GAME_MSG_DISPLAY_ZONE_SUMMARY = 1043, GAME_MSG_DISPLAY_ZONE_SUMMARY = 1043,
GAME_MSG_ZONE_SUMMARY_DISMISSED = 1044,
GAME_MSG_ACTIVITY_STATE_CHANGE_REQUEST = 1053, GAME_MSG_ACTIVITY_STATE_CHANGE_REQUEST = 1053,
GAME_MSG_MODIFY_PLAYER_ZONE_STATISTIC = 1046, GAME_MSG_MODIFY_PLAYER_ZONE_STATISTIC = 1046,
GAME_MSG_START_BUILDING_WITH_ITEM = 1057, GAME_MSG_START_BUILDING_WITH_ITEM = 1057,
@ -484,6 +485,7 @@ enum GAME_MSG : unsigned short {
GAME_MSG_LOCK_NODE_ROTATION = 1260, GAME_MSG_LOCK_NODE_ROTATION = 1260,
GAME_MSG_VEHICLE_SET_WHEEL_LOCK_STATE = 1273, GAME_MSG_VEHICLE_SET_WHEEL_LOCK_STATE = 1273,
GAME_MSG_NOTIFY_VEHICLE_OF_RACING_OBJECT = 1276, GAME_MSG_NOTIFY_VEHICLE_OF_RACING_OBJECT = 1276,
GAME_MSG_SET_NAME_BILLBOARD_STATE = 1284,
GAME_MSG_PLAYER_REACHED_RESPAWN_CHECKPOINT = 1296, GAME_MSG_PLAYER_REACHED_RESPAWN_CHECKPOINT = 1296,
GAME_MSG_HANDLE_UGC_EQUIP_POST_DELETE_BASED_ON_EDIT_MODE = 1300, GAME_MSG_HANDLE_UGC_EQUIP_POST_DELETE_BASED_ON_EDIT_MODE = 1300,
GAME_MSG_HANDLE_UGC_EQUIP_PRE_CREATE_BASED_ON_EDIT_MODE = 1301, GAME_MSG_HANDLE_UGC_EQUIP_PRE_CREATE_BASED_ON_EDIT_MODE = 1301,
@ -494,6 +496,7 @@ enum GAME_MSG : unsigned short {
GAME_MSG_MATCH_UPDATE = 1310, GAME_MSG_MATCH_UPDATE = 1310,
GAME_MSG_MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131, GAME_MSG_MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131,
GAME_MSG_MODULE_ASSEMBLY_QUERY_DATA = 1132, GAME_MSG_MODULE_ASSEMBLY_QUERY_DATA = 1132,
GAME_MSG_SHOW_BILLBOARD_INTERACT_ICON = 1337,
GAME_MSG_CHANGE_IDLE_FLAGS = 1338, GAME_MSG_CHANGE_IDLE_FLAGS = 1338,
GAME_MSG_VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340, GAME_MSG_VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340,
GAME_MSG_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341, GAME_MSG_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341,

View File

@ -0,0 +1,11 @@
#ifndef __EENDBEHAVIOR__H__
#define __EENDBEHAVIOR__H__
#include <cstdint>
enum class eEndBehavior : uint32_t {
RETURN,
WAIT
};
#endif //!__EENDBEHAVIOR__H__

View File

@ -0,0 +1,20 @@
#ifndef __EGAMEMASTERLEVEL__H__
#define __EGAMEMASTERLEVEL__H__
#include <cstdint>
enum class eGameMasterLevel : uint8_t {
CIVILIAN = 0, // Normal player.
FORUM_MODERATOR = 1, // No permissions on live servers.
JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs.
MODERATOR = 3, // Can return lost items.
SENIOR_MODERATOR = 4, // Can ban.
LEAD_MODERATOR = 5, // Can approve properties.
JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live.
INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions.
DEVELOPER = 8, // Active developer, full permissions on live.
OPERATOR = 9 // Can shutdown server for restarts & updates.
};
#endif //!__EGAMEMASTERLEVEL__H__

View File

@ -0,0 +1,15 @@
#ifndef __EPHYSICSEFFECTTYPE__H__
#define __EPHYSICSEFFECTTYPE__H__
#include <cstdint>
enum class ePhysicsEffectType : uint32_t {
PUSH,
ATTRACT,
REPULSE,
GRAVITY_SCALE,
FRICTION
};
#endif //!__EPHYSICSEFFECTTYPE__H__

View File

@ -35,7 +35,7 @@ public:
{"OnTimerDone", eTriggerEventType::TIMER_DONE}, {"OnTimerDone", eTriggerEventType::TIMER_DONE},
{"OnRebuildComplete", eTriggerEventType::REBUILD_COMPLETE}, {"OnRebuildComplete", eTriggerEventType::REBUILD_COMPLETE},
{"OnActivated", eTriggerEventType::ACTIVATED}, {"OnActivated", eTriggerEventType::ACTIVATED},
{"OnDeactivated", eTriggerEventType::DEACTIVATED}, {"OnDectivated", eTriggerEventType::DEACTIVATED}, // Dectivated vs Deactivated
{"OnArrived", eTriggerEventType::ARRIVED}, {"OnArrived", eTriggerEventType::ARRIVED},
{"OnArrivedAtEndOfPath", eTriggerEventType::ARRIVED_AT_END_OF_PATH}, {"OnArrivedAtEndOfPath", eTriggerEventType::ARRIVED_AT_END_OF_PATH},
{"OnZoneSummaryDismissed", eTriggerEventType::ZONE_SUMMARY_DISMISSED}, {"OnZoneSummaryDismissed", eTriggerEventType::ZONE_SUMMARY_DISMISSED},

View File

@ -18,6 +18,7 @@
#include "InventoryComponent.h" #include "InventoryComponent.h"
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eMissionState.h" #include "eMissionState.h"
#include "eGameMasterLevel.h"
Character::Character(uint32_t id, User* parentUser) { Character::Character(uint32_t id, User* parentUser) {
//First load the name, etc: //First load the name, etc:
@ -204,7 +205,9 @@ void Character::DoQuickXMLDataParse() {
tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char"); tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char");
if (character) { if (character) {
character->QueryAttribute("cc", &m_Coins); character->QueryAttribute("cc", &m_Coins);
character->QueryAttribute("gm", &m_GMLevel); int32_t gm_level = 0;
character->QueryAttribute("gm", &gm_level);
m_GMLevel = static_cast<eGameMasterLevel>(gm_level);
uint64_t lzidConcat = 0; uint64_t lzidConcat = 0;
if (character->FindAttribute("lzid")) { if (character->FindAttribute("lzid")) {
@ -304,7 +307,7 @@ void Character::SaveXMLToDatabase() {
tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char"); tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char");
if (character) { if (character) {
character->SetAttribute("gm", m_GMLevel); character->SetAttribute("gm", static_cast<uint32_t>(m_GMLevel));
character->SetAttribute("cc", m_Coins); character->SetAttribute("cc", m_Coins);
auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID(); auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID();
@ -545,7 +548,7 @@ void Character::OnZoneLoad() {
const auto maxGMLevel = m_ParentUser->GetMaxGMLevel(); const auto maxGMLevel = m_ParentUser->GetMaxGMLevel();
// This does not apply to the GMs // This does not apply to the GMs
if (maxGMLevel > GAME_MASTER_LEVEL_CIVILIAN) { if (maxGMLevel > eGameMasterLevel::CIVILIAN) {
return; return;
} }
@ -621,3 +624,21 @@ void Character::SendMuteNotice() const {
ChatPackets::SendSystemMessage(GetEntity()->GetSystemAddress(), u"You are muted until " + timeStr); ChatPackets::SendSystemMessage(GetEntity()->GetSystemAddress(), u"You are muted until " + timeStr);
} }
void Character::SetBillboardVisible(bool visible) {
if (m_BillboardVisible == visible) return;
m_BillboardVisible = visible;
GameMessages::SendSetNamebillboardState(UNASSIGNED_SYSTEM_ADDRESS, m_OurEntity->GetObjectID());
if (!visible) return;
// The GameMessage we send for turning the nameplate off just deletes the BillboardSubcomponent from the parent component.
// Because that same message does not allow for custom parameters, we need to create the BillboardSubcomponent a different way
// This workaround involves sending an unrelated GameMessage that does not apply to player entites,
// but forces the client to create the necessary SubComponent that controls the billboard.
GameMessages::SendShowBillboardInteractIcon(UNASSIGNED_SYSTEM_ADDRESS, m_OurEntity->GetObjectID());
// Now turn off the billboard for the owner.
GameMessages::SendSetNamebillboardState(m_OurEntity->GetSystemAddress(), m_OurEntity->GetObjectID());
}

View File

@ -15,6 +15,7 @@ class User;
struct Packet; struct Packet;
class Entity; class Entity;
enum class ePermissionMap : uint64_t; enum class ePermissionMap : uint64_t;
enum class eGameMasterLevel : uint8_t;
/** /**
* Meta information about a character, like their name and style * Meta information about a character, like their name and style
@ -308,13 +309,13 @@ public:
* Gets the GM level of the character * Gets the GM level of the character
* @return the GM level * @return the GM level
*/ */
int32_t GetGMLevel() const { return m_GMLevel; } eGameMasterLevel GetGMLevel() const { return m_GMLevel; }
/** /**
* Sets the GM level of the character * Sets the GM level of the character
* @param value the GM level to set * @param value the GM level to set
*/ */
void SetGMLevel(uint8_t value) { m_GMLevel = value; } void SetGMLevel(eGameMasterLevel value) { m_GMLevel = value; }
/** /**
* Gets the current amount of coins of the character * Gets the current amount of coins of the character
@ -451,6 +452,10 @@ public:
*/ */
void SetIsFlying(bool isFlying) { m_IsFlying = isFlying; } void SetIsFlying(bool isFlying) { m_IsFlying = isFlying; }
bool GetBillboardVisible() { return m_BillboardVisible; }
void SetBillboardVisible(bool visible);
private: private:
/** /**
* The ID of this character. First 32 bits of the ObjectID. * The ID of this character. First 32 bits of the ObjectID.
@ -477,7 +482,7 @@ private:
* *
* @see eGameMasterLevel * @see eGameMasterLevel
*/ */
int32_t m_GMLevel; eGameMasterLevel m_GMLevel;
/** /**
* Bitmap of permission attributes this character has. * Bitmap of permission attributes this character has.
@ -652,6 +657,11 @@ private:
*/ */
bool m_IsFlying = false; bool m_IsFlying = false;
/**
* True if billboard (referred to as nameplate for end users) is visible, false otherwise
*/
bool m_BillboardVisible = true;
/** /**
* Queries the character XML and updates all the fields of this object * Queries the character XML and updates all the fields of this object
* NOTE: quick as there's no DB lookups * NOTE: quick as there's no DB lookups

View File

@ -70,6 +70,7 @@
#include "RailActivatorComponent.h" #include "RailActivatorComponent.h"
#include "LUPExhibitComponent.h" #include "LUPExhibitComponent.h"
#include "TriggerComponent.h" #include "TriggerComponent.h"
#include "eGameMasterLevel.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
// Table includes // Table includes
@ -89,7 +90,7 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity)
m_TemplateID = info.lot; m_TemplateID = info.lot;
m_ParentEntity = parentEntity; m_ParentEntity = parentEntity;
m_Character = nullptr; m_Character = nullptr;
m_GMLevel = 0; m_GMLevel = eGameMasterLevel::CIVILIAN;
m_CollectibleID = 0; m_CollectibleID = 0;
m_NetworkID = 0; m_NetworkID = 0;
m_Groups = {}; m_Groups = {};
@ -763,7 +764,7 @@ void Entity::Initialize() {
no_ghosting: no_ghosting:
TriggerEvent(eTriggerEventType::CREATE); TriggerEvent(eTriggerEventType::CREATE, this);
if (m_Character) { if (m_Character) {
auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>(); auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>();
@ -858,7 +859,7 @@ void Entity::SetProximityRadius(dpEntity* entity, std::string name) {
proxMon->SetProximityRadius(entity, name); proxMon->SetProximityRadius(entity, name);
} }
void Entity::SetGMLevel(uint8_t value) { void Entity::SetGMLevel(eGameMasterLevel value) {
m_GMLevel = value; m_GMLevel = value;
if (GetParentUser()) { if (GetParentUser()) {
Character* character = GetParentUser()->GetLastUsedChar(); Character* character = GetParentUser()->GetLastUsedChar();
@ -970,7 +971,7 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke
outBitStream->Write0(); //ObjectWorldState outBitStream->Write0(); //ObjectWorldState
if (m_GMLevel != 0) { if (m_GMLevel != eGameMasterLevel::CIVILIAN) {
outBitStream->Write1(); outBitStream->Write1();
outBitStream->Write(m_GMLevel); outBitStream->Write(m_GMLevel);
} else outBitStream->Write0(); //No GM Level } else outBitStream->Write0(); //No GM Level
@ -1390,7 +1391,7 @@ void Entity::OnEmoteReceived(const int32_t emote, Entity* target) {
} }
void Entity::OnUse(Entity* originator) { void Entity::OnUse(Entity* originator) {
TriggerEvent(eTriggerEventType::INTERACT); TriggerEvent(eTriggerEventType::INTERACT, originator);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
script->OnUse(this, originator); script->OnUse(this, originator);
@ -1412,6 +1413,7 @@ void Entity::OnHitOrHealResult(Entity* attacker, int32_t damage) {
} }
void Entity::OnHit(Entity* attacker) { void Entity::OnHit(Entity* attacker) {
TriggerEvent(eTriggerEventType::HIT, attacker);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
script->OnHit(this, attacker); script->OnHit(this, attacker);
} }

View File

@ -31,6 +31,7 @@ class Item;
class Character; class Character;
class EntityCallbackTimer; class EntityCallbackTimer;
enum class eTriggerEventType; enum class eTriggerEventType;
enum class eGameMasterLevel : uint8_t;
enum class eReplicaComponentType : uint32_t; enum class eReplicaComponentType : uint32_t;
namespace CppScripts { namespace CppScripts {
@ -60,7 +61,7 @@ public:
Character* GetCharacter() const { return m_Character; } Character* GetCharacter() const { return m_Character; }
uint8_t GetGMLevel() const { return m_GMLevel; } eGameMasterLevel GetGMLevel() const { return m_GMLevel; }
uint8_t GetCollectibleID() const { return uint8_t(m_CollectibleID); } uint8_t GetCollectibleID() const { return uint8_t(m_CollectibleID); }
@ -108,7 +109,7 @@ public:
void SetCharacter(Character* value) { m_Character = value; } void SetCharacter(Character* value) { m_Character = value; }
void SetGMLevel(uint8_t value); void SetGMLevel(eGameMasterLevel value);
void SetOwnerOverride(LWOOBJID value); void SetOwnerOverride(LWOOBJID value);
@ -308,7 +309,7 @@ protected:
Entity* m_ParentEntity; //For spawners and the like Entity* m_ParentEntity; //For spawners and the like
std::vector<Entity*> m_ChildEntities; std::vector<Entity*> m_ChildEntities;
uint8_t m_GMLevel; eGameMasterLevel m_GMLevel;
uint16_t m_CollectibleID; uint16_t m_CollectibleID;
std::vector<std::string> m_Groups; std::vector<std::string> m_Groups;
uint16_t m_NetworkID; uint16_t m_NetworkID;

View File

@ -20,6 +20,7 @@
#include "MessageIdentifiers.h" #include "MessageIdentifiers.h"
#include "dConfig.h" #include "dConfig.h"
#include "eTriggerEventType.h" #include "eTriggerEventType.h"
#include "eGameMasterLevel.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
EntityManager* EntityManager::m_Address = nullptr; EntityManager* EntityManager::m_Address = nullptr;
@ -162,6 +163,8 @@ void EntityManager::DestroyEntity(Entity* entity) {
return; return;
} }
entity->TriggerEvent(eTriggerEventType::DESTROY, entity);
const auto id = entity->GetObjectID(); const auto id = entity->GetObjectID();
if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), id)) { if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), id)) {
@ -370,7 +373,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
// PacketUtils::SavePacket("[24]_"+std::to_string(entity->GetObjectID()) + "_" + std::to_string(m_SerializationCounter) + ".bin", (char*)stream.GetData(), stream.GetNumberOfBytesUsed()); // PacketUtils::SavePacket("[24]_"+std::to_string(entity->GetObjectID()) + "_" + std::to_string(m_SerializationCounter) + ".bin", (char*)stream.GetData(), stream.GetNumberOfBytesUsed());
if (entity->IsPlayer()) { if (entity->IsPlayer()) {
if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { if (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN) {
GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, sysAddr); GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, sysAddr);
} }
} }
@ -587,7 +590,7 @@ void EntityManager::ScheduleForKill(Entity* entity) {
SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>(); SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>();
if (switchComp) { if (switchComp) {
entity->TriggerEvent(eTriggerEventType::DEACTIVATED); entity->TriggerEvent(eTriggerEventType::DEACTIVATED, entity);
} }
const auto objectId = entity->GetObjectID(); const auto objectId = entity->GetObjectID();

View File

@ -6,13 +6,14 @@
#include "Game.h" #include "Game.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "eServerDisconnectIdentifiers.h" #include "eServerDisconnectIdentifiers.h"
#include "eGameMasterLevel.h"
User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) { User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) {
m_AccountID = 0; m_AccountID = 0;
m_Username = ""; m_Username = "";
m_SessionKey = ""; m_SessionKey = "";
m_MaxGMLevel = 0; //The max GM level this account can assign to it's characters m_MaxGMLevel = eGameMasterLevel::CIVILIAN; //The max GM level this account can assign to it's characters
m_LastCharID = 0; m_LastCharID = 0;
m_SessionKey = sessionKey; m_SessionKey = sessionKey;
@ -33,7 +34,7 @@ User::User(const SystemAddress& sysAddr, const std::string& username, const std:
sql::ResultSet* res = stmt->executeQuery(); sql::ResultSet* res = stmt->executeQuery();
while (res->next()) { while (res->next()) {
m_AccountID = res->getUInt(1); m_AccountID = res->getUInt(1);
m_MaxGMLevel = res->getInt(2); m_MaxGMLevel = static_cast<eGameMasterLevel>(res->getInt(2));
m_MuteExpire = 0; //res->getUInt64(3); m_MuteExpire = 0; //res->getUInt64(3);
} }

View File

@ -9,6 +9,7 @@
#include <unordered_map> #include <unordered_map>
class Character; class Character;
enum class eGameMasterLevel : uint8_t;
struct BehaviorParams { struct BehaviorParams {
uint32_t behavior; uint32_t behavior;
@ -29,7 +30,7 @@ public:
std::string& GetSessionKey() { return m_SessionKey; } std::string& GetSessionKey() { return m_SessionKey; }
SystemAddress& GetSystemAddress() { return m_SystemAddress; } SystemAddress& GetSystemAddress() { return m_SystemAddress; }
uint32_t GetMaxGMLevel() { return m_MaxGMLevel; } eGameMasterLevel GetMaxGMLevel() { return m_MaxGMLevel; }
uint32_t GetLastCharID() { return m_LastCharID; } uint32_t GetLastCharID() { return m_LastCharID; }
void SetLastCharID(uint32_t newCharID) { m_LastCharID = newCharID; } void SetLastCharID(uint32_t newCharID) { m_LastCharID = newCharID; }
@ -61,7 +62,7 @@ private:
std::string m_SessionKey; std::string m_SessionKey;
SystemAddress m_SystemAddress; SystemAddress m_SystemAddress;
uint32_t m_MaxGMLevel; //The max GM level this account can assign to it's characters eGameMasterLevel m_MaxGMLevel; //The max GM level this account can assign to it's characters
uint32_t m_LastCharID; uint32_t m_LastCharID;
std::vector<Character*> m_Characters; std::vector<Character*> m_Characters;
LWOOBJID m_LoggedInCharID; LWOOBJID m_LoggedInCharID;

View File

@ -23,6 +23,7 @@
#include "AssetManager.h" #include "AssetManager.h"
#include "CDClientDatabase.h" #include "CDClientDatabase.h"
#include "dMessageIdentifiers.h" #include "dMessageIdentifiers.h"
#include "eGameMasterLevel.h"
UserManager* UserManager::m_Address = nullptr; UserManager* UserManager::m_Address = nullptr;
@ -330,7 +331,7 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet)
//Check to see if our name was pre-approved: //Check to see if our name was pre-approved:
bool nameOk = IsNamePreapproved(name); bool nameOk = IsNamePreapproved(name);
if (!nameOk && u->GetMaxGMLevel() > 1) nameOk = true; if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true;
if (name != "") { if (name != "") {
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("INSERT INTO `charinfo`(`id`, `account_id`, `name`, `pending_name`, `needs_rename`, `last_login`) VALUES (?,?,?,?,?,?)"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("INSERT INTO `charinfo`(`id`, `account_id`, `name`, `pending_name`, `needs_rename`, `last_login`) VALUES (?,?,?,?,?,?)");

View File

@ -7,6 +7,7 @@
#include "dLogger.h" #include "dLogger.h"
#include "GameMessages.h" #include "GameMessages.h"
#include <BitStream.h> #include <BitStream.h>
#include "eTriggerEventType.h"
BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) { BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) {
m_PetEnabled = false; m_PetEnabled = false;
@ -46,8 +47,10 @@ void BouncerComponent::SetPetBouncerEnabled(bool value) {
EntityManager::Instance()->SerializeEntity(m_Parent); EntityManager::Instance()->SerializeEntity(m_Parent);
if (value) { if (value) {
m_Parent->TriggerEvent(eTriggerEventType::PET_ON_SWITCH, m_Parent);
GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 1513, u"create", "PetOnSwitch", LWOOBJID_EMPTY, 1, 1, true); GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 1513, u"create", "PetOnSwitch", LWOOBJID_EMPTY, 1, 1, true);
} else { } else {
m_Parent->TriggerEvent(eTriggerEventType::PET_OFF_SWITCH, m_Parent);
GameMessages::SendStopFXEffect(m_Parent, true, "PetOnSwitch"); GameMessages::SendStopFXEffect(m_Parent, true, "PetOnSwitch");
} }

View File

@ -14,6 +14,7 @@
#include "GameMessages.h" #include "GameMessages.h"
#include "Item.h" #include "Item.h"
#include "AMFFormat.h" #include "AMFFormat.h"
#include "eGameMasterLevel.h"
CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) { CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) {
m_Character = character; m_Character = character;
@ -165,9 +166,9 @@ void CharacterComponent::SetPvpEnabled(const bool value) {
m_PvpEnabled = value; m_PvpEnabled = value;
} }
void CharacterComponent::SetGMLevel(int gmlevel) { void CharacterComponent::SetGMLevel(eGameMasterLevel gmlevel) {
m_DirtyGMInfo = true; m_DirtyGMInfo = true;
if (gmlevel > 0) m_IsGM = true; if (gmlevel > eGameMasterLevel::CIVILIAN) m_IsGM = true;
else m_IsGM = false; else m_IsGM = false;
m_GMLevel = gmlevel; m_GMLevel = gmlevel;
} }
@ -239,7 +240,7 @@ void CharacterComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
// End custom attributes // End custom attributes
// //
if (m_GMLevel > 0) { if (m_GMLevel > eGameMasterLevel::CIVILIAN) {
m_IsGM = true; m_IsGM = true;
m_DirtyGMInfo = true; m_DirtyGMInfo = true;
m_EditorLevel = m_GMLevel; m_EditorLevel = m_GMLevel;

View File

@ -178,7 +178,7 @@ public:
* Sets the GM level of the character, should be called in the entity. Here it's set for serialization * Sets the GM level of the character, should be called in the entity. Here it's set for serialization
* @param gmlevel the gm level to set * @param gmlevel the gm level to set
*/ */
void SetGMLevel(int gmlevel); void SetGMLevel(eGameMasterLevel gmlevel);
/** /**
* Initializes the player statistics from the string stored in the XML * Initializes the player statistics from the string stored in the XML
@ -333,7 +333,7 @@ private:
/** /**
* The current GM level of this character (anything > 0 counts as a GM) * The current GM level of this character (anything > 0 counts as a GM)
*/ */
unsigned char m_GMLevel; eGameMasterLevel m_GMLevel;
/** /**
* Whether the character has HF enabled * Whether the character has HF enabled
@ -343,7 +343,7 @@ private:
/** /**
* The level of the character in HF * The level of the character in HF
*/ */
unsigned char m_EditorLevel; eGameMasterLevel m_EditorLevel;
/** /**
* Whether the currently active activity has been changed * Whether the currently active activity has been changed

View File

@ -23,6 +23,7 @@
#include "EntityInfo.h" #include "EntityInfo.h"
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "RenderComponent.h" #include "RenderComponent.h"
#include "eGameMasterLevel.h"
std::unordered_map<LOT, PetComponent::PetPuzzleData> PetComponent::buildCache{}; std::unordered_map<LOT, PetComponent::PetPuzzleData> PetComponent::buildCache{};
std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::currentActivities{}; std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::currentActivities{};
@ -988,7 +989,7 @@ void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandTy
// TODO: Go to player // TODO: Go to player
} }
if (owner->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (owner->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
ChatPackets::SendSystemMessage(owner->GetSystemAddress(), u"Commmand Type: " + (GeneralUtils::to_u16string(commandType)) + u" - Type Id: " + (GeneralUtils::to_u16string(typeId))); ChatPackets::SendSystemMessage(owner->GetSystemAddress(), u"Commmand Type: " + (GeneralUtils::to_u16string(commandType)) + u" - Type Id: " + (GeneralUtils::to_u16string(typeId)));
} }
} }
@ -1080,7 +1081,7 @@ void PetComponent::SetPetNameForModeration(const std::string& petName) {
int approved = 1; //default, in mod int approved = 1; //default, in mod
//Make sure that the name isn't already auto-approved: //Make sure that the name isn't already auto-approved:
if (Game::chatFilter->IsSentenceOkay(petName, 0).empty()) { if (Game::chatFilter->IsSentenceOkay(petName, eGameMasterLevel::CIVILIAN).empty()) {
approved = 2; //approved approved = 2; //approved
} }

View File

@ -14,6 +14,7 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "ControllablePhysicsComponent.h" #include "ControllablePhysicsComponent.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "ePhysicsEffectType.h"
#include "CDClientManager.h" #include "CDClientManager.h"
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
@ -36,7 +37,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : Component(par
m_PositionInfoDirty = false; m_PositionInfoDirty = false;
m_IsPhysicsEffectActive = false; m_IsPhysicsEffectActive = false;
m_EffectType = 0; m_EffectType = ePhysicsEffectType::PUSH;
m_DirectionalMultiplier = 0.0f; m_DirectionalMultiplier = 0.0f;
m_MinMax = false; m_MinMax = false;
@ -405,7 +406,7 @@ void PhantomPhysicsComponent::SetDirectionalMultiplier(float mul) {
m_EffectInfoDirty = true; m_EffectInfoDirty = true;
} }
void PhantomPhysicsComponent::SetEffectType(uint32_t type) { void PhantomPhysicsComponent::SetEffectType(ePhysicsEffectType type) {
m_EffectType = type; m_EffectType = type;
m_EffectInfoDirty = true; m_EffectInfoDirty = true;
} }

View File

@ -17,6 +17,7 @@
class LDFBaseData; class LDFBaseData;
class Entity; class Entity;
class dpEntity; class dpEntity;
enum class ePhysicsEffectType : uint32_t ;
/** /**
* Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be * Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be
@ -103,13 +104,13 @@ public:
* Returns the effect that's currently active, defaults to 0 * Returns the effect that's currently active, defaults to 0
* @return the effect that's currently active * @return the effect that's currently active
*/ */
uint32_t GetEffectType() const { return m_EffectType; } ePhysicsEffectType GetEffectType() const { return m_EffectType; }
/** /**
* Sets the effect that's currently active * Sets the effect that's currently active
* @param type the effect to set * @param type the effect to set
*/ */
void SetEffectType(uint32_t type); void SetEffectType(ePhysicsEffectType type);
/** /**
* Returns the Physics entity for the component * Returns the Physics entity for the component
@ -168,7 +169,7 @@ private:
/** /**
* The physics effect that's currently active, defaults to 0 * The physics effect that's currently active, defaults to 0
*/ */
uint32_t m_EffectType; ePhysicsEffectType m_EffectType;
/** /**
* A scaling multiplier to add to the directional vector * A scaling multiplier to add to the directional vector

View File

@ -12,6 +12,7 @@
#include "UserManager.h" #include "UserManager.h"
#include "dLogger.h" #include "dLogger.h"
#include "AMFFormat.h" #include "AMFFormat.h"
#include "eGameMasterLevel.h"
PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) { PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) {
this->propertyQueries = {}; this->propertyQueries = {};
@ -271,7 +272,7 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl
bool isModeratorApproved = propertyEntry->getBoolean(10); bool isModeratorApproved = propertyEntry->getBoolean(10);
if (!isModeratorApproved && entity->GetGMLevel() >= GAME_MASTER_LEVEL_LEAD_MODERATOR) { if (!isModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) {
propertyName = "[AWAITING APPROVAL]"; propertyName = "[AWAITING APPROVAL]";
propertyDescription = "[AWAITING APPROVAL]"; propertyDescription = "[AWAITING APPROVAL]";
isModeratorApproved = true; isModeratorApproved = true;

View File

@ -8,6 +8,7 @@
#include "CharacterComponent.h" #include "CharacterComponent.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eTriggerEventType.h"
#include "dServer.h" #include "dServer.h"
#include "PacketUtils.h" #include "PacketUtils.h"
@ -496,6 +497,8 @@ void RebuildComponent::CompleteRebuild(Entity* user) {
for (const auto& callback : m_RebuildCompleteCallbacks) for (const auto& callback : m_RebuildCompleteCallbacks)
callback(user); callback(user);
m_Parent->TriggerEvent(eTriggerEventType::REBUILD_COMPLETE, user);
auto* movingPlatform = m_Parent->GetComponent<MovingPlatformComponent>(); auto* movingPlatform = m_Parent->GetComponent<MovingPlatformComponent>();
if (movingPlatform != nullptr) { if (movingPlatform != nullptr) {
movingPlatform->OnCompleteRebuild(); movingPlatform->OnCompleteRebuild();

View File

@ -305,7 +305,7 @@ bool ScriptedActivityComponent::HasLobby() const {
bool ScriptedActivityComponent::IsValidActivity(Entity* player) { bool ScriptedActivityComponent::IsValidActivity(Entity* player) {
// Makes it so that scripted activities with an unimplemented map cannot be joined // Makes it so that scripted activities with an unimplemented map cannot be joined
/*if (player->GetGMLevel() < GAME_MASTER_LEVEL_DEVELOPER && (m_ActivityInfo.instanceMapID == 1302 || m_ActivityInfo.instanceMapID == 1301)) { /*if (player->GetGMLevel() < eGameMasterLevel::DEVELOPER && (m_ActivityInfo.instanceMapID == 1302 || m_ActivityInfo.instanceMapID == 1301)) {
if (m_Parent->GetLOT() == 4860) { if (m_Parent->GetLOT() == 4860) {
auto* missionComponent = player->GetComponent<MissionComponent>(); auto* missionComponent = player->GetComponent<MissionComponent>();
missionComponent->CompleteMission(229); missionComponent->CompleteMission(229);

View File

@ -44,7 +44,7 @@ void SwitchComponent::EntityEnter(Entity* entity) {
} }
m_Active = true; m_Active = true;
if (!m_Parent) return; if (!m_Parent) return;
m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED); m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED, entity);
const auto grpName = m_Parent->GetVarAsString(u"grp_name"); const auto grpName = m_Parent->GetVarAsString(u"grp_name");
@ -80,7 +80,7 @@ void SwitchComponent::Update(float deltaTime) {
if (m_Timer <= 0.0f) { if (m_Timer <= 0.0f) {
m_Active = false; m_Active = false;
if (!m_Parent) return; if (!m_Parent) return;
m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED); m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED, m_Parent);
const auto grpName = m_Parent->GetVarAsString(u"grp_name"); const auto grpName = m_Parent->GetVarAsString(u"grp_name");

View File

@ -1,10 +1,19 @@
#include "TriggerComponent.h" #include "TriggerComponent.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "LUTriggers.h" #include "TeamManager.h"
#include "eTriggerCommandType.h" #include "eTriggerCommandType.h"
#include "eMissionTaskType.h"
#include "ePhysicsEffectType.h"
#include "CharacterComponent.h"
#include "ControllablePhysicsComponent.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "PhantomPhysicsComponent.h" #include "PhantomPhysicsComponent.h"
#include "CDMissionTasksTable.h" #include "Player.h"
#include "RebuildComponent.h"
#include "SkillComponent.h"
#include "eEndBehavior.h"
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) { TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) {
m_Parent = parent; m_Parent = parent;
@ -51,19 +60,37 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
case eTriggerCommandType::FIRE_EVENT: case eTriggerCommandType::FIRE_EVENT:
HandleFireEvent(targetEntity, command->args); HandleFireEvent(targetEntity, command->args);
break; break;
case eTriggerCommandType::DESTROY_OBJ: break; case eTriggerCommandType::DESTROY_OBJ:
case eTriggerCommandType::TOGGLE_TRIGGER: break; HandleDestroyObject(targetEntity, command->args);
case eTriggerCommandType::RESET_REBUILD: break; break;
case eTriggerCommandType::TOGGLE_TRIGGER:
HandleToggleTrigger(targetEntity, command->args);
break;
case eTriggerCommandType::RESET_REBUILD:
HandleResetRebuild(targetEntity, command->args);
break;
case eTriggerCommandType::SET_PATH: break; case eTriggerCommandType::SET_PATH: break;
case eTriggerCommandType::SET_PICK_TYPE: break; case eTriggerCommandType::SET_PICK_TYPE: break;
case eTriggerCommandType::MOVE_OBJECT: break; case eTriggerCommandType::MOVE_OBJECT:
case eTriggerCommandType::ROTATE_OBJECT: break; HandleMoveObject(targetEntity, argArray);
case eTriggerCommandType::PUSH_OBJECT: break; break;
case eTriggerCommandType::REPEL_OBJECT: break; case eTriggerCommandType::ROTATE_OBJECT:
HandleRotateObject(targetEntity, argArray);
break;
case eTriggerCommandType::PUSH_OBJECT:
HandlePushObject(targetEntity, argArray);
break;
case eTriggerCommandType::REPEL_OBJECT:
HandleRepelObject(targetEntity, command->args);
break;
case eTriggerCommandType::SET_TIMER: break; case eTriggerCommandType::SET_TIMER: break;
case eTriggerCommandType::CANCEL_TIMER: break; case eTriggerCommandType::CANCEL_TIMER: break;
case eTriggerCommandType::PLAY_CINEMATIC: break; case eTriggerCommandType::PLAY_CINEMATIC:
case eTriggerCommandType::TOGGLE_BBB: break; HandlePlayCinematic(targetEntity, argArray);
break;
case eTriggerCommandType::TOGGLE_BBB:
HandleToggleBBB(targetEntity, command->args);
break;
case eTriggerCommandType::UPDATE_MISSION: case eTriggerCommandType::UPDATE_MISSION:
HandleUpdateMission(targetEntity, argArray); HandleUpdateMission(targetEntity, argArray);
break; break;
@ -75,8 +102,43 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
case eTriggerCommandType::STOP_PATHING: break; case eTriggerCommandType::STOP_PATHING: break;
case eTriggerCommandType::START_PATHING: break; case eTriggerCommandType::START_PATHING: break;
case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break; case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break;
case eTriggerCommandType::PLAY_EFFECT: break; case eTriggerCommandType::PLAY_EFFECT:
case eTriggerCommandType::STOP_EFFECT: break; HandlePlayEffect(targetEntity, argArray);
break;
case eTriggerCommandType::STOP_EFFECT:
GameMessages::SendStopFXEffect(targetEntity, true, command->args);
break;
case eTriggerCommandType::CAST_SKILL:
HandleCastSkill(targetEntity, command->args);
break;
case eTriggerCommandType::DISPLAY_ZONE_SUMMARY:
GameMessages::SendDisplayZoneSummary(targetEntity->GetObjectID(), targetEntity->GetSystemAddress(), false, command->args == "1", m_Parent->GetObjectID());
break;
case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT:
HandleSetPhysicsVolumeEffect(targetEntity, argArray);
break;
case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS:
HandleSetPhysicsVolumeStatus(targetEntity, command->args);
break;
case eTriggerCommandType::SET_MODEL_TO_BUILD: break;
case eTriggerCommandType::SPAWN_MODEL_BRICKS: break;
case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK:
HandleActivateSpawnerNetwork(command->args);
break;
case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK:
HandleDeactivateSpawnerNetwork(command->args);
break;
case eTriggerCommandType::RESET_SPAWNER_NETWORK:
HandleResetSpawnerNetwork(command->args);
break;
case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS:
HandleDestroySpawnerNetworkObjects(command->args);
break;
case eTriggerCommandType::GO_TO_WAYPOINT: break;
case eTriggerCommandType::ACTIVATE_PHYSICS:
HandleActivatePhysics(targetEntity, command->args);
break;
// DEPRECATED BLOCK START
case eTriggerCommandType::ACTIVATE_MUSIC_CUE: break; case eTriggerCommandType::ACTIVATE_MUSIC_CUE: break;
case eTriggerCommandType::DEACTIVATE_MUSIC_CUE: break; case eTriggerCommandType::DEACTIVATE_MUSIC_CUE: break;
case eTriggerCommandType::FLASH_MUSIC_CUE: break; case eTriggerCommandType::FLASH_MUSIC_CUE: break;
@ -87,20 +149,7 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity
case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break; case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break;
case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break; case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break;
case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break; case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break;
case eTriggerCommandType::CAST_SKILL: break; // DEPRECATED BLOCK END
case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: break;
case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT:
HandleSetPhysicsVolume(targetEntity, argArray, command->target);
break;
case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: break;
case eTriggerCommandType::SET_MODEL_TO_BUILD: break;
case eTriggerCommandType::SPAWN_MODEL_BRICKS: break;
case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: break;
case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: break;
case eTriggerCommandType::RESET_SPAWNER_NETWORK: break;
case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: break;
case eTriggerCommandType::GO_TO_WAYPOINT: break;
case eTriggerCommandType::ACTIVATE_PHYSICS: break;
default: default:
Game::logger->LogDebug("TriggerComponent", "Event %i was not handled!", command->id); Game::logger->LogDebug("TriggerComponent", "Event %i was not handled!", command->id);
break; break;
@ -113,70 +162,262 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman
if (command->target == "self") entities.push_back(m_Parent); if (command->target == "self") entities.push_back(m_Parent);
else if (command->target == "zone") { /*TODO*/ } else if (command->target == "zone") { /*TODO*/ }
else if (command->target == "target") { /*TODO*/ } else if (command->target == "target" && optionalTarget) entities.push_back(optionalTarget);
else if (command->target == "targetTeam") { /*TODO*/ } else if (command->target == "targetTeam" && optionalTarget) {
else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); auto* team = TeamManager::Instance()->GetTeam(optionalTarget->GetObjectID());
else if (command->target == "allPlayers") { /*TODO*/ } for (const auto memberId : team->members) {
else if (command->target == "allNPCs") { /*TODO*/ } auto* member = EntityManager::Instance()->GetEntity(memberId);
if (member) entities.push_back(member);
if (optionalTarget) entities.push_back(optionalTarget); }
} else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName);
else if (command->target == "allPlayers") {
for (auto* player : Player::GetAllPlayers()) {
entities.push_back(player);
}
} else if (command->target == "allNPCs") { /*UNUSED*/ }
return entities; return entities;
} }
void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target) {
PhantomPhysicsComponent* phanPhys = m_Parent->GetComponent<PhantomPhysicsComponent>();
if (!phanPhys) return;
phanPhys->SetPhysicsEffectActive(true);
uint32_t effectType = 0;
std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase
if (argArray.at(0) == "push") effectType = 0;
else if (argArray.at(0) == "attract") effectType = 1;
else if (argArray.at(0) == "repulse") effectType = 2;
else if (argArray.at(0) == "gravity") effectType = 3;
else if (argArray.at(0) == "friction") effectType = 4;
phanPhys->SetEffectType(effectType);
phanPhys->SetDirectionalMultiplier(std::stof(argArray.at(1)));
if (argArray.size() > 4) {
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse<float>(argArray.at(2), direction.x);
GeneralUtils::TryParse<float>(argArray.at(3), direction.y);
GeneralUtils::TryParse<float>(argArray.at(4), direction.z);
phanPhys->SetDirection(direction);
}
if (argArray.size() > 5) {
uint32_t min;
GeneralUtils::TryParse<uint32_t>(argArray.at(6), min);
phanPhys->SetMin(min);
uint32_t max;
GeneralUtils::TryParse<uint32_t>(argArray.at(7), max);
phanPhys->SetMax(max);
}
// TODO: why is this contruct and not serialize?
if (target == "self") EntityManager::Instance()->ConstructEntity(m_Parent);
}
void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) {
CDMissionTasksTable* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>();
std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) {
return (entry.targetGroup == argArray.at(4));
});
for (const CDMissionTasks& task : missionTasks) {
MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>();
if (!missionComponent) continue;
missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray.at(2)));
}
}
void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) { void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) {
script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0); script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0);
} }
} }
void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){
uint32_t killType;
GeneralUtils::TryParse<uint32_t>(args, killType);
targetEntity->Smash(m_Parent->GetObjectID(), static_cast<eKillType>(killType));
}
void TriggerComponent::HandleToggleTrigger(Entity* targetEntity, std::string args){
auto* triggerComponent = targetEntity->GetComponent<TriggerComponent>();
if (!triggerComponent) {
Game::logger->Log("TriggerComponent::HandleToggleTrigger", "Trigger component not found!");
return;
}
triggerComponent->SetTriggerEnabled(args == "1");
}
void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args){
auto* rebuildComponent = targetEntity->GetComponent<RebuildComponent>();
if (!rebuildComponent) {
Game::logger->Log("TriggerComponent::HandleResetRebuild", "Rebuild component not found!");
return;
}
rebuildComponent->ResetRebuild(args == "1");
}
void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray){
if (argArray.size() <= 2) return;
auto position = targetEntity->GetPosition();
NiPoint3 offset = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), offset);
position += offset;
targetEntity->SetPosition(position);
}
void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray){
if (argArray.size() <= 2) return;
NiPoint3 vector = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), vector);
NiQuaternion rotation = NiQuaternion::FromEulerAngles(vector);
targetEntity->SetRotation(rotation);
}
void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray){
auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandlePushObject", "Phantom Physics component not found!");
return;
}
phantomPhysicsComponent->SetPhysicsEffectActive(true);
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH);
phantomPhysicsComponent->SetDirectionalMultiplier(1);
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), direction);
phantomPhysicsComponent->SetDirection(direction);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args){
auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandleRepelObject", "Phantom Physics component not found!");
return;
}
float forceMultiplier;
GeneralUtils::TryParse<float>(args, forceMultiplier);
phantomPhysicsComponent->SetPhysicsEffectActive(true);
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE);
phantomPhysicsComponent->SetDirectionalMultiplier(forceMultiplier);
auto triggerPos = m_Parent->GetPosition();
auto targetPos = targetEntity->GetPosition();
// normalize the vectors to get the direction
auto delta = targetPos - triggerPos;
auto length = delta.Length();
NiPoint3 direction = delta / length;
phantomPhysicsComponent->SetDirection(direction);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void TriggerComponent::HandlePlayCinematic(Entity* targetEntity, std::vector<std::string> argArray) {
float leadIn = -1.0;
auto wait = eEndBehavior::RETURN;
bool unlock = true;
bool leaveLocked = false;
bool hidePlayer = false;
if (argArray.size() >= 2) {
GeneralUtils::TryParse<float>(argArray.at(1), leadIn);
if (argArray.size() >= 3 && argArray.at(2) == "wait") {
wait = eEndBehavior::WAIT;
if (argArray.size() >= 4 && argArray.at(3) == "unlock") {
unlock = false;
if (argArray.size() >= 5 && argArray.at(4) == "leavelocked") {
leaveLocked = true;
if (argArray.size() >= 6 && argArray.at(5) == "hideplayer") {
hidePlayer = true;
}
}
}
}
}
GameMessages::SendPlayCinematic(targetEntity->GetObjectID(), GeneralUtils::UTF8ToUTF16(argArray.at(0)), targetEntity->GetSystemAddress(), true, true, false, false, wait, hidePlayer, leadIn, leaveLocked, unlock);
}
void TriggerComponent::HandleToggleBBB(Entity* targetEntity, std::string args) {
auto* character = targetEntity->GetCharacter();
if (!character) {
Game::logger->Log("TriggerComponent::HandleToggleBBB", "Character was not found!");
return;
}
bool buildMode = !(character->GetBuildMode());
if (args == "enter") buildMode = true;
else if (args == "exit") buildMode = false;
character->SetBuildMode(buildMode);
}
void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) {
// there are only explore tasks used
// If others need to be implemented for modding
// then we need a good way to convert this from a string to that enum
if (argArray.at(0) != "exploretask") return;
MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>();
if (!missionComponent){
Game::logger->Log("TriggerComponent::HandleUpdateMission", "Mission component not found!");
return;
}
missionComponent->Progress(eMissionTaskType::EXPLORE, 0, 0, argArray.at(4));
}
void TriggerComponent::HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray) {
if (argArray.size() < 3) return;
int32_t effectID = 0;
if (!GeneralUtils::TryParse<int32_t>(argArray.at(1), effectID)) return;
std::u16string effectType = GeneralUtils::UTF8ToUTF16(argArray.at(2));
float priority = 1;
if (argArray.size() == 4) GeneralUtils::TryParse<float>(argArray.at(3), priority);
GameMessages::SendPlayFXEffect(targetEntity, effectID, effectType, argArray.at(0), LWOOBJID_EMPTY, priority);
}
void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){
auto* skillComponent = targetEntity->GetComponent<SkillComponent>();
if (!skillComponent) {
Game::logger->Log("TriggerComponent::HandleCastSkill", "Skill component not found!");
return;
}
uint32_t skillId;
GeneralUtils::TryParse<uint32_t>(args, skillId);
skillComponent->CastSkill(skillId, targetEntity->GetObjectID());
}
void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray) {
auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!");
return;
}
phantomPhysicsComponent->SetPhysicsEffectActive(true);
ePhysicsEffectType effectType = ePhysicsEffectType::PUSH;
std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase
if (argArray.at(0) == "push") effectType = ePhysicsEffectType::PUSH;
else if (argArray.at(0) == "attract") effectType = ePhysicsEffectType::ATTRACT;
else if (argArray.at(0) == "repulse") effectType = ePhysicsEffectType::REPULSE;
else if (argArray.at(0) == "gravity") effectType = ePhysicsEffectType::GRAVITY_SCALE;
else if (argArray.at(0) == "friction") effectType = ePhysicsEffectType::FRICTION;
phantomPhysicsComponent->SetEffectType(effectType);
phantomPhysicsComponent->SetDirectionalMultiplier(std::stof(argArray.at(1)));
if (argArray.size() > 4) {
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4), direction);
phantomPhysicsComponent->SetDirection(direction);
}
if (argArray.size() > 5) {
uint32_t min;
GeneralUtils::TryParse<uint32_t>(argArray.at(6), min);
phantomPhysicsComponent->SetMin(min);
uint32_t max;
GeneralUtils::TryParse<uint32_t>(argArray.at(7), max);
phantomPhysicsComponent->SetMax(max);
}
EntityManager::Instance()->SerializeEntity(targetEntity);
}
void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) {
auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
if (!phantomPhysicsComponent) {
Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!");
return;
}
phantomPhysicsComponent->SetPhysicsEffectActive(args == "On");
EntityManager::Instance()->SerializeEntity(targetEntity);
}
void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Activate();
}
}
void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Deactivate();
}
}
void TriggerComponent::HandleResetSpawnerNetwork(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Reset();
}
}
void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args){
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->DestroyAllEntities();
}
}
void TriggerComponent::HandleActivatePhysics(Entity* targetEntity, std::string args) {
if (args == "true") {
// TODO add physics entity if there isn't one
} else if (args == "false"){
// TODO remove Phsyics entity if there is one
} else {
Game::logger->LogDebug("TriggerComponent", "Invalid argument for ActivatePhysics Trigger: %s", args.c_str());
}
}

View File

@ -2,13 +2,9 @@
#define __TRIGGERCOMPONENT__H__ #define __TRIGGERCOMPONENT__H__
#include "Component.h" #include "Component.h"
#include "LUTriggers.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
namespace LUTriggers {
struct Trigger;
struct Command;
};
class TriggerComponent : public Component { class TriggerComponent : public Component {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER; static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER;
@ -17,18 +13,35 @@ public:
void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr);
LUTriggers::Trigger* GetTrigger() const { return m_Trigger; } LUTriggers::Trigger* GetTrigger() const { return m_Trigger; }
void SetTriggerEnabled(bool enabled){ m_Trigger->enabled = enabled; };
private: private:
void HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget); void HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget);
std::vector<std::string> ParseArgs(std::string args);
std::vector<Entity*> GatherTargets(LUTriggers::Command* command, Entity* optionalTarget); std::vector<Entity*> GatherTargets(LUTriggers::Command* command, Entity* optionalTarget);
// Trigger Event Handlers // Trigger Event Handlers
void HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target);
void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray);
void HandleFireEvent(Entity* targetEntity, std::string args); void HandleFireEvent(Entity* targetEntity, std::string args);
void HandleCastSkill(Entity* targetEntity, uint32_t skillID); void HandleDestroyObject(Entity* targetEntity, std::string args);
void HandleToggleTrigger(Entity* targetEntity, std::string args);
void HandleResetRebuild(Entity* targetEntity, std::string args);
void HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray);
void HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray);
void HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray);
void HandleRepelObject(Entity* targetEntity, std::string args);
void HandlePlayCinematic(Entity* targetEntity, std::vector<std::string> argArray);
void HandleToggleBBB(Entity* targetEntity, std::string args);
void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray);
void HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray);
void HandleCastSkill(Entity* targetEntity, std::string args);
void HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray);
void HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args);
void HandleActivateSpawnerNetwork(std::string args);
void HandleDeactivateSpawnerNetwork(std::string args);
void HandleResetSpawnerNetwork(std::string args);
void HandleDestroySpawnerNetworkObjects(std::string args);
void HandleActivatePhysics(Entity* targetEntity, std::string args);
LUTriggers::Trigger* m_Trigger; LUTriggers::Trigger* m_Trigger;
}; };

View File

@ -673,6 +673,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
case GAME_MSG_ACTIVATE_BUBBLE_BUFF: case GAME_MSG_ACTIVATE_BUBBLE_BUFF:
GameMessages::HandleActivateBubbleBuff(inStream, entity); GameMessages::HandleActivateBubbleBuff(inStream, entity);
break; break;
case GAME_MSG_ZONE_SUMMARY_DISMISSED:
GameMessages::HandleZoneSummaryDismissed(inStream, entity);
break;
default: default:
// Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID); // Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID);
break; break;

View File

@ -35,6 +35,7 @@
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eMissionState.h" #include "eMissionState.h"
#include "RenderComponent.h" #include "RenderComponent.h"
#include "eTriggerEventType.h"
#include <sstream> #include <sstream>
#include <future> #include <future>
@ -410,7 +411,7 @@ void GameMessages::SendServerDoneLoadingAllObjects(Entity* entity, const SystemA
SEND_PACKET; SEND_PACKET;
} }
void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level) { void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, eGameMasterLevel level) {
CBITSTREAM; CBITSTREAM;
CMSGHEADER; CMSGHEADER;
bitStream.Write(objectID); bitStream.Write(objectID);
@ -419,7 +420,7 @@ void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level) {
SEND_PACKET_BROADCAST; SEND_PACKET_BROADCAST;
} }
void GameMessages::SendGMLevelBroadcast(const LWOOBJID& objectID, uint8_t level) { void GameMessages::SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLevel level) {
CBITSTREAM; CBITSTREAM;
CMSGHEADER; CMSGHEADER;
bitStream.Write(objectID); bitStream.Write(objectID);
@ -2814,7 +2815,7 @@ void GameMessages::HandleSetConsumableItem(RakNet::BitStream* inStream, Entity*
void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr,
bool allowGhostUpdates, bool bCloseMultiInteract, bool bSendServerNotify, bool bUseControlledObjectForAudioListener, bool allowGhostUpdates, bool bCloseMultiInteract, bool bSendServerNotify, bool bUseControlledObjectForAudioListener,
int endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished, eEndBehavior endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished,
bool lockPlayer, bool result, bool skipIfSamePath, float startTimeAdvance) { bool lockPlayer, bool result, bool skipIfSamePath, float startTimeAdvance) {
CBITSTREAM; CBITSTREAM;
CMSGHEADER; CMSGHEADER;
@ -2827,8 +2828,8 @@ void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName,
bitStream.Write(bSendServerNotify); bitStream.Write(bSendServerNotify);
bitStream.Write(bUseControlledObjectForAudioListener); bitStream.Write(bUseControlledObjectForAudioListener);
bitStream.Write(endBehavior != 0); bitStream.Write(endBehavior != eEndBehavior::RETURN);
if (endBehavior != 0) bitStream.Write(endBehavior); if (endBehavior != eEndBehavior::RETURN) bitStream.Write(endBehavior);
bitStream.Write(hidePlayerDuringCine); bitStream.Write(hidePlayerDuringCine);
@ -6155,3 +6156,39 @@ void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const S
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
SEND_PACKET; SEND_PACKET;
} }
void GameMessages::HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity) {
LWOOBJID player_id;
inStream->Read<LWOOBJID>(player_id);
auto target = EntityManager::Instance()->GetEntity(player_id);
entity->TriggerEvent(eTriggerEventType::ZONE_SUMMARY_DISMISSED, target);
};
void GameMessages::SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId) {
CBITSTREAM;
CMSGHEADER;
bitStream.Write(objectId);
bitStream.Write(GAME_MSG::GAME_MSG_SET_NAME_BILLBOARD_STATE);
// Technically these bits would be written, however the client does not
// contain a deserialize method to actually deserialize, so we are leaving it out.
// As such this GM only turns the billboard off.
// bitStream.Write(overrideDefault);
// bitStream.Write(state);
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST
else SEND_PACKET
}
void GameMessages::SendShowBillboardInteractIcon(const SystemAddress& sysAddr, LWOOBJID objectId) {
CBITSTREAM;
CMSGHEADER;
bitStream.Write(objectId);
bitStream.Write(GAME_MSG::GAME_MSG_SHOW_BILLBOARD_INTERACT_ICON);
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST
else SEND_PACKET
}

View File

@ -7,6 +7,7 @@
#include <vector> #include <vector>
#include "eMovementPlatformState.h" #include "eMovementPlatformState.h"
#include "NiPoint3.h" #include "NiPoint3.h"
#include "eEndBehavior.h"
class AMFValue; class AMFValue;
class Entity; class Entity;
@ -21,6 +22,7 @@ enum class eAnimationFlags : uint32_t;
enum class eUnequippableActiveType; enum class eUnequippableActiveType;
enum eInventoryType : uint32_t; enum eInventoryType : uint32_t;
enum class eGameMasterLevel : uint8_t;
namespace GameMessages { namespace GameMessages {
class PropertyDataMessage; class PropertyDataMessage;
@ -61,8 +63,8 @@ namespace GameMessages {
void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr); void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr);
void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr); void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr);
void SendGMLevelBroadcast(const LWOOBJID& objectID, uint8_t level); void SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLevel level);
void SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level); void SendChatModeUpdate(const LWOOBJID& objectID, eGameMasterLevel level);
void SendAddItemToInventoryClientSync(Entity* entity, const SystemAddress& sysAddr, Item* item, const LWOOBJID& objectID, bool showFlyingLoot, int itemCount, LWOOBJID subKey = LWOOBJID_EMPTY, eLootSourceType lootSourceType = eLootSourceType::LOOT_SOURCE_NONE); void SendAddItemToInventoryClientSync(Entity* entity, const SystemAddress& sysAddr, Item* item, const LWOOBJID& objectID, bool showFlyingLoot, int itemCount, LWOOBJID subKey = LWOOBJID_EMPTY, eLootSourceType lootSourceType = eLootSourceType::LOOT_SOURCE_NONE);
void SendNotifyClientFlagChange(const LWOOBJID& objectID, int iFlagID, bool bFlag, const SystemAddress& sysAddr); void SendNotifyClientFlagChange(const LWOOBJID& objectID, int iFlagID, bool bFlag, const SystemAddress& sysAddr);
@ -265,7 +267,7 @@ namespace GameMessages {
void SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, void SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr,
bool allowGhostUpdates = true, bool bCloseMultiInteract = true, bool bSendServerNotify = false, bool bUseControlledObjectForAudioListener = false, bool allowGhostUpdates = true, bool bCloseMultiInteract = true, bool bSendServerNotify = false, bool bUseControlledObjectForAudioListener = false,
int endBehavior = 0, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false, eEndBehavior endBehavior = eEndBehavior::RETURN, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false,
bool lockPlayer = true, bool result = false, bool skipIfSamePath = false, float startTimeAdvance = 0); bool lockPlayer = true, bool result = false, bool skipIfSamePath = false, float startTimeAdvance = 0);
void SendEndCinematic(LWOOBJID objectID, std::u16string pathName, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS, void SendEndCinematic(LWOOBJID objectID, std::u16string pathName, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS,
@ -574,6 +576,8 @@ namespace GameMessages {
void HandleToggleGhostReferenceOverride(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleToggleGhostReferenceOverride(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr);
void HandleSetGhostReferencePosition(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleSetGhostReferencePosition(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr);
void SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId);
void SendShowBillboardInteractIcon(const SystemAddress& sysAddr, LWOOBJID objectId);
void HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr);
void HandleSellToVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleSellToVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr);
void HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr);
@ -621,7 +625,7 @@ namespace GameMessages {
void HandleReportBug(RakNet::BitStream* inStream, Entity* entity); void HandleReportBug(RakNet::BitStream* inStream, Entity* entity);
void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId); void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId);
// bubble // bubble
void HandleDeactivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity); void HandleDeactivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity);
@ -630,6 +634,8 @@ namespace GameMessages {
void SendActivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); void SendActivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr);
void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr);
void HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity);
}; };
#endif // GAMEMESSAGES_H #endif // GAMEMESSAGES_H

View File

@ -75,6 +75,7 @@
#include "eMissionState.h" #include "eMissionState.h"
#include "TriggerComponent.h" #include "TriggerComponent.h"
#include "eServerDisconnectIdentifiers.h" #include "eServerDisconnectIdentifiers.h"
#include "eGameMasterLevel.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "RenderComponent.h" #include "RenderComponent.h"
@ -122,19 +123,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
//Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"", GeneralUtils::UTF16ToWTF8(command).c_str()); //Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"", GeneralUtils::UTF16ToWTF8(command).c_str());
User* user = UserManager::Instance()->GetUser(sysAddr); User* user = UserManager::Instance()->GetUser(sysAddr);
if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > eGameMasterLevel::CIVILIAN) {
if (args.size() != 1) return; if (args.size() != 1) return;
uint32_t level; uint32_t level_intermed = 0;
if (!GeneralUtils::TryParse(args[0], level)) { if (!GeneralUtils::TryParse(args[0], level_intermed)) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid gm level."); ChatPackets::SendSystemMessage(sysAddr, u"Invalid gm level.");
return; return;
} }
eGameMasterLevel level = static_cast<eGameMasterLevel>(level_intermed);
#ifndef DEVELOPER_SERVER #ifndef DEVELOPER_SERVER
if (user->GetMaxGMLevel() == GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { if (user->GetMaxGMLevel() == eGameMasterLevel::JUNIOR_DEVELOPER) {
level = GAME_MASTER_LEVEL_CIVILIAN; level = eGameMasterLevel::CIVILIAN;
} }
#endif #endif
@ -147,9 +149,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (success) { if (success) {
if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && level == GAME_MASTER_LEVEL_CIVILIAN) { if (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN && level == eGameMasterLevel::CIVILIAN) {
GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS);
} else if (entity->GetGMLevel() == GAME_MASTER_LEVEL_CIVILIAN && level > GAME_MASTER_LEVEL_CIVILIAN) { } else if (entity->GetGMLevel() == eGameMasterLevel::CIVILIAN && level > eGameMasterLevel::CIVILIAN) {
GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS);
} }
@ -161,10 +163,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
#ifndef DEVELOPER_SERVER #ifndef DEVELOPER_SERVER
if ((entity->GetGMLevel() > user->GetMaxGMLevel()) || (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && user->GetMaxGMLevel() == GAME_MASTER_LEVEL_JUNIOR_DEVELOPER)) { if ((entity->GetGMLevel() > user->GetMaxGMLevel()) || (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN && user->GetMaxGMLevel() == eGameMasterLevel::JUNIOR_DEVELOPER)) {
WorldPackets::SendGMLevelChange(sysAddr, true, user->GetMaxGMLevel(), entity->GetGMLevel(), GAME_MASTER_LEVEL_CIVILIAN); WorldPackets::SendGMLevelChange(sysAddr, true, user->GetMaxGMLevel(), entity->GetGMLevel(), eGameMasterLevel::CIVILIAN);
GameMessages::SendChatModeUpdate(entity->GetObjectID(), GAME_MASTER_LEVEL_CIVILIAN); GameMessages::SendChatModeUpdate(entity->GetObjectID(), eGameMasterLevel::CIVILIAN);
entity->SetGMLevel(GAME_MASTER_LEVEL_CIVILIAN); entity->SetGMLevel(eGameMasterLevel::CIVILIAN);
GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS);
@ -172,6 +174,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
#endif #endif
if (chatCommand == "togglenameplate" && (Game::config->GetValue("allownameplateoff") == "1" || entity->GetGMLevel() > eGameMasterLevel::DEVELOPER)) {
auto* character = entity->GetCharacter();
if (character && character->GetBillboardVisible()) {
character->SetBillboardVisible(false);
ChatPackets::SendSystemMessage(sysAddr, u"Your nameplate has been turned off and is not visible to players currently in this zone.");
} else {
character->SetBillboardVisible(true);
ChatPackets::SendSystemMessage(sysAddr, u"Your nameplate is now on and visible to all players.");
}
return;
}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//HANDLE ALL NON GM SLASH COMMANDS RIGHT HERE! //HANDLE ALL NON GM SLASH COMMANDS RIGHT HERE!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ -337,7 +352,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}); });
} }
if (user->GetMaxGMLevel() == 0 || entity->GetGMLevel() >= 0) { if (user->GetMaxGMLevel() == eGameMasterLevel::CIVILIAN || entity->GetGMLevel() >= eGameMasterLevel::CIVILIAN) {
if (chatCommand == "die") { if (chatCommand == "die") {
entity->Smash(entity->GetObjectID()); entity->Smash(entity->GetObjectID());
} }
@ -363,7 +378,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Map: " + (GeneralUtils::to_u16string(zoneId.GetMapID())) + u"\nClone: " + (GeneralUtils::to_u16string(zoneId.GetCloneID())) + u"\nInstance: " + (GeneralUtils::to_u16string(zoneId.GetInstanceID()))); ChatPackets::SendSystemMessage(sysAddr, u"Map: " + (GeneralUtils::to_u16string(zoneId.GetMapID())) + u"\nClone: " + (GeneralUtils::to_u16string(zoneId.GetCloneID())) + u"\nInstance: " + (GeneralUtils::to_u16string(zoneId.GetInstanceID())));
} }
if (entity->GetGMLevel() == 0) return; if (entity->GetGMLevel() == eGameMasterLevel::CIVILIAN) return;
} }
// Log command to database // Log command to database
@ -373,7 +388,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
stmt->execute(); stmt->execute();
delete stmt; delete stmt;
if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0 if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) { // could break characters so only allow if GM > 0
int32_t minifigItemId; int32_t minifigItemId;
if (!GeneralUtils::TryParse(args[1], minifigItemId)) { if (!GeneralUtils::TryParse(args[1], minifigItemId)) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID."); ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID.");
@ -417,7 +432,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character
} }
if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
std::u16string anim = GeneralUtils::ASCIIToUTF16(args[0], args[0].size()); std::u16string anim = GeneralUtils::ASCIIToUTF16(args[0], args[0].size());
RenderComponent::PlayAnimation(entity, anim); RenderComponent::PlayAnimation(entity, anim);
auto* possessorComponent = entity->GetComponent<PossessorComponent>(); auto* possessorComponent = entity->GetComponent<PossessorComponent>();
@ -427,7 +442,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "list-spawns" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "list-spawns" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) { for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) {
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first)); ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first));
} }
@ -437,7 +452,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
int32_t emoteID; int32_t emoteID;
if (!GeneralUtils::TryParse(args[0], emoteID)) { if (!GeneralUtils::TryParse(args[0], emoteID)) {
@ -448,11 +463,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
entity->GetCharacter()->UnlockEmote(emoteID); entity->GetCharacter()->UnlockEmote(emoteID);
} }
if (chatCommand == "force-save" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "force-save" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
entity->GetCharacter()->SaveXMLToDatabase(); entity->GetCharacter()->SaveXMLToDatabase();
} }
if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
ChatPackets::SendSystemMessage(sysAddr, u"Brutally murdering that player, if online on this server."); ChatPackets::SendSystemMessage(sysAddr, u"Brutally murdering that player, if online on this server.");
auto* user = UserManager::Instance()->GetUser(args[0]); auto* user = UserManager::Instance()->GetUser(args[0]);
@ -467,7 +482,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
float boost; float boost;
if (!GeneralUtils::TryParse(args[0], boost)) { if (!GeneralUtils::TryParse(args[0], boost)) {
@ -498,7 +513,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
EntityManager::Instance()->SerializeEntity(entity); EntityManager::Instance()->SerializeEntity(entity);
} }
if (chatCommand == "freecam" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "freecam" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
const auto state = !entity->GetVar<bool>(u"freecam"); const auto state = !entity->GetVar<bool>(u"freecam");
entity->SetVar<bool>(u"freecam", state); entity->SetVar<bool>(u"freecam", state);
@ -508,7 +523,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "setcontrolscheme" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "setcontrolscheme" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
uint32_t scheme; uint32_t scheme;
if (!GeneralUtils::TryParse(args[0], scheme)) { if (!GeneralUtils::TryParse(args[0], scheme)) {
@ -522,7 +537,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "approveproperty" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_LEAD_MODERATOR) { if (chatCommand == "approveproperty" && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) {
if (PropertyManagementComponent::Instance() != nullptr) { if (PropertyManagementComponent::Instance() != nullptr) {
PropertyManagementComponent::Instance()->UpdateApprovedStatus(true); PropertyManagementComponent::Instance()->UpdateApprovedStatus(true);
@ -531,7 +546,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
AMFStringValue* value = new AMFStringValue(); AMFStringValue* value = new AMFStringValue();
value->SetStringValue(args[0]); value->SetStringValue(args[0]);
@ -544,7 +559,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
AMFTrueValue* value = new AMFTrueValue(); AMFTrueValue* value = new AMFTrueValue();
AMFArrayValue amfArgs; AMFArrayValue amfArgs;
@ -556,7 +571,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
uint32_t size; uint32_t size;
if (!GeneralUtils::TryParse(args.at(0), size)) { if (!GeneralUtils::TryParse(args.at(0), size)) {
@ -597,7 +612,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "runmacro" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "runmacro" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() != 1) return; if (args.size() != 1) return;
// Only process if input does not contain separator charaters // Only process if input does not contain separator charaters
@ -627,7 +642,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "addmission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "addmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 0) return; if (args.size() == 0) return;
uint32_t missionID; uint32_t missionID;
@ -642,7 +657,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "completemission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "completemission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 0) return; if (args.size() == 0) return;
uint32_t missionID; uint32_t missionID;
@ -657,7 +672,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "setflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) {
uint32_t flagId; uint32_t flagId;
if (!GeneralUtils::TryParse(args[0], flagId)) { if (!GeneralUtils::TryParse(args[0], flagId)) {
@ -668,7 +683,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
entity->GetCharacter()->SetPlayerFlag(flagId, true); entity->GetCharacter()->SetPlayerFlag(flagId, true);
} }
if (chatCommand == "setflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 2) { if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 2) {
uint32_t flagId; uint32_t flagId;
std::string onOffFlag = args[0]; std::string onOffFlag = args[0];
if (!GeneralUtils::TryParse(args[1], flagId)) { if (!GeneralUtils::TryParse(args[1], flagId)) {
@ -681,7 +696,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
entity->GetCharacter()->SetPlayerFlag(flagId, onOffFlag == "on"); entity->GetCharacter()->SetPlayerFlag(flagId, onOffFlag == "on");
} }
if (chatCommand == "clearflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { if (chatCommand == "clearflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) {
uint32_t flagId; uint32_t flagId;
if (!GeneralUtils::TryParse(args[0], flagId)) { if (!GeneralUtils::TryParse(args[0], flagId)) {
@ -692,7 +707,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
entity->GetCharacter()->SetPlayerFlag(flagId, false); entity->GetCharacter()->SetPlayerFlag(flagId, false);
} }
if (chatCommand == "resetmission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 0) return; if (args.size() == 0) return;
uint32_t missionID; uint32_t missionID;
@ -719,7 +734,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "playeffect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) {
int32_t effectID = 0; int32_t effectID = 0;
if (!GeneralUtils::TryParse(args[0], effectID)) { if (!GeneralUtils::TryParse(args[0], effectID)) {
@ -730,11 +745,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendPlayFXEffect(entity->GetObjectID(), effectID, GeneralUtils::ASCIIToUTF16(args[1]), args[2]); GameMessages::SendPlayFXEffect(entity->GetObjectID(), effectID, GeneralUtils::ASCIIToUTF16(args[1]), args[2]);
} }
if (chatCommand == "stopeffect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if (chatCommand == "stopeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
GameMessages::SendStopFXEffect(entity, true, args[0]); GameMessages::SendStopFXEffect(entity, true, args[0]);
} }
if (chatCommand == "setanntitle" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "setanntitle" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() < 0) return; if (args.size() < 0) return;
std::stringstream ss; std::stringstream ss;
@ -745,7 +760,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "setannmsg" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "setannmsg" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() < 0) return; if (args.size() < 0) return;
std::stringstream ss; std::stringstream ss;
@ -756,7 +771,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "announce" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "announce" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (entity->GetCharacter()->GetAnnouncementTitle().size() == 0 || entity->GetCharacter()->GetAnnouncementMessage().size() == 0) { if (entity->GetCharacter()->GetAnnouncementTitle().size() == 0 || entity->GetCharacter()->GetAnnouncementMessage().size() == 0) {
ChatPackets::SendSystemMessage(sysAddr, u"Use /setanntitle <title> & /setannmsg <msg> first!"); ChatPackets::SendSystemMessage(sysAddr, u"Use /setanntitle <title> & /setannmsg <msg> first!");
return; return;
@ -766,7 +781,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == GAME_MASTER_LEVEL_OPERATOR) { if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == eGameMasterLevel::OPERATOR) {
//Tell the master server that we're going to be shutting down whole "universe": //Tell the master server that we're going to be shutting down whole "universe":
CBITSTREAM; CBITSTREAM;
PacketUtils::WriteHeader(bitStream, MASTER, MSG_MASTER_SHUTDOWN_UNIVERSE); PacketUtils::WriteHeader(bitStream, MASTER, MSG_MASTER_SHUTDOWN_UNIVERSE);
@ -778,7 +793,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "getnavmeshheight" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "getnavmeshheight" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto control = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); auto control = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS));
if (!control) return; if (!control) return;
@ -787,7 +802,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, msg); ChatPackets::SendSystemMessage(sysAddr, msg);
} }
if (chatCommand == "gmadditem" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "gmadditem" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 1) { if (args.size() == 1) {
uint32_t itemLOT; uint32_t itemLOT;
@ -822,7 +837,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "mailitem" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_MODERATOR && args.size() >= 2) { if (chatCommand == "mailitem" && entity->GetGMLevel() >= eGameMasterLevel::MODERATOR && args.size() >= 2) {
const auto& playerName = args[0]; const auto& playerName = args[0];
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT id from charinfo WHERE name=? LIMIT 1;"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT id from charinfo WHERE name=? LIMIT 1;");
@ -871,7 +886,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "setname" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "setname" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
std::string name = ""; std::string name = "";
for (const auto& arg : args) { for (const auto& arg : args) {
@ -881,7 +896,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS);
} }
if (chatCommand == "title" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "title" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
std::string name = entity->GetCharacter()->GetName() + " - "; std::string name = entity->GetCharacter()->GetName() + " - ";
for (const auto& arg : args) { for (const auto& arg : args) {
@ -891,7 +906,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS);
} }
if ((chatCommand == "teleport" || chatCommand == "tele") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_MODERATOR) { if ((chatCommand == "teleport" || chatCommand == "tele") && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_MODERATOR) {
NiPoint3 pos{}; NiPoint3 pos{};
if (args.size() == 3) { if (args.size() == 3) {
@ -957,7 +972,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "tpall" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "tpall" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
const auto pos = entity->GetPosition(); const auto pos = entity->GetPosition();
const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
@ -969,7 +984,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "dismount" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "dismount" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto* possessorComponent = entity->GetComponent<PossessorComponent>(); auto* possessorComponent = entity->GetComponent<PossessorComponent>();
if (possessorComponent) { if (possessorComponent) {
auto possessableId = possessorComponent->GetPossessable(); auto possessableId = possessorComponent->GetPossessable();
@ -980,7 +995,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "fly" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { if (chatCommand == "fly" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) {
auto* character = entity->GetCharacter(); auto* character = entity->GetCharacter();
if (character) { if (character) {
@ -1016,7 +1031,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
//------- GM COMMANDS TO ACTUALLY MODERATE -------- //------- GM COMMANDS TO ACTUALLY MODERATE --------
if (chatCommand == "mute" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { if (chatCommand == "mute" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) {
if (args.size() >= 1) { if (args.size() >= 1) {
auto* player = Player::GetPlayer(args[0]); auto* player = Player::GetPlayer(args[0]);
@ -1111,7 +1126,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "kick" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_MODERATOR) { if (chatCommand == "kick" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_MODERATOR) {
if (args.size() == 1) { if (args.size() == 1) {
auto* player = Player::GetPlayer(args[0]); auto* player = Player::GetPlayer(args[0]);
@ -1129,7 +1144,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "ban" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_SENIOR_MODERATOR) { if (chatCommand == "ban" && entity->GetGMLevel() >= eGameMasterLevel::SENIOR_MODERATOR) {
if (args.size() == 1) { if (args.size() == 1) {
auto* player = Player::GetPlayer(args[0]); auto* player = Player::GetPlayer(args[0]);
@ -1178,7 +1193,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
//------------------------------------------------- //-------------------------------------------------
if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "buffme" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE));
if (dest) { if (dest) {
dest->SetHealth(999); dest->SetHealth(999);
@ -1191,7 +1206,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
EntityManager::Instance()->SerializeEntity(entity); EntityManager::Instance()->SerializeEntity(entity);
} }
if (chatCommand == "startcelebration" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { if (chatCommand == "startcelebration" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) {
int32_t celebration; int32_t celebration;
if (!GeneralUtils::TryParse(args[0], celebration)) { if (!GeneralUtils::TryParse(args[0], celebration)) {
@ -1202,7 +1217,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration); GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration);
} }
if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "buffmed" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE));
if (dest) { if (dest) {
dest->SetHealth(9); dest->SetHealth(9);
@ -1215,7 +1230,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
EntityManager::Instance()->SerializeEntity(entity); EntityManager::Instance()->SerializeEntity(entity);
} }
if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "refillstats" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE));
if (dest) { if (dest) {
@ -1227,7 +1242,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
EntityManager::Instance()->SerializeEntity(entity); EntityManager::Instance()->SerializeEntity(entity);
} }
if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if (chatCommand == "lookup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
auto query = CDClientDatabase::CreatePreppedStmt( auto query = CDClientDatabase::CreatePreppedStmt(
"SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50");
// Concatenate all of the arguments into a single query so a multi word query can be used properly. // Concatenate all of the arguments into a single query so a multi word query can be used properly.
@ -1249,7 +1264,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if (chatCommand == "spawn" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS));
if (!comp) return; if (!comp) return;
@ -1290,7 +1305,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
EntityManager::Instance()->ConstructEntity(newEntity); EntityManager::Instance()->ConstructEntity(newEntity);
} }
if (chatCommand == "spawngroup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { if (chatCommand == "spawngroup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) {
auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>(); auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return; if (!controllablePhysicsComponent) return;
@ -1341,7 +1356,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
int32_t uscore; int32_t uscore;
if (!GeneralUtils::TryParse(args[0], uscore)) { if (!GeneralUtils::TryParse(args[0], uscore)) {
@ -1363,7 +1378,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType); GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType);
} }
if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
// We may be trying to set a specific players level to a level. If so override the entity with the requested players. // We may be trying to set a specific players level to a level. If so override the entity with the requested players.
std::string requestedPlayerToSetLevelOf = ""; std::string requestedPlayerToSetLevelOf = "";
if (args.size() > 1) { if (args.size() > 1) {
@ -1431,7 +1446,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "pos" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "pos" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
const auto position = entity->GetPosition(); const auto position = entity->GetPosition();
ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(position.x)) + u", " + (GeneralUtils::to_u16string(position.y)) + u", " + (GeneralUtils::to_u16string(position.z)) + u">"); ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(position.x)) + u", " + (GeneralUtils::to_u16string(position.y)) + u", " + (GeneralUtils::to_u16string(position.z)) + u">");
@ -1439,7 +1454,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
std::cout << position.x << ", " << position.y << ", " << position.z << std::endl; std::cout << position.x << ", " << position.y << ", " << position.z << std::endl;
} }
if (chatCommand == "rot" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "rot" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
const auto rotation = entity->GetRotation(); const auto rotation = entity->GetRotation();
ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(rotation.w)) + u", " + (GeneralUtils::to_u16string(rotation.x)) + u", " + (GeneralUtils::to_u16string(rotation.y)) + u", " + (GeneralUtils::to_u16string(rotation.z)) + u">"); ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(rotation.w)) + u", " + (GeneralUtils::to_u16string(rotation.x)) + u", " + (GeneralUtils::to_u16string(rotation.y)) + u", " + (GeneralUtils::to_u16string(rotation.z)) + u">");
@ -1447,22 +1462,22 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
std::cout << rotation.w << ", " << rotation.x << ", " << rotation.y << ", " << rotation.z << std::endl; std::cout << rotation.w << ", " << rotation.x << ", " << rotation.y << ", " << rotation.z << std::endl;
} }
if (chatCommand == "locrow" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "locrow" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
const auto position = entity->GetPosition(); const auto position = entity->GetPosition();
const auto rotation = entity->GetRotation(); const auto rotation = entity->GetRotation();
std::cout << "<location x=\"" << position.x << "\" y=\"" << position.y << "\" z=\"" << position.z << "\" rw=\"" << rotation.w << "\" rx=\"" << rotation.x << "\" ry=\"" << rotation.y << "\" rz=\"" << rotation.z << "\" />" << std::endl; std::cout << "<location x=\"" << position.x << "\" y=\"" << position.y << "\" z=\"" << position.z << "\" rw=\"" << rotation.w << "\" rx=\"" << rotation.x << "\" ry=\"" << rotation.y << "\" rz=\"" << rotation.z << "\" />" << std::endl;
} }
if (chatCommand == "playlvlfx" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "playlvlfx" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
GameMessages::SendPlayFXEffect(entity, 7074, u"create", "7074", LWOOBJID_EMPTY, 1.0f, 1.0f, true); GameMessages::SendPlayFXEffect(entity, 7074, u"create", "7074", LWOOBJID_EMPTY, 1.0f, 1.0f, true);
} }
if (chatCommand == "playrebuildfx" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "playrebuildfx" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
GameMessages::SendPlayFXEffect(entity, 230, u"rebuild", "230", LWOOBJID_EMPTY, 1.0f, 1.0f, true); GameMessages::SendPlayFXEffect(entity, 230, u"rebuild", "230", LWOOBJID_EMPTY, 1.0f, 1.0f, true);
} }
if ((chatCommand == "freemoney" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) && args.size() == 1) { if ((chatCommand == "freemoney" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) && args.size() == 1) {
int32_t money; int32_t money;
if (!GeneralUtils::TryParse(args[0], money)) { if (!GeneralUtils::TryParse(args[0], money)) {
@ -1474,7 +1489,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ch->SetCoins(ch->GetCoins() + money, eLootSourceType::LOOT_SOURCE_MODERATION); ch->SetCoins(ch->GetCoins() + money, eLootSourceType::LOOT_SOURCE_MODERATION);
} }
if ((chatCommand == "setcurrency") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if ((chatCommand == "setcurrency") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
int32_t money; int32_t money;
if (!GeneralUtils::TryParse(args[0], money)) { if (!GeneralUtils::TryParse(args[0], money)) {
@ -1487,13 +1502,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
// Allow for this on even while not a GM, as it sometimes toggles incorrrectly. // Allow for this on even while not a GM, as it sometimes toggles incorrrectly.
if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= eGameMasterLevel::DEVELOPER) {
GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS);
return; return;
} }
if (chatCommand == "gmimmune" && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "gmimmune" && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>(); auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
int32_t state = false; int32_t state = false;
@ -1510,7 +1525,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "buff" && args.size() >= 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "buff" && args.size() >= 2 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto* buffComponent = entity->GetComponent<BuffComponent>(); auto* buffComponent = entity->GetComponent<BuffComponent>();
int32_t id = 0; int32_t id = 0;
@ -1533,7 +1548,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if ((chatCommand == "testmap" && args.size() >= 1) && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { if ((chatCommand == "testmap" && args.size() >= 1) && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) {
ChatPackets::SendSystemMessage(sysAddr, u"Requesting map change..."); ChatPackets::SendSystemMessage(sysAddr, u"Requesting map change...");
uint32_t reqZone; uint32_t reqZone;
LWOCLONEID cloneId = 0; LWOCLONEID cloneId = 0;
@ -1592,7 +1607,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "createprivate" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { if (chatCommand == "createprivate" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) {
uint32_t zone; uint32_t zone;
if (!GeneralUtils::TryParse(args[0], zone)) { if (!GeneralUtils::TryParse(args[0], zone)) {
@ -1616,13 +1631,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if ((chatCommand == "debugui") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if ((chatCommand == "debugui") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
ChatPackets::SendSystemMessage(sysAddr, u"Opening UIDebugger..."); ChatPackets::SendSystemMessage(sysAddr, u"Opening UIDebugger...");
AMFArrayValue args; AMFArrayValue args;
GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", nullptr); GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", nullptr);
} }
if ((chatCommand == "boost") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if ((chatCommand == "boost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto* possessorComponent = entity->GetComponent<PossessorComponent>(); auto* possessorComponent = entity->GetComponent<PossessorComponent>();
if (possessorComponent == nullptr) { if (possessorComponent == nullptr) {
@ -1654,7 +1669,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
if ((chatCommand == "unboost") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if ((chatCommand == "unboost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
auto* possessorComponent = entity->GetComponent<PossessorComponent>(); auto* possessorComponent = entity->GetComponent<PossessorComponent>();
if (possessorComponent == nullptr) return; if (possessorComponent == nullptr) return;
@ -1664,7 +1679,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendVehicleRemovePassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendVehicleRemovePassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
} }
if (chatCommand == "activatespawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if (chatCommand == "activatespawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]);
for (auto* spawner : spawners) { for (auto* spawner : spawners) {
@ -1678,7 +1693,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= 6) { if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) {
//Go tell physics to spawn all the vertices: //Go tell physics to spawn all the vertices:
auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS); auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS);
for (auto en : entities) { for (auto en : entities) {
@ -1688,7 +1703,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= 6) { if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) {
auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR); auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR);
for (auto en : entities) { for (auto en : entities) {
auto phys = static_cast<ProximityMonitorComponent*>(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR)); auto phys = static_cast<ProximityMonitorComponent*>(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR));
@ -1704,7 +1719,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]);
for (auto* spawner : spawners) { for (auto* spawner : spawners) {
@ -1718,7 +1733,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
} }
} }
if (chatCommand == "reforge" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 2) { if (chatCommand == "reforge" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 2) {
LOT baseItem; LOT baseItem;
LOT reforgedItem; LOT reforgedItem;
@ -1735,7 +1750,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
inventoryComponent->AddItem(baseItem, 1, eLootSourceType::LOOT_SOURCE_MODERATION, eInventoryType::INVALID, data); inventoryComponent->AddItem(baseItem, 1, eLootSourceType::LOOT_SOURCE_MODERATION, eInventoryType::INVALID, data);
} }
if (chatCommand == "crash" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR) { if (chatCommand == "crash" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR) {
ChatPackets::SendSystemMessage(sysAddr, u"Crashing..."); ChatPackets::SendSystemMessage(sysAddr, u"Crashing...");
int* badPtr = nullptr; int* badPtr = nullptr;
@ -1744,7 +1759,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "metrics" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "metrics" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
for (const auto variable : Metrics::GetAllMetrics()) { for (const auto variable : Metrics::GetAllMetrics()) {
auto* metric = Metrics::GetMetric(variable); auto* metric = Metrics::GetMetric(variable);
@ -1781,7 +1796,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
Game::config->ReloadConfig(); Game::config->ReloadConfig();
VanityUtilities::SpawnVanity(); VanityUtilities::SpawnVanity();
dpWorld::Instance().Reload(); dpWorld::Instance().Reload();
@ -1797,7 +1812,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!"); ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!");
} }
if (chatCommand == "rollloot" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR && args.size() >= 3) { if (chatCommand == "rollloot" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR && args.size() >= 3) {
uint32_t lootMatrixIndex = 0; uint32_t lootMatrixIndex = 0;
uint32_t targetLot = 0; uint32_t targetLot = 0;
uint32_t loops = 1; uint32_t loops = 1;
@ -1834,7 +1849,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, message); ChatPackets::SendSystemMessage(sysAddr, message);
} }
if (chatCommand == "deleteinven" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if (chatCommand == "deleteinven" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
eInventoryType inventoryType = eInventoryType::INVALID; eInventoryType inventoryType = eInventoryType::INVALID;
if (!GeneralUtils::TryParse(args[0], inventoryType)) { if (!GeneralUtils::TryParse(args[0], inventoryType)) {
// In this case, we treat the input as a string and try to find it in the reflection list // In this case, we treat the input as a string and try to find it in the reflection list
@ -1861,7 +1876,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Deleted inventory " + GeneralUtils::UTF8ToUTF16(args[0])); ChatPackets::SendSystemMessage(sysAddr, u"Deleted inventory " + GeneralUtils::UTF8ToUTF16(args[0]));
} }
if (chatCommand == "inspect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { if (chatCommand == "inspect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
Entity* closest = nullptr; Entity* closest = nullptr;
eReplicaComponentType component; eReplicaComponentType component;
@ -2004,7 +2019,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto* phantomPhysicsComponent = closest->GetComponent<PhantomPhysicsComponent>(); auto* phantomPhysicsComponent = closest->GetComponent<PhantomPhysicsComponent>();
if (phantomPhysicsComponent != nullptr) { if (phantomPhysicsComponent != nullptr) {
ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetEffectType()))); ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(static_cast<uint32_t>(phantomPhysicsComponent->GetEffectType()))));
const auto dir = phantomPhysicsComponent->GetDirection(); const auto dir = phantomPhysicsComponent->GetDirection();
ChatPackets::SendSystemMessage(sysAddr, u"Direction: <" + (GeneralUtils::to_u16string(dir.x)) + u", " + (GeneralUtils::to_u16string(dir.y)) + u", " + (GeneralUtils::to_u16string(dir.z)) + u">"); ChatPackets::SendSystemMessage(sysAddr, u"Direction: <" + (GeneralUtils::to_u16string(dir.x)) + u", " + (GeneralUtils::to_u16string(dir.y)) + u", " + (GeneralUtils::to_u16string(dir.z)) + u">");
ChatPackets::SendSystemMessage(sysAddr, u"Multiplier: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetDirectionalMultiplier()))); ChatPackets::SendSystemMessage(sysAddr, u"Multiplier: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetDirectionalMultiplier())));

View File

@ -32,6 +32,7 @@
#include "CharacterComponent.h" #include "CharacterComponent.h"
#include "Database.h" #include "Database.h"
#include "dMessageIdentifiers.h" #include "dMessageIdentifiers.h"
#include "eGameMasterLevel.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) { void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) {
@ -66,7 +67,7 @@ void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* pack
} }
std::string playerName = user->GetLastUsedChar()->GetName(); std::string playerName = user->GetLastUsedChar()->GetName();
bool isMythran = user->GetLastUsedChar()->GetGMLevel() > 0; bool isMythran = user->GetLastUsedChar()->GetGMLevel() > eGameMasterLevel::CIVILIAN;
if (!user->GetLastChatMessageApproved() && !isMythran) return; if (!user->GetLastChatMessageApproved() && !isMythran) return;

View File

@ -15,6 +15,7 @@
#include "CharacterComponent.h" #include "CharacterComponent.h"
#include "ZCompression.h" #include "ZCompression.h"
void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) { void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) {
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_LOAD_STATIC_ZONE); PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_LOAD_STATIC_ZONE);
@ -127,7 +128,7 @@ void WorldPackets::SendServerState(const SystemAddress& sysAddr) {
SEND_PACKET; SEND_PACKET;
} }
void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm) { void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) {
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_CREATE_CHARACTER); PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_CREATE_CHARACTER);
@ -144,8 +145,8 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent
LDFData<LOT>* lot = new LDFData<LOT>(u"template", 1); LDFData<LOT>* lot = new LDFData<LOT>(u"template", 1);
LDFData<std::string>* xmlConfigData = new LDFData<std::string>(u"xmlData", xmlData); LDFData<std::string>* xmlConfigData = new LDFData<std::string>(u"xmlData", xmlData);
LDFData<std::u16string>* name = new LDFData<std::u16string>(u"name", username); LDFData<std::u16string>* name = new LDFData<std::u16string>(u"name", username);
LDFData<int32_t>* gmlevel = new LDFData<int32_t>(u"gmlevel", gm); LDFData<int32_t>* gmlevel = new LDFData<int32_t>(u"gmlevel", static_cast<int32_t>(gm));
LDFData<int32_t>* chatmode = new LDFData<int32_t>(u"chatmode", gm); LDFData<int32_t>* chatmode = new LDFData<int32_t>(u"chatmode", static_cast<int32_t>(gm));
LDFData<int64_t>* reputation = new LDFData<int64_t>(u"reputation", character->GetReputation()); LDFData<int64_t>* reputation = new LDFData<int64_t>(u"reputation", character->GetReputation());
objid->WriteToPacket(&data); objid->WriteToPacket(&data);
@ -220,14 +221,14 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool
SEND_PACKET; SEND_PACKET;
} }
void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, uint8_t highestLevel, uint8_t prevLevel, uint8_t newLevel) { void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel) {
CBITSTREAM; CBITSTREAM;
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAKE_GM_RESPONSE); PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAKE_GM_RESPONSE);
bitStream.Write<uint8_t>(success); bitStream.Write<uint8_t>(success);
bitStream.Write<uint16_t>(highestLevel); bitStream.Write(static_cast<uint16_t>(highestLevel));
bitStream.Write<uint16_t>(prevLevel); bitStream.Write(static_cast<uint16_t>(prevLevel));
bitStream.Write<uint16_t>(newLevel); bitStream.Write(static_cast<uint16_t>(newLevel));
SEND_PACKET; SEND_PACKET;
} }

View File

@ -8,6 +8,7 @@
class User; class User;
struct SystemAddress; struct SystemAddress;
enum class eGameMasterLevel : uint8_t;
namespace WorldPackets { namespace WorldPackets {
void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum); void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum);
@ -17,9 +18,9 @@ namespace WorldPackets {
void SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response); void SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response);
void SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift); void SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift);
void SendServerState(const SystemAddress& sysAddr); void SendServerState(const SystemAddress& sysAddr);
void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm); void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm);
void SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems); void SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems);
void SendGMLevelChange(const SystemAddress& sysAddr, bool success, uint8_t highestLevel, uint8_t prevLevel, uint8_t newLevel); void SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel);
} }
#endif // WORLDPACKETS_H #endif // WORLDPACKETS_H

View File

@ -5,13 +5,14 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "AgMonumentLaserServer.h" #include "AgMonumentLaserServer.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "ePhysicsEffectType.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
void AgLaserSensorServer::OnStartup(Entity* self) { void AgLaserSensorServer::OnStartup(Entity* self) {
PhantomPhysicsComponent* physComp = static_cast<PhantomPhysicsComponent*>(self->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); PhantomPhysicsComponent* physComp = static_cast<PhantomPhysicsComponent*>(self->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS));
physComp->SetPhysicsEffectActive(true); physComp->SetPhysicsEffectActive(true);
physComp->SetEffectType(2); // repulse (prolly should make definitions of these are in Entity.cpp) physComp->SetEffectType(ePhysicsEffectType::REPULSE);
physComp->SetDirectionalMultiplier(static_cast<float>(m_RepelForce)); physComp->SetDirectionalMultiplier(static_cast<float>(m_RepelForce));
physComp->SetDirection(NiPoint3::UNIT_Y); physComp->SetDirection(NiPoint3::UNIT_Y);

View File

@ -2,6 +2,7 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "Preconditions.h" #include "Preconditions.h"
#include "eEndBehavior.h"
#include "DestroyableComponent.h" #include "DestroyableComponent.h"
#ifdef _WIN32 #ifdef _WIN32
@ -53,7 +54,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) {
if (!cinematic.empty()) { if (!cinematic.empty()) {
GameMessages::SendPlayCinematic(playerId, GeneralUtils::ASCIIToUTF16(cinematic), player->GetSystemAddress(), GameMessages::SendPlayCinematic(playerId, GeneralUtils::ASCIIToUTF16(cinematic), player->GetSystemAddress(),
true, true, false, false, 0, false, leanIn true, true, false, false, eEndBehavior::RETURN, false, leanIn
); );
} }

View File

@ -1,6 +1,7 @@
#include "ForceVolumeServer.h" #include "ForceVolumeServer.h"
#include "PhantomPhysicsComponent.h" #include "PhantomPhysicsComponent.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "ePhysicsEffectType.h"
void ForceVolumeServer::OnStartup(Entity* self) { void ForceVolumeServer::OnStartup(Entity* self) {
auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>();
@ -12,7 +13,7 @@ void ForceVolumeServer::OnStartup(Entity* self) {
const auto forceY = self->GetVar<float>(u"ForceY"); const auto forceY = self->GetVar<float>(u"ForceY");
const auto forceZ = self->GetVar<float>(u"ForceZ"); const auto forceZ = self->GetVar<float>(u"ForceZ");
phantomPhysicsComponent->SetEffectType(0); // PUSH phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH);
phantomPhysicsComponent->SetDirectionalMultiplier(forceAmount); phantomPhysicsComponent->SetDirectionalMultiplier(forceAmount);
phantomPhysicsComponent->SetDirection({ forceX, forceY, forceZ }); phantomPhysicsComponent->SetDirection({ forceX, forceY, forceZ });
phantomPhysicsComponent->SetPhysicsEffectActive(true); phantomPhysicsComponent->SetPhysicsEffectActive(true);

View File

@ -5,6 +5,7 @@
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eMissionState.h" #include "eMissionState.h"
#include "RenderComponent.h" #include "RenderComponent.h"
#include "eEndBehavior.h"
void NtAssemblyTubeServer::OnStartup(Entity* self) { void NtAssemblyTubeServer::OnStartup(Entity* self) {
self->SetProximityRadius(5, "teleport"); self->SetProximityRadius(5, "teleport");
@ -46,7 +47,7 @@ void NtAssemblyTubeServer::RunAssemblyTube(Entity* self, Entity* player) {
if (!teleCinematic.empty()) { if (!teleCinematic.empty()) {
const auto teleCinematicUname = teleCinematic; const auto teleCinematicUname = teleCinematic;
GameMessages::SendPlayCinematic(player->GetObjectID(), teleCinematicUname, player->GetSystemAddress(), GameMessages::SendPlayCinematic(player->GetObjectID(), teleCinematicUname, player->GetSystemAddress(),
true, true, true, false, 0, false, -1, false, true true, true, true, false, eEndBehavior::RETURN, false, -1, false, true
); );
} }

View File

@ -3,6 +3,7 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "ePhysicsEffectType.h"
void NtSentinelWalkwayServer::OnStartup(Entity* self) { void NtSentinelWalkwayServer::OnStartup(Entity* self) {
auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>();
@ -19,7 +20,7 @@ void NtSentinelWalkwayServer::OnStartup(Entity* self) {
const auto forward = self->GetRotation().GetRightVector() * -1; const auto forward = self->GetRotation().GetRightVector() * -1;
phantomPhysicsComponent->SetEffectType(0); // PUSH phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH);
phantomPhysicsComponent->SetDirectionalMultiplier(force); phantomPhysicsComponent->SetDirectionalMultiplier(force);
phantomPhysicsComponent->SetDirection(forward); phantomPhysicsComponent->SetDirection(forward);
phantomPhysicsComponent->SetPhysicsEffectActive(true); phantomPhysicsComponent->SetPhysicsEffectActive(true);

View File

@ -4,6 +4,7 @@
#include "Entity.h" #include "Entity.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "RenderComponent.h" #include "RenderComponent.h"
#include "eEndBehavior.h"
void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { void NtVentureCannonServer::OnUse(Entity* self, Entity* user) {
auto* player = user; auto* player = user;
@ -76,7 +77,7 @@ void NtVentureCannonServer::EnterCannonEnded(Entity* self, Entity* player) {
const auto exitCinematicUname = exitCinematic; const auto exitCinematicUname = exitCinematic;
GameMessages::SendPlayCinematic(player->GetObjectID(), exitCinematicUname, player->GetSystemAddress(), GameMessages::SendPlayCinematic(player->GetObjectID(), exitCinematicUname, player->GetSystemAddress(),
true, true, true, false, 0, false, 0, false, false true, true, true, false, eEndBehavior::RETURN, false, 0, false, false
); );
self->AddCallbackTimer(1.5f, [this, self, playerID]() { self->AddCallbackTimer(1.5f, [this, self, playerID]() {

View File

@ -303,18 +303,8 @@ void BasePropertyServer::ResetSpawner(const std::string& spawnerName) {
void BasePropertyServer::DestroySpawner(const std::string& spawnerName) { void BasePropertyServer::DestroySpawner(const std::string& spawnerName) {
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) {
for (auto* node : spawner->m_Info.nodes) { if (!spawner) return;
for (const auto& element : node->entities) { spawner->DestroyAllEntities();
auto* entity = EntityManager::Instance()->GetEntity(element);
if (entity == nullptr)
continue;
entity->Kill();
}
node->entities.clear();
}
spawner->Deactivate(); spawner->Deactivate();
} }
} }

View File

@ -3,6 +3,7 @@
#include "RebuildComponent.h" #include "RebuildComponent.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "eEndBehavior.h"
void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) {
const auto myGroup = "AllPipes"; const auto myGroup = "AllPipes";
@ -42,7 +43,7 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) {
missionComponent->ForceProgressTaskType(769, 1, 1, false); missionComponent->ForceProgressTaskType(769, 1, 1, false);
} }
GameMessages::SendPlayCinematic(player->GetObjectID(), u"ParadoxPipeFinish", player->GetSystemAddress(), true, true, false, false, 0, false, 2.0f); GameMessages::SendPlayCinematic(player->GetObjectID(), u"ParadoxPipeFinish", player->GetSystemAddress(), true, true, false, false, eEndBehavior::RETURN, false, 2.0f);
} }
object->SetVar(u"PlayerID", LWOOBJID_EMPTY); object->SetVar(u"PlayerID", LWOOBJID_EMPTY);

View File

@ -134,24 +134,23 @@ void Spawner::AddEntitySpawnedCallback(std::function<void(Entity*)> callback) {
void Spawner::Reset() { void Spawner::Reset() {
m_Start = true; m_Start = true;
DestroyAllEntities();
for (auto* node : m_Info.nodes) {
for (const auto& spawned : node->entities) {
auto* entity = EntityManager::Instance()->GetEntity(spawned);
if (entity == nullptr) continue;
entity->Kill();
}
node->entities.clear();
}
m_Entities.clear(); m_Entities.clear();
m_AmountSpawned = 0; m_AmountSpawned = 0;
m_NeedsUpdate = true; m_NeedsUpdate = true;
} }
void Spawner::DestroyAllEntities(){
for (auto* node : m_Info.nodes) {
for (const auto& element : node->entities) {
auto* entity = EntityManager::Instance()->GetEntity(element);
if (entity == nullptr) continue;
entity->Kill();
}
node->entities.clear();
}
}
void Spawner::SoftReset() { void Spawner::SoftReset() {
m_Start = true; m_Start = true;
m_AmountSpawned = 0; m_AmountSpawned = 0;

View File

@ -61,6 +61,7 @@ public:
void AddEntitySpawnedCallback(std::function<void(Entity*)> callback); void AddEntitySpawnedCallback(std::function<void(Entity*)> callback);
void SetSpawnLot(LOT lot); void SetSpawnLot(LOT lot);
void Reset(); void Reset();
void DestroyAllEntities();
void SoftReset(); void SoftReset();
void SetRespawnTime(float time); void SetRespawnTime(float time);
void SetNumToMaintain(int32_t value); void SetNumToMaintain(int32_t value);

View File

@ -182,17 +182,7 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id) {
Game::logger->Log("dZoneManager", "Failed to find spawner entity (%llu)", id); Game::logger->Log("dZoneManager", "Failed to find spawner entity (%llu)", id);
} }
for (auto* node : spawner->m_Info.nodes) { spawner->DestroyAllEntities();
for (const auto& element : node->entities) {
auto* nodeEntity = EntityManager::Instance()->GetEntity(element);
if (nodeEntity == nullptr) continue;
nodeEntity->Kill();
}
node->entities.clear();
}
spawner->Deactivate(); spawner->Deactivate();

View File

@ -48,6 +48,7 @@ These commands are primarily for development and testing. The usage of many of t
|Command|Usage|Description|Admin Level Requirement| |Command|Usage|Description|Admin Level Requirement|
|--- |--- |--- |--- | |--- |--- |--- |--- |
|togglenameplate|`/togglenameplate`|Turns the nameplate above your head that is visible to other players off and on.|8 or if `allow_nameplate_off` is set to exactly `1` in the settings|
|fix-stats|`/fix-stats`|Resets skills, buffs, and destroyables.|| |fix-stats|`/fix-stats`|Resets skills, buffs, and destroyables.||
|join|`/join <password>`|Joins a private zone with given password.|| |join|`/join <password>`|Joins a private zone with given password.||
|leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station.|| |leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station.||
@ -127,13 +128,13 @@ There are 9 Game master levels
|Level|Variable Name|Description| |Level|Variable Name|Description|
|--- |--- |--- | |--- |--- |--- |
|0|GAME_MASTER_LEVEL_CIVILIAN|Normal player| |0|CIVILIAN|Normal player|
|1|GAME_MASTER_LEVEL_FORUM_MODERATOR|Forum moderator. No permissions on live servers.| |1|FORUM_MODERATOR|Forum moderator. No permissions on live servers.|
|2|GAME_MASTER_LEVEL_JUNIOR_MODERATOR|Can kick/mute and pull chat logs| |2|JUNIOR_MODERATOR|Can kick/mute and pull chat logs|
|3|GAME_MASTER_LEVEL_MODERATOR|Can return lost items| |3|MODERATOR|Can return lost items|
|4|GAME_MASTER_LEVEL_SENIOR_MODERATOR|Can ban| |4|SENIOR_MODERATOR|Can ban|
|5|GAME_MASTER_LEVEL_LEAD_MODERATOR|Can approve properties| |5|LEAD_MODERATOR|Can approve properties|
|6|GAME_MASTER_LEVEL_JUNIOR_DEVELOPER|Junior developer & future content team. Civilan on live.| |6|JUNIOR_DEVELOPER|Junior developer & future content team. Civilan on live.|
|7|GAME_MASTER_LEVEL_INACTIVE_DEVELOPER|Inactive developer, limited permissions.| |7|INACTIVE_DEVELOPER|Inactive developer, limited permissions.|
|8|GAME_MASTER_LEVEL_DEVELOPER|Active developer, full permissions on live.| |8|DEVELOPER|Active developer, full permissions on live.|
|9|GAME_MASTER_LEVEL_OPERATOR|Can shutdown server for restarts & updates.| |9|OPERATOR|Can shutdown server for restarts & updates.|

View File

@ -58,3 +58,6 @@ hardcore_uscore_enemies_multiplier=2
# Percentage of u-score to lose on player death # Percentage of u-score to lose on player death
hardcore_lose_uscore_on_death_percent=10 hardcore_lose_uscore_on_death_percent=10
# Allow civilian players the ability to turn the nameplate above their head off. Must be exactly 1 to be enabled for civilians.
allow_nameplate_off=0