Merge remote-tracking branch 'origin/main' into grim-lu

This commit is contained in:
wincent
2023-10-07 14:22:23 +02:00
407 changed files with 6059 additions and 3708 deletions

View File

@@ -5,14 +5,12 @@
#include "Game.h"
#include "AssetManager.h"
#include "tinyxml2.h"
#include "Brick.h"
std::vector<Brick> BrickDatabase::emptyCache{};
BrickDatabase* BrickDatabase::m_Address = nullptr;
const BrickList& BrickDatabase::GetBricks(const LxfmlPath& lxfmlPath) {
static std::unordered_map<LxfmlPath, BrickList> m_Cache;
static const BrickList emptyCache;
BrickDatabase::BrickDatabase() = default;
BrickDatabase::~BrickDatabase() = default;
std::vector<Brick>& BrickDatabase::GetBricks(const std::string& lxfmlPath) {
const auto cached = m_Cache.find(lxfmlPath);
if (cached != m_Cache.end()) {
@@ -45,7 +43,7 @@ std::vector<Brick>& BrickDatabase::GetBricks(const std::string& lxfmlPath) {
return emptyCache;
}
std::vector<Brick> parts;
BrickList parts;
auto* lxfml = doc->FirstChildElement("LXFML");
auto* bricks = lxfml->FirstChildElement("Bricks");

View File

@@ -1,29 +1,16 @@
#ifndef __BRICKDATABASE__H__
#define __BRICKDATABASE__H__
#pragma once
#include "Entity.h"
class BrickDatabase
{
public:
static BrickDatabase* Instance() {
if (m_Address == nullptr) {
m_Address = new BrickDatabase();
}
class Brick;
using BrickList = std::vector<Brick>;
using LxfmlPath = std::string;
return m_Address;
}
std::vector<Brick>& GetBricks(const std::string& lxfmlPath);
explicit BrickDatabase();
~BrickDatabase();
private:
std::unordered_map<std::string, std::vector<Brick>> m_Cache;
static std::vector<Brick> emptyCache;
static BrickDatabase* m_Address; //For singleton method
/* data */
namespace BrickDatabase {
const BrickList& GetBricks(const LxfmlPath& lxfmlPath);
};
#endif //!__BRICKDATABASE__H__

View File

@@ -1,4 +1,5 @@
set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp"
"CheatDetection.cpp"
"GUID.cpp"
"Loot.cpp"
"Mail.cpp"

View File

@@ -0,0 +1,138 @@
#include "CheatDetection.h"
#include "Database.h"
#include "Entity.h"
#include "PossessableComponent.h"
#include "Player.h"
#include "Game.h"
#include "EntityManager.h"
#include "Character.h"
#include "User.h"
#include "UserManager.h"
#include "dConfig.h"
Entity* GetPossessedEntity(const LWOOBJID& objId) {
auto* entity = Game::entityManager->GetEntity(objId);
if (!entity) return nullptr;
auto* possessableComponent = entity->GetComponent<PossessableComponent>();
// If no possessable, then this entity is the most possessed entity.
if (!possessableComponent) return entity;
// If not, get the entity that possesses the fetched entity.
return Game::entityManager->GetEntity(possessableComponent->GetPossessor());
}
void ReportCheat(User* user, const SystemAddress& sysAddr, const char* messageIfNotSender, va_list args) {
if (!user) {
Game::logger->Log("CheatDetection", "WARNING: User is null, using defaults.");
}
std::unique_ptr<sql::PreparedStatement> stmt(Database::CreatePreppedStmt(
"INSERT INTO player_cheat_detections (account_id, name, violation_msg, violation_system_address) VALUES (?, ?, ?, ?)")
);
stmt->setInt(1, user ? user->GetAccountID() : 0);
stmt->setString(2, user ? user->GetUsername().c_str() : "User is null.");
constexpr int32_t bufSize = 4096;
char buffer[bufSize];
vsnprintf(buffer, bufSize, messageIfNotSender, args);
stmt->setString(3, buffer);
stmt->setString(4, Game::config->GetValue("log_ip_addresses_for_anti_cheat") == "1" ? sysAddr.ToString() : "IP logging disabled.");
stmt->execute();
Game::logger->Log("CheatDetection", "Anti-cheat message: %s", buffer);
}
void LogAndSaveFailedAntiCheatCheck(const LWOOBJID& id, const SystemAddress& sysAddr, const CheckType checkType, const char* messageIfNotSender, va_list args) {
User* toReport = nullptr;
switch (checkType) {
case CheckType::Entity: {
auto* player = Player::GetPlayer(sysAddr);
auto* entity = GetPossessedEntity(id);
// If player exists and entity exists in world, use both for logging info.
if (entity && player) {
Game::logger->Log("CheatDetection", "Player (%s) (%llu) at system address (%s) with sending player (%s) (%llu) does not match their own.",
player->GetCharacter()->GetName().c_str(), player->GetObjectID(),
sysAddr.ToString(),
entity->GetCharacter()->GetName().c_str(), entity->GetObjectID());
toReport = player->GetParentUser();
// In the case that the target entity id did not exist, just log the player info.
} else if (player) {
Game::logger->Log("CheatDetection", "Player (%s) (%llu) at system address (%s) with sending player (%llu) does not match their own.",
player->GetCharacter()->GetName().c_str(), player->GetObjectID(),
sysAddr.ToString(), id);
toReport = player->GetParentUser();
// In the rare case that the player does not exist, just log the system address and who the target id was.
} else {
Game::logger->Log("CheatDetection", "Player at system address (%s) with sending player (%llu) does not match their own.",
sysAddr.ToString(), id);
}
break;
}
case CheckType::User: {
auto* user = UserManager::Instance()->GetUser(sysAddr);
if (user) {
Game::logger->Log("CheatDetection", "User at system address (%s) (%s) (%llu) sent a packet as (%i) which is not an id they own.",
sysAddr.ToString(), user->GetLastUsedChar()->GetName().c_str(), user->GetLastUsedChar()->GetObjectID(), static_cast<int32_t>(id));
// Can't know sending player. Just log system address for IP banning.
} else {
Game::logger->Log("CheatDetection", "No user found for system address (%s).", sysAddr.ToString());
}
toReport = user;
break;
}
};
ReportCheat(toReport, sysAddr, messageIfNotSender, args);
}
void CheatDetection::ReportCheat(User* user, const SystemAddress& sysAddr, const char* messageIfNotSender, ...) {
va_list args;
va_start(args, messageIfNotSender);
ReportCheat(user, sysAddr, messageIfNotSender, args);
va_end(args);
}
bool CheatDetection::VerifyLwoobjidIsSender(const LWOOBJID& id, const SystemAddress& sysAddr, const CheckType checkType, const char* messageIfNotSender, ...) {
// Get variables we'll need for the whole function
bool invalidPacket = false;
switch (checkType) {
case CheckType::Entity: {
// In this case, the sender may be an entity in the world.
auto* entity = GetPossessedEntity(id);
if (entity) {
invalidPacket = entity->IsPlayer() && entity->GetSystemAddress() != sysAddr;
}
break;
}
case CheckType::User: {
// In this case, the player is not an entity in the world, but may be a user still in world server if they are connected.
// Check here if the system address has a character with id matching the lwoobjid after unsetting the flag bits.
auto* sendingUser = UserManager::Instance()->GetUser(sysAddr);
if (!sendingUser) {
Game::logger->Log("CheatDetection", "No user found for system address (%s).", sysAddr.ToString());
return false;
}
invalidPacket = true;
const uint32_t characterId = static_cast<uint32_t>(id);
// Check to make sure the ID provided is one of the user's characters.
for (const auto& character : sendingUser->GetCharacters()) {
if (character && character->GetID() == characterId) {
invalidPacket = false;
break;
}
}
}
};
// This will be true if the player does not possess the entity they are trying to send a packet as.
// or if the user does not own the character they are trying to send a packet as.
if (invalidPacket) {
va_list args;
va_start(args, messageIfNotSender);
LogAndSaveFailedAntiCheatCheck(id, sysAddr, checkType, messageIfNotSender, args);
va_end(args);
}
return !invalidPacket;
}

View File

@@ -0,0 +1,30 @@
#ifndef __CHEATDETECTION__H__
#define __CHEATDETECTION__H__
#include "dCommonVars.h"
struct SystemAddress;
enum class CheckType : uint8_t {
User,
Entity,
};
namespace CheatDetection {
/**
* @brief Verify that the object ID provided in this function is in someway connected to the system address who sent it.
*
* @param id The object ID to check ownership of
* @param sysAddr The system address which sent the packet
* @param checkType The check type to perform
* @param messageIfNotSender The message to log if the sender is not the owner of the object ID
* @param ... format args
* @return true If the sender is the owner of the object ID
* @return false If the sender is not the owner of the object ID
*/
bool VerifyLwoobjidIsSender(const LWOOBJID& id, const SystemAddress& sysAddr, const CheckType checkType, const char* messageIfNotSender, ...);
void ReportCheat(User* user, const SystemAddress& sysAddr, const char* messageIfNotSender, ...);
};
#endif //!__CHEATDETECTION__H__

View File

@@ -1,6 +1,11 @@
#include "GUID.h"
namespace {
const std::string EMPTY_GUID = "{00000000-0000-0000-0000-000000000000}";
}
GUID::GUID(const std::string& guid) {
if(guid == EMPTY_GUID) return;
sscanf(guid.c_str(),
"{%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx}",
&this->data1, &this->data2, &this->data3,
@@ -8,20 +13,13 @@ GUID::GUID(const std::string& guid) {
&this->data4[4], &this->data4[5], &this->data4[6], &this->data4[7]);
}
uint32_t GUID::GetData1() const {
return data1;
}
uint16_t GUID::GetData2() const {
return data2;
}
uint16_t GUID::GetData3() const {
return data3;
}
std::array<uint8_t, 8> GUID::GetData4() const {
return data4;
void GUID::Serialize(RakNet::BitStream* outBitStream) {
outBitStream->Write(GetData1());
outBitStream->Write(GetData2());
outBitStream->Write(GetData3());
for (const auto& guidSubPart : GetData4()) {
outBitStream->Write(guidSubPart);
}
}
GUID::GUID() = default;

View File

@@ -7,10 +7,24 @@ class GUID {
public:
explicit GUID();
explicit GUID(const std::string& guid);
uint32_t GetData1() const;
uint16_t GetData2() const;
uint16_t GetData3() const;
std::array<uint8_t, 8> GetData4() const;
void Serialize(RakNet::BitStream* outBitStream);
uint32_t GetData1() const {
return data1;
}
uint16_t GetData2() const {
return data2;
}
uint16_t GetData3() const {
return data3;
}
std::array<uint8_t, 8> GetData4() const {
return data4;
}
private:
uint32_t data1 = 0;
uint16_t data2 = 0;

View File

@@ -13,6 +13,7 @@
#include "Entity.h"
#include "Character.h"
#include "PacketUtils.h"
#include "BitStreamUtils.h"
#include "dLogger.h"
#include "EntityManager.h"
#include "InventoryComponent.h"
@@ -195,7 +196,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd
uint32_t itemID = static_cast<uint32_t>(attachmentID);
LOT itemLOT = 0;
//Inventory::InventoryType itemType;
int mailCost = dZoneManager::Instance()->GetWorldConfig()->mailBaseFee;
int mailCost = Game::zoneManager->GetWorldConfig()->mailBaseFee;
int stackSize = 0;
auto inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY));
Item* item = nullptr;
@@ -203,7 +204,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd
if (itemID > 0 && attachmentCount > 0 && inv) {
item = inv->FindItemById(attachmentID);
if (item) {
mailCost += (item->GetInfo().baseValue * dZoneManager::Instance()->GetWorldConfig()->mailPercentAttachmentFee);
mailCost += (item->GetInfo().baseValue * Game::zoneManager->GetWorldConfig()->mailPercentAttachmentFee);
stackSize = item->GetCount();
itemLOT = item->GetLot();
} else {
@@ -283,7 +284,7 @@ void Mail::HandleDataRequest(RakNet::BitStream* packet, const SystemAddress& sys
sql::ResultSet* res = stmt->executeQuery();
RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
bitStream.Write(int(MailMessageID::MailData));
bitStream.Write(int(0));
@@ -406,7 +407,7 @@ void Mail::HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t obje
void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) {
RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
bitStream.Write(int(MailMessageID::SendResponse));
bitStream.Write(int(response));
Game::server->Send(&bitStream, sysAddr, false);
@@ -414,7 +415,7 @@ void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse respo
void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
uint64_t messageType = 2;
uint64_t s1 = 0;
uint64_t s2 = 0;
@@ -433,7 +434,7 @@ void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
bitStream.Write(int(MailMessageID::AttachmentCollectConfirm));
bitStream.Write(int(0)); //unknown
bitStream.Write(mailID);
@@ -442,7 +443,7 @@ void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t ma
void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) {
RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
bitStream.Write(int(MailMessageID::MailDeleteConfirm));
bitStream.Write(int(0)); //unknown
bitStream.Write(mailID);
@@ -456,7 +457,7 @@ void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOO
void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
bitStream.Write(int(MailMessageID::MailReadConfirm));
bitStream.Write(int(0)); //unknown
bitStream.Write(mailID);

View File

@@ -49,7 +49,7 @@
#include "dpWorld.h"
#include "Item.h"
#include "PropertyManagementComponent.h"
#include "PacketUtils.h"
#include "BitStreamUtils.h"
#include "Loot.h"
#include "EntityInfo.h"
#include "LUTriggers.h"
@@ -185,7 +185,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
character->SetPvpEnabled(!character->GetPvpEnabled());
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
std::stringstream message;
message << character->GetName() << " changed their PVP flag to " << std::to_string(character->GetPvpEnabled()) << "!";
@@ -334,7 +334,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
if (chatCommand == "leave-zone") {
const auto currentZone = dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID();
const auto currentZone = Game::zoneManager->GetZone()->GetZoneID().GetMapID();
LWOMAPID newZone = 0;
if (currentZone % 100 == 0) {
@@ -344,14 +344,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
newZone = (currentZone / 100) * 100;
}
// If new zone would be inaccessible, then default to Avant Gardens.
if (!dZoneManager::Instance()->CheckIfAccessibleZone(newZone)) newZone = 1100;
if (!Game::zoneManager->CheckIfAccessibleZone(newZone)) newZone = 1100;
ChatPackets::SendSystemMessage(sysAddr, u"Leaving zone...");
const auto objid = entity->GetObjectID();
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, newZone, 0, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
auto* entity = EntityManager::Instance()->GetEntity(objid);
auto* entity = Game::entityManager->GetEntity(objid);
if (entity == nullptr) {
return;
@@ -398,7 +398,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
if (chatCommand == "resurrect") {
ScriptedActivityComponent* scriptedActivityComponent = dZoneManager::Instance()->GetZoneControlObject()->GetComponent<ScriptedActivityComponent>();
ScriptedActivityComponent* scriptedActivityComponent = Game::zoneManager->GetZoneControlObject()->GetComponent<ScriptedActivityComponent>();
if (scriptedActivityComponent) { // check if user is in activity world and if so, they can't resurrect
ChatPackets::SendSystemMessage(sysAddr, u"You cannot resurrect in an activity world.");
@@ -413,7 +413,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
if (chatCommand == "instanceinfo") {
const auto zoneId = dZoneManager::Instance()->GetZone()->GetZoneID();
const auto zoneId = Game::zoneManager->GetZone()->GetZoneID();
ChatPackets::SendSystemMessage(sysAddr, u"Map: " + (GeneralUtils::to_u16string(zoneId.GetMapID())) + u"\nClone: " + (GeneralUtils::to_u16string(zoneId.GetCloneID())) + u"\nInstance: " + (GeneralUtils::to_u16string(zoneId.GetInstanceID())));
}
@@ -434,7 +434,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID.");
return;
}
EntityManager::Instance()->DestructEntity(entity, sysAddr);
Game::entityManager->DestructEntity(entity, sysAddr);
auto* charComp = entity->GetComponent<CharacterComponent>();
std::string lowerName = args[0];
if (lowerName.empty()) return;
@@ -461,12 +461,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
charComp->m_Character->SetLeftHand(minifigItemId);
charComp->m_Character->SetRightHand(minifigItemId);
} else {
EntityManager::Instance()->ConstructEntity(entity);
Game::entityManager->ConstructEntity(entity);
ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig item to change, try one of the following: Eyebrows, Eyes, HairColor, HairStyle, Pants, LeftHand, Mouth, RightHand, Shirt, Hands");
return;
}
EntityManager::Instance()->ConstructEntity(entity);
Game::entityManager->ConstructEntity(entity);
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(lowerName) + u" set to " + (GeneralUtils::to_u16string(minifigItemId)));
GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character
@@ -477,13 +477,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
RenderComponent::PlayAnimation(entity, anim);
auto* possessorComponent = entity->GetComponent<PossessorComponent>();
if (possessorComponent) {
auto* possessedComponent = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
auto* possessedComponent = Game::entityManager->GetEntity(possessorComponent->GetPossessable());
if (possessedComponent) RenderComponent::PlayAnimation(possessedComponent, anim);
}
}
if (chatCommand == "list-spawns" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) {
for (const auto& pair : Game::entityManager->GetSpawnPointEntities()) {
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first));
}
@@ -512,7 +512,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto* user = UserManager::Instance()->GetUser(args[0]);
if (user) {
auto* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar());
auto* player = Game::entityManager->GetEntity(user->GetLoggedInChar());
player->Smash(entity->GetObjectID());
ChatPackets::SendSystemMessage(sysAddr, u"It has been done, do you feel good about yourself now?");
return;
@@ -540,7 +540,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (possessor) {
auto possessedID = possessor->GetPossessable();
if (possessedID != LWOOBJID_EMPTY) {
auto possessable = EntityManager::Instance()->GetEntity(possessedID);
auto possessable = Game::entityManager->GetEntity(possessedID);
if (possessable) {
auto* possessControllablePhysicsComponent = possessable->GetComponent<ControllablePhysicsComponent>();
if (possessControllablePhysicsComponent) {
@@ -550,7 +550,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
}
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
}
if (chatCommand == "freecam" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
@@ -954,7 +954,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == eGameMasterLevel::OPERATOR) {
//Tell the master server that we're going to be shutting down whole "universe":
CBITSTREAM;
PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_UNIVERSE);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_UNIVERSE);
Game::server->SendToMaster(&bitStream);
ChatPackets::SendSystemMessage(sysAddr, u"Sent universe shutdown notification to master.");
@@ -1130,13 +1130,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto* possessorComponent = entity->GetComponent<PossessorComponent>();
if (possessorComponent) {
auto* possassableEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
auto* possassableEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable());
if (possassableEntity != nullptr) {
auto* vehiclePhysicsComponent = possassableEntity->GetComponent<VehiclePhysicsComponent>();
if (vehiclePhysicsComponent) {
vehiclePhysicsComponent->SetPosition(pos);
EntityManager::Instance()->SerializeEntity(possassableEntity);
Game::entityManager->SerializeEntity(possassableEntity);
} else GameMessages::SendTeleport(possassableEntity->GetObjectID(), pos, NiQuaternion(), sysAddr);
}
}
@@ -1145,7 +1145,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (chatCommand == "tpall" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
const auto pos = entity->GetPosition();
const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
for (auto* character : characters) {
GameMessages::SendTeleport(character->GetObjectID(), pos, NiQuaternion(), character->GetSystemAddress());
@@ -1159,7 +1159,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (possessorComponent) {
auto possessableId = possessorComponent->GetPossessable();
if (possessableId != LWOOBJID_EMPTY) {
auto* possessableEntity = EntityManager::Instance()->GetEntity(possessableId);
auto* possessableEntity = Game::entityManager->GetEntity(possessableId);
if (possessableEntity) possessorComponent->Dismount(possessableEntity, true);
}
}
@@ -1285,7 +1285,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
//Notify chat about it
CBITSTREAM;
PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE);
bitStream.Write(characterId);
bitStream.Write(expire);
@@ -1373,7 +1373,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
dest->SetImagination(999);
dest->SetMaxImagination(999.0f);
}
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
}
if (chatCommand == "startcelebration" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) {
@@ -1397,7 +1397,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
dest->SetImagination(9);
dest->SetMaxImagination(9.0f);
}
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
}
if (chatCommand == "refillstats" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
@@ -1409,7 +1409,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
dest->SetImagination((int)dest->GetMaxImagination());
}
EntityManager::Instance()->SerializeEntity(entity);
Game::entityManager->SerializeEntity(entity);
}
if (chatCommand == "lookup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
@@ -1453,26 +1453,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
info.spawnerID = entity->GetObjectID();
info.spawnerNodeID = 0;
Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr);
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
if (newEntity == nullptr) {
ChatPackets::SendSystemMessage(sysAddr, u"Failed to spawn entity.");
return;
}
auto vehiclePhysicsComponent = newEntity->GetComponent<VehiclePhysicsComponent>();
if (vehiclePhysicsComponent) {
auto newRot = newEntity->GetRotation();
auto angles = newRot.GetEulerAngles();
// make it right side up
angles.x -= PI;
// make it going in the direction of the player
angles.y -= PI;
newRot = NiQuaternion::FromEulerAngles(angles);
newEntity->SetRotation(newRot);
}
EntityManager::Instance()->ConstructEntity(newEntity);
Game::entityManager->ConstructEntity(newEntity);
}
if (chatCommand == "spawngroup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) {
@@ -1515,13 +1503,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
info.pos = playerPosition + NiPoint3(cos(randomAngle) * randomRadius, 0.0f, sin(randomAngle) * randomRadius);
info.rot = NiQuaternion();
auto newEntity = EntityManager::Instance()->CreateEntity(info);
auto newEntity = Game::entityManager->CreateEntity(info);
if (newEntity == nullptr) {
ChatPackets::SendSystemMessage(sysAddr, u"Failed to spawn entity.");
return;
}
EntityManager::Instance()->ConstructEntity(newEntity);
Game::entityManager->ConstructEntity(newEntity);
numberToSpawn--;
}
}
@@ -1648,7 +1636,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
if ((chatCommand == "freemoney" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) && args.size() == 1) {
int32_t money;
int64_t money;
if (!GeneralUtils::TryParse(args[0], money)) {
ChatPackets::SendSystemMessage(sysAddr, u"Invalid money.");
@@ -1746,11 +1734,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
const auto objid = entity->GetObjectID();
if (force || dZoneManager::Instance()->CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery
if (force || Game::zoneManager->CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, reqZone, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
auto* entity = EntityManager::Instance()->GetEntity(objid);
auto* entity = Game::entityManager->GetEntity(objid);
if (!entity) return;
const auto sysAddr = entity->GetSystemAddress();
@@ -1814,7 +1802,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return;
}
auto* vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
auto* vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable());
if (vehicle == nullptr) {
return;
@@ -1843,20 +1831,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto* possessorComponent = entity->GetComponent<PossessorComponent>();
if (possessorComponent == nullptr) return;
auto* vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
auto* vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable());
if (vehicle == nullptr) return;
GameMessages::SendVehicleRemovePassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
}
if (chatCommand == "activatespawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]);
auto spawners = Game::zoneManager->GetSpawnersByName(args[0]);
for (auto* spawner : spawners) {
spawner->Activate();
}
spawners = dZoneManager::Instance()->GetSpawnersInGroup(args[0]);
spawners = Game::zoneManager->GetSpawnersInGroup(args[0]);
for (auto* spawner : spawners) {
spawner->Activate();
@@ -1865,7 +1853,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) {
//Go tell physics to spawn all the vertices:
auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS);
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS);
for (auto en : entities) {
auto phys = static_cast<PhantomPhysicsComponent*>(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS));
if (phys)
@@ -1874,7 +1862,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) {
auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR);
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR);
for (auto en : entities) {
auto phys = static_cast<ProximityMonitorComponent*>(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR));
if (phys) {
@@ -1890,13 +1878,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]);
auto spawners = Game::zoneManager->GetSpawnersByName(args[0]);
for (auto* spawner : spawners) {
spawner->Spawn();
}
spawners = dZoneManager::Instance()->GetSpawnersInGroup(args[0]);
spawners = Game::zoneManager->GetSpawnersInGroup(args[0]);
for (auto* spawner : spawners) {
spawner->Spawn();
@@ -1970,7 +1958,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
Game::config->ReloadConfig();
VanityUtilities::SpawnVanity();
dpWorld::Instance().Reload();
auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
for (auto entity : entities) {
auto* scriptedActivityComponent = entity->GetComponent<ScriptedActivityComponent>();
if (!scriptedActivityComponent) continue;
@@ -2067,7 +2055,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto closestDistance = 0.0f;
const auto candidates = EntityManager::Instance()->GetEntitiesByComponent(component);
const auto candidates = Game::entityManager->GetEntitiesByComponent(component);
for (auto* candidate : candidates) {
if (candidate->GetLOT() == 1 || candidate->GetLOT() == 8092) {
@@ -2099,7 +2087,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return;
}
EntityManager::Instance()->SerializeEntity(closest);
Game::entityManager->SerializeEntity(closest);
auto* table = CDClientManager::Instance().GetTable<CDObjectsTable>();
@@ -2139,7 +2127,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
movingPlatformComponent->GotoWaypoint(value);
}
EntityManager::Instance()->SerializeEntity(closest);
Game::entityManager->SerializeEntity(closest);
} else if (args[1] == "-a" && args.size() >= 3) {
RenderComponent::PlayAnimation(closest, args.at(2));
} else if (args[1] == "-s") {
@@ -2250,7 +2238,7 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::
//Notify chat about it
CBITSTREAM;
PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ANNOUNCEMENT);
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ANNOUNCEMENT);
bitStream.Write<uint32_t>(title.size());
for (auto character : title) {

View File

@@ -80,10 +80,10 @@ void VanityUtilities::SpawnVanity() {
// Spawn the NPC
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases);
SetupNPCTalk(npcEntity);
if (!npc.m_Phrases.empty()) {
npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases);
SetupNPCTalk(npcEntity);
}
}
return;
@@ -114,21 +114,21 @@ void VanityUtilities::SpawnVanity() {
// Spawn the NPC
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
if (!npc.m_Phrases.empty()){
npcEntity->SetVar<std::vector<std::string>>(u"chats", npc.m_Phrases);
npcEntity->SetVar<std::vector<std::string>>(u"chats", npc.m_Phrases);
auto* scriptComponent = npcEntity->GetComponent<ScriptComponent>();
auto* scriptComponent = npcEntity->GetComponent<ScriptComponent>();
if (scriptComponent && !npc.m_Script.empty()) {
scriptComponent->SetScript(npc.m_Script);
scriptComponent->SetSerialized(false);
if (scriptComponent != nullptr) {
scriptComponent->SetScript(npc.m_Script);
scriptComponent->SetSerialized(false);
for (const auto& npc : npc.m_Flags) {
npcEntity->SetVar<bool>(GeneralUtils::ASCIIToUTF16(npc.first), npc.second);
for (const auto& npc : npc.m_Flags) {
npcEntity->SetVar<bool>(GeneralUtils::ASCIIToUTF16(npc.first), npc.second);
}
}
SetupNPCTalk(npcEntity);
}
SetupNPCTalk(npcEntity);
}
if (zoneID == 1200) {
@@ -137,14 +137,14 @@ void VanityUtilities::SpawnVanity() {
info.lot = 8139;
info.pos = { 259.5f, 246.4f, -705.2f };
info.rot = { 0.0f, 0.0f, 1.0f, 0.0f };
info.spawnerID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID();
info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
info.settings = { new LDFData<bool>(u"hasCustomText", true),
new LDFData<std::string>(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string())) };
auto* entity = EntityManager::Instance()->CreateEntity(info);
auto* entity = Game::entityManager->CreateEntity(info);
EntityManager::Instance()->ConstructEntity(entity);
Game::entityManager->ConstructEntity(entity);
}
}
}
@@ -155,11 +155,12 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin
info.lot = lot;
info.pos = position;
info.rot = rotation;
info.spawnerID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID();
info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
info.settings = ldf;
auto* entity = EntityManager::Instance()->CreateEntity(info);
auto* entity = Game::entityManager->CreateEntity(info);
entity->SetVar(u"npcName", name);
if (entity->GetVar<bool>(u"noGhosting")) entity->SetIsGhostingCandidate(false);
auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
@@ -175,7 +176,7 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin
destroyableComponent->SetHealth(0);
}
EntityManager::Instance()->ConstructEntity(entity);
Game::entityManager->ConstructEntity(entity);
return entity;
}
@@ -535,7 +536,7 @@ void VanityUtilities::NPCTalk(Entity* npc) {
npc->GetObjectID(), u"sendToclient_bubble", 0, 0, npc->GetObjectID(), selected, UNASSIGNED_SYSTEM_ADDRESS);
}
EntityManager::Instance()->SerializeEntity(npc);
Game::entityManager->SerializeEntity(npc);
const float nextTime = GeneralUtils::GenerateRandomNumber<float>(15, 60);