From b432a3f5dae1c8c0e4aef76f8ae05c5d7fd69b78 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 20 Mar 2023 06:10:52 -0700 Subject: [PATCH 001/116] Remove inlines Clean up macros more tomorrow Cleanup and optimize CDActivities table Remove unused include Further work on CDActivityRewards Update MasterServer.cpp Further animations work Activities still needs work for a better PK. fix type All of these replacements worked Create internal interface for animations Allows for user to just call GetAnimationTIme or PlayAnimation rather than passing in arbitrary true false statements --- dCommon/DluAssert.h | 14 ++ dCommon/Metrics.cpp | 1 + dCommon/Metrics.hpp | 1 + dDatabase/CDClientDatabase.h | 3 - dDatabase/CDClientManager.cpp | 2 +- dDatabase/CDClientManager.h | 2 + dDatabase/Tables/CDActivitiesTable.cpp | 54 +++----- dDatabase/Tables/CDActivitiesTable.h | 45 ++++--- dDatabase/Tables/CDActivityRewardsTable.h | 14 +- dDatabase/Tables/CDAnimationsTable.cpp | 108 ++++++++++------ dDatabase/Tables/CDAnimationsTable.h | 28 ++-- .../Tables/CDComponentsRegistryTable.cpp | 94 +++----------- dDatabase/Tables/CDComponentsRegistryTable.h | 14 +- dDatabase/Tables/CDItemComponentTable.cpp | 26 ++-- dDatabase/Tables/CDItemComponentTable.h | 58 ++++----- dDatabase/Tables/CDLootMatrixTable.cpp | 2 +- dDatabase/Tables/CDLootMatrixTable.h | 2 +- dDatabase/Tables/CDMissionTasksTable.cpp | 12 +- dDatabase/Tables/CDMissionTasksTable.h | 12 +- dDatabase/Tables/CDMissionsTable.cpp | 6 +- dDatabase/Tables/CDMissionsTable.h | 6 +- dDatabase/Tables/CDObjectsTable.cpp | 20 +-- dDatabase/Tables/CDObjectsTable.h | 20 +-- dDatabase/Tables/CDPhysicsComponentTable.cpp | 16 +-- dDatabase/Tables/CDPhysicsComponentTable.h | 16 +-- dDatabase/Tables/CDSkillBehaviorTable.cpp | 28 ++-- dDatabase/Tables/CDSkillBehaviorTable.h | 28 ++-- dDatabase/Tables/CDTable.h | 16 +++ dDatabase/Tables/CDZoneTableTable.cpp | 18 +-- dDatabase/Tables/CDZoneTableTable.h | 18 +-- dGame/Entity.cpp | 5 +- dGame/LeaderboardManager.cpp | 10 +- dGame/dComponents/PetComponent.cpp | 4 +- dGame/dComponents/RailActivatorComponent.cpp | 25 +--- dGame/dComponents/RebuildComponent.cpp | 5 +- dGame/dComponents/RenderComponent.cpp | 122 +++++++++--------- dGame/dComponents/RenderComponent.h | 17 ++- .../dComponents/ScriptedActivityComponent.cpp | 34 ++--- dGame/dComponents/ScriptedActivityComponent.h | 16 ++- dGame/dComponents/SwitchComponent.cpp | 3 +- dGame/dGameMessages/GameMessages.cpp | 3 +- dGame/dUtilities/Loot.cpp | 1 + dGame/dUtilities/SlashCommandHandler.cpp | 7 +- dMasterServer/MasterServer.cpp | 5 +- dScripts/02_server/DLU/DLUVanityNPC.cpp | 3 +- .../Enemy/AG/BossSpiderQueenEnemyServer.cpp | 5 +- .../02_server/Enemy/AM/AmDarklingDragon.cpp | 11 +- .../02_server/Enemy/FV/FvMaelstromDragon.cpp | 13 +- .../02_server/Enemy/General/BaseEnemyApe.cpp | 3 +- .../Enemy/General/GfApeSmashingQB.cpp | 4 +- .../Equipment/MaestromExtracticatorServer.cpp | 25 ++-- .../Equipment/MaestromExtracticatorServer.h | 3 +- dScripts/02_server/Map/AG/AgMonumentBirds.cpp | 5 +- dScripts/02_server/Map/AM/AmSkullkinDrill.cpp | 11 +- .../02_server/Map/AM/AmSkullkinDrillStand.cpp | 4 +- dScripts/02_server/Map/AM/AmSkullkinTower.cpp | 7 +- .../02_server/Map/GF/GfCaptainsCannon.cpp | 5 +- dScripts/02_server/Map/GF/GfTikiTorch.cpp | 5 +- dScripts/02_server/Map/GF/MastTeleport.cpp | 8 +- .../02_server/Map/General/ExplodingAsset.cpp | 22 +--- .../General/Ninjago/NjIceRailActivator.cpp | 4 +- .../02_server/Map/NT/NtAssemblyTubeServer.cpp | 5 +- .../02_server/Map/NT/NtParadoxPanelServer.cpp | 7 +- .../02_server/Map/NT/NtParadoxTeleServer.cpp | 5 +- dScripts/02_server/Map/NT/NtSleepingGuard.cpp | 3 +- .../Map/NT/NtVentureCannonServer.cpp | 7 +- .../Map/njhub/CatapultBaseServer.cpp | 8 +- .../02_server/Map/njhub/CavePrisonCage.cpp | 11 +- .../boss_instance/NjMonastryBossInstance.cpp | 11 +- dScripts/BaseConsoleTeleportServer.cpp | 9 +- dScripts/ai/AG/AgFans.cpp | 10 +- dScripts/ai/AG/AgJetEffectServer.cpp | 3 +- dScripts/ai/AG/AgSalutingNpcs.cpp | 5 +- dScripts/ai/AG/AgShipPlayerShockServer.cpp | 4 +- dScripts/ai/AG/AgSpaceStuff.cpp | 12 +- dScripts/ai/FV/FvDragonSmashingGolemQb.cpp | 4 +- dScripts/ai/FV/FvFlyingCreviceDragon.cpp | 7 +- dScripts/ai/FV/FvNinjaGuard.cpp | 10 +- dScripts/ai/GENERAL/LegoDieRoll.cpp | 13 +- dScripts/ai/GF/GfOrgan.cpp | 4 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 7 +- dScripts/ai/NS/NsConcertInstrument.cpp | 5 +- dScripts/ai/NS/WhFans.cpp | 6 +- dScripts/ai/WILD/WildAmbients.cpp | 3 +- 84 files changed, 631 insertions(+), 607 deletions(-) create mode 100644 dCommon/DluAssert.h diff --git a/dCommon/DluAssert.h b/dCommon/DluAssert.h new file mode 100644 index 00000000..ce971122 --- /dev/null +++ b/dCommon/DluAssert.h @@ -0,0 +1,14 @@ +#ifndef __DLUASSERT__H__ +#define __DLUASSERT__H__ + +#include + +#define _DEBUG + +#ifdef _DEBUG +# define DluAssert(expression) assert(expression) +#else +# define DluAssert(expression) +#endif + +#endif //!__DLUASSERT__H__ diff --git a/dCommon/Metrics.cpp b/dCommon/Metrics.cpp index b97b5435..3a3b7d78 100644 --- a/dCommon/Metrics.cpp +++ b/dCommon/Metrics.cpp @@ -14,6 +14,7 @@ std::vector Metrics::m_Variables = { MetricVariable::CPUTime, MetricVariable::Sleep, MetricVariable::Frame, + MetricVariable::Database, }; void Metrics::AddMeasurement(MetricVariable variable, int64_t value) { diff --git a/dCommon/Metrics.hpp b/dCommon/Metrics.hpp index c03c914f..b7ac748f 100644 --- a/dCommon/Metrics.hpp +++ b/dCommon/Metrics.hpp @@ -20,6 +20,7 @@ enum class MetricVariable : int32_t CPUTime, Sleep, Frame, + Database, }; struct Metric diff --git a/dDatabase/CDClientDatabase.h b/dDatabase/CDClientDatabase.h index 96f67d64..59f69b7d 100644 --- a/dDatabase/CDClientDatabase.h +++ b/dDatabase/CDClientDatabase.h @@ -16,9 +16,6 @@ // Enable this to cache all entries in each table for fast access, comes with more memory cost //#define CDCLIENT_CACHE_ALL - // Enable this to skip some unused columns in some tables -#define UNUSED(v) - /*! \file CDClientDatabase.hpp \brief An interface between the CDClient.sqlite file and the server diff --git a/dDatabase/CDClientManager.cpp b/dDatabase/CDClientManager.cpp index eeea686f..9df6ff31 100644 --- a/dDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientManager.cpp @@ -40,7 +40,7 @@ CDClientManager::CDClientManager() { CDActivityRewardsTable::Instance(); - UNUSED(CDAnimationsTable::Instance()); + CDAnimationsTable::Instance(); CDBehaviorParameterTable::Instance(); CDBehaviorTemplateTable::Instance(); CDComponentsRegistryTable::Instance(); diff --git a/dDatabase/CDClientManager.h b/dDatabase/CDClientManager.h index 1754fe99..74069ff4 100644 --- a/dDatabase/CDClientManager.h +++ b/dDatabase/CDClientManager.h @@ -4,6 +4,8 @@ #include "Singleton.h" +#define UNUSED_TABLE(v) + /** * Initialize the CDClient tables so they are all loaded into memory. */ diff --git a/dDatabase/Tables/CDActivitiesTable.cpp b/dDatabase/Tables/CDActivitiesTable.cpp index e1660d66..2c2da31e 100644 --- a/dDatabase/Tables/CDActivitiesTable.cpp +++ b/dDatabase/Tables/CDActivitiesTable.cpp @@ -1,27 +1,11 @@ #include "CDActivitiesTable.h" -CDActivitiesTable::CDActivitiesTable(void) { - - // First, get the size of the table - unsigned int size = 0; - auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Activities"); - while (!tableSize.eof()) { - size = tableSize.getIntField(0, 0); - - tableSize.nextRow(); - } - - tableSize.finalize(); - - // Reserve the size - this->entries.reserve(size); - - // Now get the data +CDActivitiesTable::CDActivitiesTable() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Activities"); while (!tableData.eof()) { CDActivities entry; - entry.ActivityID = tableData.getIntField("ActivityID", -1); - entry.locStatus = tableData.getIntField("locStatus", -1); + ActivityID activityId = tableData.getIntField("ActivityID", -1); + UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); entry.instanceMapID = tableData.getIntField("instanceMapID", -1); entry.minTeams = tableData.getIntField("minTeams", -1); entry.maxTeams = tableData.getIntField("maxTeams", -1); @@ -29,34 +13,26 @@ CDActivitiesTable::CDActivitiesTable(void) { entry.maxTeamSize = tableData.getIntField("maxTeamSize", -1); entry.waitTime = tableData.getIntField("waitTime", -1); entry.startDelay = tableData.getIntField("startDelay", -1); - entry.requiresUniqueData = tableData.getIntField("requiresUniqueData", -1); + UNUSED_COLUMN(entry.requiresUniqueData = tableData.getIntField("requiresUniqueData", -1)); entry.leaderboardType = tableData.getIntField("leaderboardType", -1); - entry.localize = tableData.getIntField("localize", -1); + UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1)); entry.optionalCostLOT = tableData.getIntField("optionalCostLOT", -1); entry.optionalCostCount = tableData.getIntField("optionalCostCount", -1); - entry.showUIRewards = tableData.getIntField("showUIRewards", -1); - entry.CommunityActivityFlagID = tableData.getIntField("CommunityActivityFlagID", -1); - entry.gate_version = tableData.getStringField("gate_version", ""); + UNUSED_COLUMN(entry.showUIRewards = tableData.getIntField("showUIRewards", -1)); + UNUSED_COLUMN(entry.CommunityActivityFlagID = tableData.getIntField("CommunityActivityFlagID", -1)); + UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); entry.noTeamLootOnDeath = tableData.getIntField("noTeamLootOnDeath", -1); - entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f); + UNUSED_COLUMN(entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f)); + + auto insertedElement = this->entries.insert_or_assign(activityId, entry); + DluAssert(insertedElement.second == true); - this->entries.push_back(entry); tableData.nextRow(); } - tableData.finalize(); } -std::vector CDActivitiesTable::Query(std::function predicate) { - - std::vector data = cpplinq::from(this->entries) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data; +CDActivitiesResult CDActivitiesTable::GetActivity(ActivityID id) { + const auto foundElement = this->entries.find(id); + return foundElement != this->entries.end() ? CDActivitiesResult(foundElement->second) : CDActivitiesResult(); } - -std::vector CDActivitiesTable::GetEntries(void) const { - return this->entries; -} - diff --git a/dDatabase/Tables/CDActivitiesTable.h b/dDatabase/Tables/CDActivitiesTable.h index 4b60afbd..ed454b6e 100644 --- a/dDatabase/Tables/CDActivitiesTable.h +++ b/dDatabase/Tables/CDActivitiesTable.h @@ -1,38 +1,37 @@ #pragma once -// Custom Classes #include "CDTable.h" +typedef uint32_t ActivityID; + struct CDActivities { - unsigned int ActivityID; - unsigned int locStatus; - unsigned int instanceMapID; - unsigned int minTeams; - unsigned int maxTeams; - unsigned int minTeamSize; - unsigned int maxTeamSize; - unsigned int waitTime; - unsigned int startDelay; - bool requiresUniqueData; - unsigned int leaderboardType; - bool localize; - int optionalCostLOT; - int optionalCostCount; - bool showUIRewards; - unsigned int CommunityActivityFlagID; - std::string gate_version; + UNUSED_COLUMN(uint32_t locStatus); + uint32_t instanceMapID; + uint32_t minTeams; + uint32_t maxTeams; + uint32_t minTeamSize; + uint32_t maxTeamSize; + uint32_t waitTime; + uint32_t startDelay; + UNUSED_COLUMN(bool requiresUniqueData); + uint32_t leaderboardType; + UNUSED_COLUMN(bool localize); + int32_t optionalCostLOT; + int32_t optionalCostCount; + UNUSED_COLUMN(bool showUIRewards); + UNUSED_COLUMN(uint32_t CommunityActivityFlagID); + UNUSED_COLUMN(std::string gate_version); bool noTeamLootOnDeath; - float optionalPercentage; + UNUSED_COLUMN(float optionalPercentage); }; +typedef LookupResult CDActivitiesResult; class CDActivitiesTable : public CDTable { private: - std::vector entries; + std::map entries; public: CDActivitiesTable(); // Queries the table with a custom "where" clause - std::vector Query(std::function predicate); - - std::vector GetEntries(void) const; + CDActivitiesResult GetActivity(ActivityID predicate); }; diff --git a/dDatabase/Tables/CDActivityRewardsTable.h b/dDatabase/Tables/CDActivityRewardsTable.h index b5503fb6..9a4a4ce8 100644 --- a/dDatabase/Tables/CDActivityRewardsTable.h +++ b/dDatabase/Tables/CDActivityRewardsTable.h @@ -4,13 +4,13 @@ #include "CDTable.h" struct CDActivityRewards { - unsigned int objectTemplate; //!< The object template (?) - unsigned int ActivityRewardIndex; //!< The activity reward index - int activityRating; //!< The activity rating - unsigned int LootMatrixIndex; //!< The loot matrix index - unsigned int CurrencyIndex; //!< The currency index - unsigned int ChallengeRating; //!< The challenge rating - std::string description; //!< The description + unsigned int objectTemplate; + unsigned int ActivityRewardIndex; + int activityRating; + unsigned int LootMatrixIndex; + unsigned int CurrencyIndex; + unsigned int ChallengeRating; + std::string description; }; class CDActivityRewardsTable : public CDTable { diff --git a/dDatabase/Tables/CDAnimationsTable.cpp b/dDatabase/Tables/CDAnimationsTable.cpp index e1227f39..4f4730de 100644 --- a/dDatabase/Tables/CDAnimationsTable.cpp +++ b/dDatabase/Tables/CDAnimationsTable.cpp @@ -1,56 +1,84 @@ #include "CDAnimationsTable.h" +#include "GeneralUtils.h" +#include "Game.h" -CDAnimationsTable::CDAnimationsTable(void) { +bool CDAnimationsTable::CacheData(CppSQLite3Statement queryToCache) { + auto tableData = queryToCache.execQuery(); + // If we received a bad lookup, cache it anyways so we do not run the query again. + if (tableData.eof()) return false; - // First, get the size of the table - unsigned int size = 0; - auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Animations"); - while (!tableSize.eof()) { - size = tableSize.getIntField(0, 0); + do { + std::string animation_type = tableData.getStringField("animation_type", ""); + DluAssert(!animation_type.empty()); + AnimationGroupID animationGroupID = tableData.getIntField("animationGroupID", -1); + DluAssert(animationGroupID != -1); - tableSize.nextRow(); - } - - tableSize.finalize(); - - // Reserve the size - this->entries.reserve(size); - - // Now get the data - auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations"); - while (!tableData.eof()) { - CDAnimations entry; - entry.animationGroupID = tableData.getIntField("animationGroupID", -1); - entry.animation_type = tableData.getStringField("animation_type", ""); + CDAnimation entry; entry.animation_name = tableData.getStringField("animation_name", ""); - entry.chance_to_play = tableData.getFloatField("chance_to_play", -1.0f); - entry.min_loops = tableData.getIntField("min_loops", -1); - entry.max_loops = tableData.getIntField("max_loops", -1); - entry.animation_length = tableData.getFloatField("animation_length", -1.0f); - entry.hideEquip = tableData.getIntField("hideEquip", -1) == 1 ? true : false; - entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", -1) == 1 ? true : false; - entry.restartable = tableData.getIntField("restartable", -1) == 1 ? true : false; + entry.chance_to_play = tableData.getFloatField("chance_to_play", 1.0f); + entry.min_loops = tableData.getIntField("min_loops", 0); + entry.max_loops = tableData.getIntField("max_loops", 0); + entry.animation_length = tableData.getFloatField("animation_length", 0.0f); + entry.hideEquip = tableData.getIntField("hideEquip", 0) == 1; + entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", 0) == 1; + entry.restartable = tableData.getIntField("restartable", 0) == 1; entry.face_animation_name = tableData.getStringField("face_animation_name", ""); - entry.priority = tableData.getFloatField("priority", -1.0f); - entry.blendTime = tableData.getFloatField("blendTime", -1.0f); + entry.priority = tableData.getFloatField("priority", 0.0f); + entry.blendTime = tableData.getFloatField("blendTime", 0.0f); - this->entries.push_back(entry); + this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry); tableData.nextRow(); - } + } while (!tableData.eof()); tableData.finalize(); + + return true; } -std::vector CDAnimationsTable::Query(std::function predicate) { - - std::vector data = cpplinq::from(this->entries) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data; +void CDAnimationsTable::CacheAnimations(const CDAnimationKey animationKey) { + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Animations WHERE animationGroupID = ? and animation_type = ?"); + query.bind(1, static_cast(animationKey.second)); + query.bind(2, animationKey.first.c_str()); + // If we received a bad lookup, cache it anyways so we do not run the query again. + if (!CacheData(query)) { + this->animations[animationKey]; + } } -std::vector CDAnimationsTable::GetEntries(void) const { - return this->entries; +void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) { + auto animationEntryCached = this->animations.find(CDAnimationKey("", animationGroupID)); + if (animationEntryCached != this->animations.end()) { + return; + } + + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Animations WHERE animationGroupID = ?"); + query.bind(1, static_cast(animationGroupID)); + + // Cache the query so we don't run the query again. + CacheData(query); + this->animations[CDAnimationKey("", animationGroupID)]; } +CDAnimationLookupResult CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) { + CDAnimationKey animationKey(animationType, animationGroupID); + auto randomAnimation = GeneralUtils::GenerateRandomNumber(0, 1); + auto animationEntryCached = this->animations.find(animationKey); + if (animationEntryCached == this->animations.end()) { + this->CacheAnimations(animationKey); + } + + auto animationEntry = this->animations.find(animationKey); + + // If we have only one animation, return it regardless of the chance to play. + if (animationEntry->second.size() == 1) { + return CDAnimationLookupResult(animationEntry->second.front()); + } + + for (auto& animationEntry : animationEntry->second) { + randomAnimation -= animationEntry.chance_to_play; + // This is how the client gets the random animation. + if (animationEntry.animation_name != previousAnimationName && randomAnimation <= 0.0f) return CDAnimationLookupResult(animationEntry); + } + + return CDAnimationLookupResult(); +} diff --git a/dDatabase/Tables/CDAnimationsTable.h b/dDatabase/Tables/CDAnimationsTable.h index 43400abf..b92e37cc 100644 --- a/dDatabase/Tables/CDAnimationsTable.h +++ b/dDatabase/Tables/CDAnimationsTable.h @@ -3,9 +3,10 @@ // Custom Classes #include "CDTable.h" -struct CDAnimations { - unsigned int animationGroupID; //!< The animation group ID - std::string animation_type; //!< The animation type +struct CDAnimation { + // unsigned int animationGroupID; + // std::string animation_type; + // The above two are a pair to represent a primary key in the map. std::string animation_name; //!< The animation name float chance_to_play; //!< The chance to play the animation unsigned int min_loops; //!< The minimum number of loops @@ -19,15 +20,20 @@ struct CDAnimations { float blendTime; //!< The blend time }; +typedef LookupResult CDAnimationLookupResult; class CDAnimationsTable : public CDTable { -private: - std::vector entries; - + typedef int32_t AnimationGroupID; + typedef std::string AnimationID; + typedef std::pair CDAnimationKey; public: - CDAnimationsTable(); - // Queries the table with a custom "where" clause - std::vector Query(std::function predicate); - - std::vector GetEntries(void) const; + CDAnimationLookupResult GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID); + void CacheAnimationGroup(AnimationGroupID animationGroupID); +private: + void CacheAnimations(const CDAnimationKey animationKey); + bool CacheData(CppSQLite3Statement queryToCache); + /** + * Each animation type has a vector of animations. This is because there can be animations have a percent chance to play so one is selected at random. + */ + std::map> animations; }; diff --git a/dDatabase/Tables/CDComponentsRegistryTable.cpp b/dDatabase/Tables/CDComponentsRegistryTable.cpp index 32012f6c..f553e23c 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.cpp +++ b/dDatabase/Tables/CDComponentsRegistryTable.cpp @@ -1,93 +1,31 @@ #include "CDComponentsRegistryTable.h" #include "eReplicaComponentType.h" +#include "dLogger.h" +#include "Game.h" -#define CDCLIENT_CACHE_ALL +uint64_t CalculateId(uint64_t lhs, uint64_t rhs) { + return (lhs << 32) | rhs; +} -CDComponentsRegistryTable::CDComponentsRegistryTable(void) { +void CDComponentsRegistryTable::ReadRow(CppSQLite3Query& rowData) { + uint32_t id = rowData.getIntField("id", -1); + eReplicaComponentType component_type = static_cast(rowData.getIntField("component_type", 0)); + uint32_t component_id = rowData.getIntField("component_id", -1); -#ifdef CDCLIENT_CACHE_ALL - // First, get the size of the table - unsigned int size = 0; - auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ComponentsRegistry"); - while (!tableSize.eof()) { - size = tableSize.getIntField(0, 0); + auto insertedEntry = this->mappedEntries.insert_or_assign(CalculateId(id, static_cast(component_type)), component_id); + DluAssert(insertedEntry.second == true); +} - tableSize.nextRow(); - } - - tableSize.finalize(); - - // Reserve the size - //this->entries.reserve(size); - - // Now get the data +CDComponentsRegistryTable::CDComponentsRegistryTable() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry"); while (!tableData.eof()) { - CDComponentsRegistry entry; - entry.id = tableData.getIntField("id", -1); - entry.component_type = static_cast(tableData.getIntField("component_type", 0)); - entry.component_id = tableData.getIntField("component_id", -1); - - this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id); - + ReadRow(tableData); tableData.nextRow(); } - tableData.finalize(); -#endif } int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) { - const auto& iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); - - if (iter == this->mappedEntries.end()) { - return defaultValue; - } - - return iter->second; - -#ifndef CDCLIENT_CACHE_ALL - // Now get the data - std::stringstream query; - - query << "SELECT * FROM ComponentsRegistry WHERE id = " << std::to_string(id); - - auto tableData = CDClientDatabase::ExecuteQuery(query.str()); - while (!tableData.eof()) { - CDComponentsRegistry entry; - entry.id = tableData.getIntField("id", -1); - entry.component_type = tableData.getIntField("component_type", -1); - entry.component_id = tableData.getIntField("component_id", -1); - - //this->entries.push_back(entry); - - //Darwin's stuff: - const auto& it = this->mappedEntries.find(entry.id); - if (it != mappedEntries.end()) { - const auto& iter = it->second.find(entry.component_type); - if (iter == it->second.end()) { - it->second.insert(std::make_pair(entry.component_type, entry.component_id)); - } - } else { - std::map map; - map.insert(std::make_pair(entry.component_type, entry.component_id)); - this->mappedEntries.insert(std::make_pair(entry.id, map)); - } - - tableData.nextRow(); - } - - tableData.finalize(); - - const auto& it2 = this->mappedEntries.find(id); - if (it2 != mappedEntries.end()) { - const auto& iter = it2->second.find(componentType); - if (iter != it2->second.end()) { - return iter->second; - } - } - - return defaultValue; -#endif + const auto iter = this->mappedEntries.find(CalculateId(id, static_cast(componentType))); + return iter != this->mappedEntries.end() ? iter->second : defaultValue; } - diff --git a/dDatabase/Tables/CDComponentsRegistryTable.h b/dDatabase/Tables/CDComponentsRegistryTable.h index 990072c9..2e45f293 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.h +++ b/dDatabase/Tables/CDComponentsRegistryTable.h @@ -1,21 +1,15 @@ #pragma once -// Custom Classes #include "CDTable.h" enum class eReplicaComponentType : uint32_t; -struct CDComponentsRegistry { - unsigned int id; //!< The LOT is used as the ID - eReplicaComponentType component_type; //!< See ComponentTypes enum for values - unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0 -}; - class CDComponentsRegistryTable : public CDTable { -private: - std::map mappedEntries; //id, component_type, component_id - public: CDComponentsRegistryTable(); int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0); +private: + void ReadRow(CppSQLite3Query& rowData); +private: + std::unordered_map mappedEntries; }; diff --git a/dDatabase/Tables/CDItemComponentTable.cpp b/dDatabase/Tables/CDItemComponentTable.cpp index 54afc417..d53269c2 100644 --- a/dDatabase/Tables/CDItemComponentTable.cpp +++ b/dDatabase/Tables/CDItemComponentTable.cpp @@ -3,8 +3,7 @@ CDItemComponent CDItemComponentTable::Default = {}; -//! Constructor -CDItemComponentTable::CDItemComponentTable(void) { +CDItemComponentTable::CDItemComponentTable() { Default = CDItemComponent(); #ifdef CDCLIENT_CACHE_ALL @@ -55,13 +54,13 @@ CDItemComponentTable::CDItemComponentTable(void) { entry.currencyLOT = tableData.getIntField("currencyLOT", -1); entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1); entry.subItems = tableData.getStringField("subItems", ""); - entry.audioEventUse = tableData.getStringField("audioEventUse", ""); + UNUSED_COLUMN(entry.audioEventUse = tableData.getStringField("audioEventUse", "");) entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false; entry.commendationLOT = tableData.getIntField("commendationLOT", -1); entry.commendationCost = tableData.getIntField("commendationCost", -1); - entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", ""); + UNUSED_COLUMN(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "");) entry.currencyCosts = tableData.getStringField("currencyCosts", ""); - entry.ingredientInfo = tableData.getStringField("ingredientInfo", ""); + UNUSED_COLUMN(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "");) entry.locStatus = tableData.getIntField("locStatus", -1); entry.forgeType = tableData.getIntField("forgeType", -1); entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f); @@ -74,8 +73,8 @@ CDItemComponentTable::CDItemComponentTable(void) { #endif } -const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int skillID) { - const auto& it = this->entries.find(skillID); +const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int id) { + const auto& it = this->entries.find(id); if (it != this->entries.end()) { return it->second; } @@ -83,11 +82,11 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s #ifndef CDCLIENT_CACHE_ALL std::stringstream query; - query << "SELECT * FROM ItemComponent WHERE id = " << std::to_string(skillID); + query << "SELECT * FROM ItemComponent WHERE id = " << std::to_string(id); auto tableData = CDClientDatabase::ExecuteQuery(query.str()); if (tableData.eof()) { - entries.insert(std::make_pair(skillID, Default)); + entries.insert(std::make_pair(id, Default)); return Default; } @@ -125,13 +124,13 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s entry.currencyLOT = tableData.getIntField("currencyLOT", -1); entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1); entry.subItems = tableData.getStringField("subItems", ""); - UNUSED(entry.audioEventUse = tableData.getStringField("audioEventUse", "")); + UNUSED_COLUMN(entry.audioEventUse = tableData.getStringField("audioEventUse", "")); entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false; entry.commendationLOT = tableData.getIntField("commendationLOT", -1); entry.commendationCost = tableData.getIntField("commendationCost", -1); - UNUSED(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "")); + UNUSED_COLUMN(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "")); entry.currencyCosts = tableData.getStringField("currencyCosts", ""); - UNUSED(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "")); + UNUSED_COLUMN(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "")); entry.locStatus = tableData.getIntField("locStatus", -1); entry.forgeType = tableData.getIntField("forgeType", -1); entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f); @@ -140,7 +139,7 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s tableData.nextRow(); } - const auto& it2 = this->entries.find(skillID); + const auto& it2 = this->entries.find(id); if (it2 != this->entries.end()) { return it2->second; } @@ -169,4 +168,3 @@ std::map CDItemComponentTable::ParseCraftingCurrencies(const CDIt return currencies; } - diff --git a/dDatabase/Tables/CDItemComponentTable.h b/dDatabase/Tables/CDItemComponentTable.h index 11c34dd6..1cc46b4a 100644 --- a/dDatabase/Tables/CDItemComponentTable.h +++ b/dDatabase/Tables/CDItemComponentTable.h @@ -5,60 +5,60 @@ #include "dCommonVars.h" struct CDItemComponent { - unsigned int id; //!< The Component ID + uint32_t id; //!< The Component ID std::string equipLocation; //!< The equip location - unsigned int baseValue; //!< The monetary base value of the item + uint32_t baseValue; //!< The monetary base value of the item bool isKitPiece; //!< Whether or not the item belongs to a kit - unsigned int rarity; //!< The rarity of the item - unsigned int itemType; //!< The item type + uint32_t rarity; //!< The rarity of the item + uint32_t itemType; //!< The item type int64_t itemInfo; //!< The item info bool inLootTable; //!< Whether or not the item is in a loot table bool inVendor; //!< Whether or not the item is in a vendor inventory bool isUnique; //!< ??? bool isBOP; //!< ??? bool isBOE; //!< ??? - unsigned int reqFlagID; //!< User must have completed this flag to get the item - unsigned int reqSpecialtyID; //!< ??? - unsigned int reqSpecRank; //!< ??? - unsigned int reqAchievementID; //!< The required achievement must be completed - unsigned int stackSize; //!< The stack size of the item - unsigned int color1; //!< Something to do with item color... - unsigned int decal; //!< The decal of the item - unsigned int offsetGroupID; //!< Something to do with group IDs - unsigned int buildTypes; //!< Something to do with building + uint32_t reqFlagID; //!< User must have completed this flag to get the item + uint32_t reqSpecialtyID; //!< ??? + uint32_t reqSpecRank; //!< ??? + uint32_t reqAchievementID; //!< The required achievement must be completed + uint32_t stackSize; //!< The stack size of the item + uint32_t color1; //!< Something to do with item color... + uint32_t decal; //!< The decal of the item + uint32_t offsetGroupID; //!< Something to do with group IDs + uint32_t buildTypes; //!< Something to do with building std::string reqPrecondition; //!< The required precondition - unsigned int animationFlag; //!< The Animation Flag - unsigned int equipEffects; //!< The effect played when the item is equipped + uint32_t animationFlag; //!< The Animation Flag + uint32_t equipEffects; //!< The effect played when the item is equipped bool readyForQA; //!< ??? - unsigned int itemRating; //!< ??? + uint32_t itemRating; //!< ??? bool isTwoHanded; //!< Whether or not the item is double handed - unsigned int minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object? - unsigned int delResIndex; //!< ??? - unsigned int currencyLOT; //!< ??? - unsigned int altCurrencyCost; //!< ??? + uint32_t minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object? + uint32_t delResIndex; //!< ??? + uint32_t currencyLOT; //!< ??? + uint32_t altCurrencyCost; //!< ??? std::string subItems; //!< A comma seperate string of sub items (maybe for multi-itemed things like faction test gear set) - UNUSED(std::string audioEventUse); //!< ??? + UNUSED_COLUMN(std::string audioEventUse); //!< ??? bool noEquipAnimation; //!< Whether or not there is an equip animation - unsigned int commendationLOT; //!< The commendation LOT - unsigned int commendationCost; //!< The commendation cost - UNUSED(std::string audioEquipMetaEventSet); //!< ??? + uint32_t commendationLOT; //!< The commendation LOT + uint32_t commendationCost; //!< The commendation cost + UNUSED_COLUMN(std::string audioEquipMetaEventSet); //!< ??? std::string currencyCosts; //!< Used for crafting - UNUSED(std::string ingredientInfo); //!< Unused - unsigned int locStatus; //!< ??? - unsigned int forgeType; //!< Forge Type + UNUSED_COLUMN(std::string ingredientInfo); //!< Unused + uint32_t locStatus; //!< ??? + uint32_t forgeType; //!< Forge Type float SellMultiplier; //!< Something to do with early vendors perhaps (but replaced) }; class CDItemComponentTable : public CDTable { private: - std::map entries; + std::map entries; public: CDItemComponentTable(); static std::map ParseCraftingCurrencies(const CDItemComponent& itemComponent); // Gets an entry by ID - const CDItemComponent& GetItemComponentByID(unsigned int skillID); + const CDItemComponent& GetItemComponentByID(uint32_t id); static CDItemComponent Default; }; diff --git a/dDatabase/Tables/CDLootMatrixTable.cpp b/dDatabase/Tables/CDLootMatrixTable.cpp index 8f25e8a3..c6c5cd8e 100644 --- a/dDatabase/Tables/CDLootMatrixTable.cpp +++ b/dDatabase/Tables/CDLootMatrixTable.cpp @@ -29,7 +29,7 @@ CDLootMatrixTable::CDLootMatrixTable(void) { entry.maxToDrop = tableData.getIntField("maxToDrop", -1); entry.id = tableData.getIntField("id", -1); entry.flagID = tableData.getIntField("flagID", -1); - UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); this->entries.push_back(entry); tableData.nextRow(); diff --git a/dDatabase/Tables/CDLootMatrixTable.h b/dDatabase/Tables/CDLootMatrixTable.h index c6035841..c56be7a8 100644 --- a/dDatabase/Tables/CDLootMatrixTable.h +++ b/dDatabase/Tables/CDLootMatrixTable.h @@ -12,7 +12,7 @@ struct CDLootMatrix { unsigned int maxToDrop; //!< The maximum amount of loot from this matrix to drop unsigned int id; //!< The ID of the Loot Matrix unsigned int flagID; //!< ??? - UNUSED(std::string gate_version); //!< The Gate Version + UNUSED_COLUMN(std::string gate_version); //!< The Gate Version }; class CDLootMatrixTable : public CDTable { diff --git a/dDatabase/Tables/CDMissionTasksTable.cpp b/dDatabase/Tables/CDMissionTasksTable.cpp index f32dca1b..ca65c85f 100644 --- a/dDatabase/Tables/CDMissionTasksTable.cpp +++ b/dDatabase/Tables/CDMissionTasksTable.cpp @@ -22,18 +22,18 @@ CDMissionTasksTable::CDMissionTasksTable(void) { while (!tableData.eof()) { CDMissionTasks entry; entry.id = tableData.getIntField("id", -1); - UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); entry.taskType = tableData.getIntField("taskType", -1); entry.target = tableData.getIntField("target", -1); entry.targetGroup = tableData.getStringField("targetGroup", ""); entry.targetValue = tableData.getIntField("targetValue", -1); entry.taskParam1 = tableData.getStringField("taskParam1", ""); - UNUSED(entry.largeTaskIcon = tableData.getStringField("largeTaskIcon", "")); - UNUSED(entry.IconID = tableData.getIntField("IconID", -1)); + UNUSED_COLUMN(entry.largeTaskIcon = tableData.getStringField("largeTaskIcon", "")); + UNUSED_COLUMN(entry.IconID = tableData.getIntField("IconID", -1)); entry.uid = tableData.getIntField("uid", -1); - UNUSED(entry.largeTaskIconID = tableData.getIntField("largeTaskIconID", -1)); - UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); - UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED_COLUMN(entry.largeTaskIconID = tableData.getIntField("largeTaskIconID", -1)); + UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); + UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); this->entries.push_back(entry); tableData.nextRow(); diff --git a/dDatabase/Tables/CDMissionTasksTable.h b/dDatabase/Tables/CDMissionTasksTable.h index fa213faf..f5e780f5 100644 --- a/dDatabase/Tables/CDMissionTasksTable.h +++ b/dDatabase/Tables/CDMissionTasksTable.h @@ -5,18 +5,18 @@ struct CDMissionTasks { unsigned int id; //!< The Mission ID that the task belongs to - UNUSED(unsigned int locStatus); //!< ??? + UNUSED_COLUMN(unsigned int locStatus); //!< ??? unsigned int taskType; //!< The task type unsigned int target; //!< The mission target std::string targetGroup; //!< The mission target group int targetValue; //!< The target value std::string taskParam1; //!< The task param 1 - UNUSED(std::string largeTaskIcon); //!< ??? - UNUSED(unsigned int IconID); //!< ??? + UNUSED_COLUMN(std::string largeTaskIcon); //!< ??? + UNUSED_COLUMN(unsigned int IconID); //!< ??? unsigned int uid; //!< ??? - UNUSED(unsigned int largeTaskIconID); //!< ??? - UNUSED(bool localize); //!< Whether or not the task should be localized - UNUSED(std::string gate_version); //!< ??? + UNUSED_COLUMN(unsigned int largeTaskIconID); //!< ??? + UNUSED_COLUMN(bool localize); //!< Whether or not the task should be localized + UNUSED_COLUMN(std::string gate_version); //!< ??? }; class CDMissionTasksTable : public CDTable { diff --git a/dDatabase/Tables/CDMissionsTable.cpp b/dDatabase/Tables/CDMissionsTable.cpp index d4ee40ae..53137560 100644 --- a/dDatabase/Tables/CDMissionsTable.cpp +++ b/dDatabase/Tables/CDMissionsTable.cpp @@ -71,9 +71,9 @@ CDMissionsTable::CDMissionsTable(void) { entry.isRandom = tableData.getIntField("isRandom", -1) == 1 ? true : false; entry.randomPool = tableData.getStringField("randomPool", ""); entry.UIPrereqID = tableData.getIntField("UIPrereqID", -1); - UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED(entry.HUDStates = tableData.getStringField("HUDStates", "")); - UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED_COLUMN(entry.HUDStates = tableData.getStringField("HUDStates", "")); + UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1); this->entries.push_back(entry); diff --git a/dDatabase/Tables/CDMissionsTable.h b/dDatabase/Tables/CDMissionsTable.h index e6a44b02..8e3f2039 100644 --- a/dDatabase/Tables/CDMissionsTable.h +++ b/dDatabase/Tables/CDMissionsTable.h @@ -54,9 +54,9 @@ struct CDMissions { bool isRandom; //!< ??? std::string randomPool; //!< ??? int UIPrereqID; //!< ??? - UNUSED(std::string gate_version); //!< The gate version - UNUSED(std::string HUDStates); //!< ??? - UNUSED(int locStatus); //!< ??? + UNUSED_COLUMN(std::string gate_version); //!< The gate version + UNUSED_COLUMN(std::string HUDStates); //!< ??? + UNUSED_COLUMN(int locStatus); //!< ??? int reward_bankinventory; //!< The amount of bank space this mission rewards }; diff --git a/dDatabase/Tables/CDObjectsTable.cpp b/dDatabase/Tables/CDObjectsTable.cpp index c68c3e6a..e28fb100 100644 --- a/dDatabase/Tables/CDObjectsTable.cpp +++ b/dDatabase/Tables/CDObjectsTable.cpp @@ -65,18 +65,18 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) { CDObjects entry; entry.id = tableData.getIntField("id", -1); entry.name = tableData.getStringField("name", ""); - UNUSED(entry.placeable = tableData.getIntField("placeable", -1)); + UNUSED_COLUMN(entry.placeable = tableData.getIntField("placeable", -1)); entry.type = tableData.getStringField("type", ""); - UNUSED(ntry.description = tableData.getStringField(4, "")); - UNUSED(entry.localize = tableData.getIntField("localize", -1)); - UNUSED(entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1)); - UNUSED(entry.displayName = tableData.getStringField("displayName", "")); + UNUSED_COLUMN(ntry.description = tableData.getStringField(4, "")); + UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1)); + UNUSED_COLUMN(entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1)); + UNUSED_COLUMN(entry.displayName = tableData.getStringField("displayName", "")); entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f); - UNUSED(entry.nametag = tableData.getIntField("nametag", -1)); - UNUSED(entry._internalNotes = tableData.getStringField("_internalNotes", "")); - UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); - UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED(entry.HQ_valid = tableData.getIntField("HQ_valid", -1)); + UNUSED_COLUMN(entry.nametag = tableData.getIntField("nametag", -1)); + UNUSED_COLUMN(entry._internalNotes = tableData.getStringField("_internalNotes", "")); + UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED_COLUMN(entry.HQ_valid = tableData.getIntField("HQ_valid", -1)); this->entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); diff --git a/dDatabase/Tables/CDObjectsTable.h b/dDatabase/Tables/CDObjectsTable.h index 171eddef..dc6cc884 100644 --- a/dDatabase/Tables/CDObjectsTable.h +++ b/dDatabase/Tables/CDObjectsTable.h @@ -6,18 +6,18 @@ struct CDObjects { unsigned int id; //!< The LOT of the object std::string name; //!< The internal name of the object - UNUSED(unsigned int placeable); //!< Whether or not the object is placable + UNUSED_COLUMN(unsigned int placeable); //!< Whether or not the object is placable std::string type; //!< The object type - UNUSED(std::string description); //!< An internal description of the object - UNUSED(unsigned int localize); //!< Whether or not the object should localize - UNUSED(unsigned int npcTemplateID); //!< Something related to NPCs... - UNUSED(std::string displayName); //!< The display name of the object + UNUSED_COLUMN(std::string description); //!< An internal description of the object + UNUSED_COLUMN(unsigned int localize); //!< Whether or not the object should localize + UNUSED_COLUMN(unsigned int npcTemplateID); //!< Something related to NPCs... + UNUSED_COLUMN(std::string displayName); //!< The display name of the object float interactionDistance; //!< The interaction distance of the object - UNUSED(unsigned int nametag); //!< ??? - UNUSED(std::string _internalNotes); //!< Some internal notes (rarely used) - UNUSED(unsigned int locStatus); //!< ??? - UNUSED(std::string gate_version); //!< The gate version for the object - UNUSED(unsigned int HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com + UNUSED_COLUMN(unsigned int nametag); //!< ??? + UNUSED_COLUMN(std::string _internalNotes); //!< Some internal notes (rarely used) + UNUSED_COLUMN(unsigned int locStatus); //!< ??? + UNUSED_COLUMN(std::string gate_version); //!< The gate version for the object + UNUSED_COLUMN(unsigned int HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com }; class CDObjectsTable : public CDTable { diff --git a/dDatabase/Tables/CDPhysicsComponentTable.cpp b/dDatabase/Tables/CDPhysicsComponentTable.cpp index bb21ed7f..8c705f5b 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.cpp +++ b/dDatabase/Tables/CDPhysicsComponentTable.cpp @@ -7,19 +7,19 @@ CDPhysicsComponentTable::CDPhysicsComponentTable(void) { entry->id = tableData.getIntField("id", -1); entry->bStatic = tableData.getIntField("static", -1) != 0; entry->physicsAsset = tableData.getStringField("physics_asset", ""); - UNUSED(entry->jump = tableData.getIntField("jump", -1) != 0); - UNUSED(entry->doublejump = tableData.getIntField("doublejump", -1) != 0); + UNUSED_COLUMN(entry->jump = tableData.getIntField("jump", -1) != 0); + UNUSED_COLUMN(entry->doublejump = tableData.getIntField("doublejump", -1) != 0); entry->speed = tableData.getFloatField("speed", -1); - UNUSED(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1)); + UNUSED_COLUMN(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1)); entry->playerHeight = tableData.getFloatField("playerHeight"); entry->playerRadius = tableData.getFloatField("playerRadius"); entry->pcShapeType = tableData.getIntField("pcShapeType"); entry->collisionGroup = tableData.getIntField("collisionGroup"); - UNUSED(entry->airSpeed = tableData.getFloatField("airSpeed")); - UNUSED(entry->boundaryAsset = tableData.getStringField("boundaryAsset")); - UNUSED(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed")); - UNUSED(entry->friction = tableData.getFloatField("friction")); - UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset")); + UNUSED_COLUMN(entry->airSpeed = tableData.getFloatField("airSpeed")); + UNUSED_COLUMN(entry->boundaryAsset = tableData.getStringField("boundaryAsset")); + UNUSED_COLUMN(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed")); + UNUSED_COLUMN(entry->friction = tableData.getFloatField("friction")); + UNUSED_COLUMN(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset")); m_entries.insert(std::make_pair(entry->id, entry)); tableData.nextRow(); diff --git a/dDatabase/Tables/CDPhysicsComponentTable.h b/dDatabase/Tables/CDPhysicsComponentTable.h index e63d337d..ee4dddc1 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.h +++ b/dDatabase/Tables/CDPhysicsComponentTable.h @@ -6,19 +6,19 @@ struct CDPhysicsComponent { int id; bool bStatic; std::string physicsAsset; - UNUSED(bool jump); - UNUSED(bool doublejump); + UNUSED_COLUMN(bool jump); + UNUSED_COLUMN(bool doublejump); float speed; - UNUSED(float rotSpeed); + UNUSED_COLUMN(float rotSpeed); float playerHeight; float playerRadius; int pcShapeType; int collisionGroup; - UNUSED(float airSpeed); - UNUSED(std::string boundaryAsset); - UNUSED(float jumpAirSpeed); - UNUSED(float friction); - UNUSED(std::string gravityVolumeAsset); + UNUSED_COLUMN(float airSpeed); + UNUSED_COLUMN(std::string boundaryAsset); + UNUSED_COLUMN(float jumpAirSpeed); + UNUSED_COLUMN(float friction); + UNUSED_COLUMN(std::string gravityVolumeAsset); }; class CDPhysicsComponentTable : public CDTable { diff --git a/dDatabase/Tables/CDSkillBehaviorTable.cpp b/dDatabase/Tables/CDSkillBehaviorTable.cpp index c5df78ef..8420a8c6 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.cpp +++ b/dDatabase/Tables/CDSkillBehaviorTable.cpp @@ -24,24 +24,24 @@ CDSkillBehaviorTable::CDSkillBehaviorTable(void) { while (!tableData.eof()) { CDSkillBehavior entry; entry.skillID = tableData.getIntField("skillID", -1); - UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); entry.behaviorID = tableData.getIntField("behaviorID", -1); entry.imaginationcost = tableData.getIntField("imaginationcost", -1); entry.cooldowngroup = tableData.getIntField("cooldowngroup", -1); entry.cooldown = tableData.getFloatField("cooldown", -1.0f); - UNUSED(entry.isNpcEditor = tableData.getIntField("isNpcEditor", -1) == 1 ? true : false); - UNUSED(entry.skillIcon = tableData.getIntField("skillIcon", -1)); - UNUSED(entry.oomSkillID = tableData.getStringField("oomSkillID", "")); - UNUSED(entry.oomBehaviorEffectID = tableData.getIntField("oomBehaviorEffectID", -1)); - UNUSED(entry.castTypeDesc = tableData.getIntField("castTypeDesc", -1)); - UNUSED(entry.imBonusUI = tableData.getIntField("imBonusUI", -1)); - UNUSED(entry.lifeBonusUI = tableData.getIntField("lifeBonusUI", -1)); - UNUSED(entry.armorBonusUI = tableData.getIntField("armorBonusUI", -1)); - UNUSED(entry.damageUI = tableData.getIntField("damageUI", -1)); - UNUSED(entry.hideIcon = tableData.getIntField("hideIcon", -1) == 1 ? true : false); - UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); - UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED(entry.cancelType = tableData.getIntField("cancelType", -1)); + UNUSED_COLUMN(entry.isNpcEditor = tableData.getIntField("isNpcEditor", -1) == 1 ? true : false); + UNUSED_COLUMN(entry.skillIcon = tableData.getIntField("skillIcon", -1)); + UNUSED_COLUMN(entry.oomSkillID = tableData.getStringField("oomSkillID", "")); + UNUSED_COLUMN(entry.oomBehaviorEffectID = tableData.getIntField("oomBehaviorEffectID", -1)); + UNUSED_COLUMN(entry.castTypeDesc = tableData.getIntField("castTypeDesc", -1)); + UNUSED_COLUMN(entry.imBonusUI = tableData.getIntField("imBonusUI", -1)); + UNUSED_COLUMN(entry.lifeBonusUI = tableData.getIntField("lifeBonusUI", -1)); + UNUSED_COLUMN(entry.armorBonusUI = tableData.getIntField("armorBonusUI", -1)); + UNUSED_COLUMN(entry.damageUI = tableData.getIntField("damageUI", -1)); + UNUSED_COLUMN(entry.hideIcon = tableData.getIntField("hideIcon", -1) == 1 ? true : false); + UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); + UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED_COLUMN(entry.cancelType = tableData.getIntField("cancelType", -1)); this->entries.insert(std::make_pair(entry.skillID, entry)); //this->entries.push_back(entry); diff --git a/dDatabase/Tables/CDSkillBehaviorTable.h b/dDatabase/Tables/CDSkillBehaviorTable.h index eb3094e0..4e6bddb9 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.h +++ b/dDatabase/Tables/CDSkillBehaviorTable.h @@ -5,24 +5,24 @@ struct CDSkillBehavior { unsigned int skillID; //!< The Skill ID of the skill - UNUSED(unsigned int locStatus); //!< ?? + UNUSED_COLUMN(unsigned int locStatus); //!< ?? unsigned int behaviorID; //!< The Behavior ID of the skill unsigned int imaginationcost; //!< The imagination cost of the skill unsigned int cooldowngroup; //!< The cooldown group ID of the skill float cooldown; //!< The cooldown time of the skill - UNUSED(bool isNpcEditor); //!< ??? - UNUSED(unsigned int skillIcon); //!< The Skill Icon ID - UNUSED(std::string oomSkillID); //!< ??? - UNUSED(unsigned int oomBehaviorEffectID); //!< ??? - UNUSED(unsigned int castTypeDesc); //!< The cast type description(?) - UNUSED(unsigned int imBonusUI); //!< The imagination bonus of the skill - UNUSED(nsigned int lifeBonusUI); //!< The life bonus of the skill - UNUSED(unsigned int armorBonusUI); //!< The armor bonus of the skill - UNUSED(unsigned int damageUI); //!< ??? - UNUSED(bool hideIcon); //!< Whether or not to show the icon - UNUSED(bool localize); //!< ??? - UNUSED(std::string gate_version); //!< ??? - UNUSED(unsigned int cancelType); //!< The cancel type (?) + UNUSED_COLUMN(bool isNpcEditor); //!< ??? + UNUSED_COLUMN(unsigned int skillIcon); //!< The Skill Icon ID + UNUSED_COLUMN(std::string oomSkillID); //!< ??? + UNUSED_COLUMN(unsigned int oomBehaviorEffectID); //!< ??? + UNUSED_COLUMN(unsigned int castTypeDesc); //!< The cast type description(?) + UNUSED_COLUMN(unsigned int imBonusUI); //!< The imagination bonus of the skill + UNUSED_COLUMN(nsigned int lifeBonusUI); //!< The life bonus of the skill + UNUSED_COLUMN(unsigned int armorBonusUI); //!< The armor bonus of the skill + UNUSED_COLUMN(unsigned int damageUI); //!< ??? + UNUSED_COLUMN(bool hideIcon); //!< Whether or not to show the icon + UNUSED_COLUMN(bool localize); //!< ??? + UNUSED_COLUMN(std::string gate_version); //!< ??? + UNUSED_COLUMN(unsigned int cancelType); //!< The cancel type (?) }; class CDSkillBehaviorTable : public CDTable { diff --git a/dDatabase/Tables/CDTable.h b/dDatabase/Tables/CDTable.h index fca16eb8..45c67b0d 100644 --- a/dDatabase/Tables/CDTable.h +++ b/dDatabase/Tables/CDTable.h @@ -2,6 +2,7 @@ #include "CDClientDatabase.h" #include "Singleton.h" +#include "DluAssert.h" #include #include @@ -15,6 +16,9 @@ #endif #include "cpplinq.hpp" +// Enable this to skip some unused columns in some tables +#define UNUSED_COLUMN(v) + #pragma warning (disable : 4244) //Disable double to float conversion warnings #pragma warning (disable : 4715) //Disable "not all control paths return a value" @@ -23,3 +27,15 @@ class CDTable : public Singleton { protected: virtual ~CDTable() = default; }; + +template +class LookupResult { + typedef std::pair DataType; +public: + LookupResult() { m_data.first = T(); m_data.second = false; }; + LookupResult(T& data) { m_data.first = data; m_data.second = true; }; + inline const T& Data() { return m_data.first; }; + inline const bool& FoundData() { return m_data.second; }; +private: + DataType m_data; +}; diff --git a/dDatabase/Tables/CDZoneTableTable.cpp b/dDatabase/Tables/CDZoneTableTable.cpp index bafbf8fe..89158dd7 100644 --- a/dDatabase/Tables/CDZoneTableTable.cpp +++ b/dDatabase/Tables/CDZoneTableTable.cpp @@ -26,25 +26,25 @@ CDZoneTableTable::CDZoneTableTable(void) { entry.ghostdistance = tableData.getFloatField("ghostdistance", -1.0f); entry.population_soft_cap = tableData.getIntField("population_soft_cap", -1); entry.population_hard_cap = tableData.getIntField("population_hard_cap", -1); - UNUSED(entry.DisplayDescription = tableData.getStringField("DisplayDescription", "")); - UNUSED(entry.mapFolder = tableData.getStringField("mapFolder", "")); + UNUSED_COLUMN(entry.DisplayDescription = tableData.getStringField("DisplayDescription", "")); + UNUSED_COLUMN(entry.mapFolder = tableData.getStringField("mapFolder", "")); entry.smashableMinDistance = tableData.getFloatField("smashableMinDistance", -1.0f); entry.smashableMaxDistance = tableData.getFloatField("smashableMaxDistance", -1.0f); - UNUSED(entry.mixerProgram = tableData.getStringField("mixerProgram", "")); - UNUSED(entry.clientPhysicsFramerate = tableData.getStringField("clientPhysicsFramerate", "")); - UNUSED(entry.serverPhysicsFramerate = tableData.getStringField("serverPhysicsFramerate", "")); + UNUSED_COLUMN(entry.mixerProgram = tableData.getStringField("mixerProgram", "")); + UNUSED_COLUMN(entry.clientPhysicsFramerate = tableData.getStringField("clientPhysicsFramerate", "")); + UNUSED_COLUMN(entry.serverPhysicsFramerate = tableData.getStringField("serverPhysicsFramerate", "")); entry.zoneControlTemplate = tableData.getIntField("zoneControlTemplate", -1); entry.widthInChunks = tableData.getIntField("widthInChunks", -1); entry.heightInChunks = tableData.getIntField("heightInChunks", -1); entry.petsAllowed = tableData.getIntField("petsAllowed", -1) == 1 ? true : false; entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false; entry.fZoneWeight = tableData.getFloatField("fZoneWeight", -1.0f); - UNUSED(entry.thumbnail = tableData.getStringField("thumbnail", "")); + UNUSED_COLUMN(entry.thumbnail = tableData.getStringField("thumbnail", "")); entry.PlayerLoseCoinsOnDeath = tableData.getIntField("PlayerLoseCoinsOnDeath", -1) == 1 ? true : false; - UNUSED(entry.disableSaveLoc = tableData.getIntField("disableSaveLoc", -1) == 1 ? true : false); + UNUSED_COLUMN(entry.disableSaveLoc = tableData.getIntField("disableSaveLoc", -1) == 1 ? true : false); entry.teamRadius = tableData.getFloatField("teamRadius", -1.0f); - UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED(entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false); + UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED_COLUMN(entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false); this->m_Entries.insert(std::make_pair(entry.zoneID, entry)); tableData.nextRow(); diff --git a/dDatabase/Tables/CDZoneTableTable.h b/dDatabase/Tables/CDZoneTableTable.h index f844fd25..e46a87ee 100644 --- a/dDatabase/Tables/CDZoneTableTable.h +++ b/dDatabase/Tables/CDZoneTableTable.h @@ -12,25 +12,25 @@ struct CDZoneTable { float ghostdistance; //!< The ghosting distance unsigned int population_soft_cap; //!< The "soft cap" on the world population unsigned int population_hard_cap; //!< The "hard cap" on the world population - UNUSED(std::string DisplayDescription); //!< The display description of the world - UNUSED(std::string mapFolder); //!< ??? + UNUSED_COLUMN(std::string DisplayDescription); //!< The display description of the world + UNUSED_COLUMN(std::string mapFolder); //!< ??? float smashableMinDistance; //!< The minimum smashable distance? float smashableMaxDistance; //!< The maximum smashable distance? - UNUSED(std::string mixerProgram); //!< ??? - UNUSED(std::string clientPhysicsFramerate); //!< The client physics framerate - UNUSED(std::string serverPhysicsFramerate); //!< The server physics framerate + UNUSED_COLUMN(std::string mixerProgram); //!< ??? + UNUSED_COLUMN(std::string clientPhysicsFramerate); //!< The client physics framerate + UNUSED_COLUMN(std::string serverPhysicsFramerate); //!< The server physics framerate unsigned int zoneControlTemplate; //!< The Zone Control template unsigned int widthInChunks; //!< The width of the world in chunks unsigned int heightInChunks; //!< The height of the world in chunks bool petsAllowed; //!< Whether or not pets are allowed in the world bool localize; //!< Whether or not the world should be localized float fZoneWeight; //!< ??? - UNUSED(std::string thumbnail); //!< The thumbnail of the world + UNUSED_COLUMN(std::string thumbnail); //!< The thumbnail of the world bool PlayerLoseCoinsOnDeath; //!< Whether or not the user loses coins on death - UNUSED(bool disableSaveLoc); //!< Disables the saving location? + UNUSED_COLUMN(bool disableSaveLoc); //!< Disables the saving location? float teamRadius; //!< ??? - UNUSED(std::string gate_version); //!< The gate version - UNUSED(bool mountsAllowed); //!< Whether or not mounts are allowed + UNUSED_COLUMN(std::string gate_version); //!< The gate version + UNUSED_COLUMN(bool mountsAllowed); //!< Whether or not mounts are allowed }; class CDZoneTableTable : public CDTable { diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 13507527..290f4f7e 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -592,8 +592,9 @@ void Entity::Initialize() { m_Components.insert(std::make_pair(eReplicaComponentType::BOUNCER, comp)); } - if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER) > 0 && m_TemplateID != 2365) || m_Character) { - RenderComponent* render = new RenderComponent(this); + int32_t renderaComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER); + if ((renderaComponentId > 0 && m_TemplateID != 2365) || m_Character) { + RenderComponent* render = new RenderComponent(this, renderaComponentId); m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render)); } diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d85a95d4..5a4754b9 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -277,13 +277,11 @@ void LeaderboardManager::SendLeaderboard(uint32_t gameID, InfoType infoType, boo } LeaderboardType LeaderboardManager::GetLeaderboardType(uint32_t gameID) { - auto* activitiesTable = CDClientManager::Instance().GetTable(); - std::vector activities = activitiesTable->Query([=](const CDActivities& entry) { - return (entry.ActivityID == gameID); - }); + CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); + auto activityResult = activitiesTable->GetActivity(gameID); - for (const auto& activity : activities) { - return static_cast(activity.leaderboardType); + if (activityResult.FoundData()) { + return static_cast(activityResult.Data().leaderboardType); } return LeaderboardType::None; diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 5549f952..f5b7a1a7 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -22,7 +22,7 @@ #include "Database.h" #include "EntityInfo.h" #include "eMissionTaskType.h" - +#include "RenderComponent.h" std::unordered_map PetComponent::buildCache{}; std::unordered_map PetComponent::currentActivities{}; @@ -525,7 +525,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { } GameMessages::SendPlayFXEffect(tamer, -1, u"petceleb", "", LWOOBJID_EMPTY, 1, 1, true); - GameMessages::SendPlayAnimation(tamer, u"rebuild-celebrate"); + RenderComponent::PlayAnimation(tamer, u"rebuild-celebrate"); EntityInfo info{}; info.lot = cached->second.puzzleModelLot; diff --git a/dGame/dComponents/RailActivatorComponent.cpp b/dGame/dComponents/RailActivatorComponent.cpp index 49fc105d..2a12caf8 100644 --- a/dGame/dComponents/RailActivatorComponent.cpp +++ b/dGame/dComponents/RailActivatorComponent.cpp @@ -7,6 +7,8 @@ #include "RebuildComponent.h" #include "Game.h" #include "dLogger.h" +#include "RenderComponent.h" +#include "EntityManager.h" RailActivatorComponent::RailActivatorComponent(Entity* parent, int32_t componentID) : Component(parent) { m_ComponentID = componentID; @@ -56,23 +58,10 @@ void RailActivatorComponent::OnUse(Entity* originator) { GameMessages::SendPlayFXEffect(originator->GetObjectID(), m_StartEffect.first, m_StartEffect.second, std::to_string(m_StartEffect.first)); } - + + float animationLength = 0.5f; if (!m_StartAnimation.empty()) { - GameMessages::SendPlayAnimation(originator, m_StartAnimation); - } - - float animationLength; - - if (m_StartAnimation == u"whirlwind-rail-up-earth") { - animationLength = 1.5f; - } else if (m_StartAnimation == u"whirlwind-rail-up-lightning") { - animationLength = 0.5f; - } else if (m_StartAnimation == u"whirlwind-rail-up-ice") { - animationLength = 0.5f; - } else if (m_StartAnimation == u"whirlwind-rail-up-fire") { - animationLength = 0.5f; - } else { - animationLength = 0.5f; + animationLength = RenderComponent::PlayAnimation(originator, m_StartAnimation); } const auto originatorID = originator->GetObjectID(); @@ -111,7 +100,7 @@ void RailActivatorComponent::OnRailMovementReady(Entity* originator) const { } if (!m_LoopAnimation.empty()) { - GameMessages::SendPlayAnimation(originator, m_LoopAnimation); + RenderComponent::PlayAnimation(originator, m_LoopAnimation); } GameMessages::SendSetRailMovement(originator->GetObjectID(), m_PathDirection, m_Path, m_PathStart, @@ -146,7 +135,7 @@ void RailActivatorComponent::OnCancelRailMovement(Entity* originator) { } if (!m_StopAnimation.empty()) { - GameMessages::SendPlayAnimation(originator, m_StopAnimation); + RenderComponent::PlayAnimation(originator, m_StopAnimation); } // Remove the player after they've signalled they're done railing diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index abd21873..f0b39346 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -16,6 +16,7 @@ #include "Preconditions.h" #include "Loot.h" #include "TeamManager.h" +#include "RenderComponent.h" #include "CppScripts.h" @@ -510,7 +511,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { character->SetPlayerFlag(flagNumber, true); } } - GameMessages::SendPlayAnimation(user, u"rebuild-celebrate", 1.09f); + RenderComponent::PlayAnimation(user, u"rebuild-celebrate", 1.09f); } void RebuildComponent::ResetRebuild(bool failed) { @@ -520,7 +521,7 @@ void RebuildComponent::ResetRebuild(bool failed) { GameMessages::SendEnableRebuild(m_Parent, false, false, failed, eFailReason::REASON_NOT_GIVEN, m_ResetTime, builder->GetObjectID()); if (failed) { - GameMessages::SendPlayAnimation(builder, u"rebuild-fail"); + RenderComponent::PlayAnimation(builder, u"rebuild-fail"); } } diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index ee42acba..bccd6207 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -11,72 +11,34 @@ #include "GameMessages.h" #include "Game.h" #include "dLogger.h" +#include "CDAnimationsTable.h" std::unordered_map RenderComponent::m_DurationCache{}; -RenderComponent::RenderComponent(Entity* parent) : Component(parent) { +RenderComponent::RenderComponent(Entity* parent, int32_t componentId): Component(parent) { m_Effects = std::vector(); + m_LastAnimationName = ""; + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM RenderComponent WHERE id = ?;"); + query.bind(1, componentId); + auto result = query.execQuery(); - return; - - /* - auto* table = CDClientManager::Instance().GetTable(); - - const auto entry = table->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::RENDER); - - std::stringstream query; - - query << "SELECT effect1, effect2, effect3, effect4, effect5, effect6 FROM RenderComponent WHERE id = " << std::to_string(entry) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - if (result.eof()) - { - return; - } - - for (auto i = 0; i < 6; ++i) - { - if (result.fieldIsNull(i)) - { - continue; - } - - const auto id = result.getIntField(i); - - if (id <= 0) - { - continue; - } - - query.clear(); - - query << "SELECT effectType, effectName FROM BehaviorEffect WHERE effectID = " << std::to_string(id) << ";"; - - auto effectResult = CDClientDatabase::ExecuteQuery(query.str()); - - while (!effectResult.eof()) - { - const auto type = effectResult.fieldIsNull(0) ? "" : std::string(effectResult.getStringField(0)); - - const auto name = effectResult.fieldIsNull(1) ? "" : std::string(effectResult.getStringField(1)); - - auto* effect = new Effect(); - - effect->name = name; - effect->type = GeneralUtils::ASCIIToUTF16(type); - effect->scale = 1; - effect->effectID = id; - effect->secondary = LWOOBJID_EMPTY; - - m_Effects.push_back(effect); - - effectResult.nextRow(); + if (!result.eof()) { + auto animationGroupIDs = std::string(result.getStringField("animationGroupIDs", "")); + if (!animationGroupIDs.empty()) { + auto* animationsTable = CDClientManager::Instance().GetTable(); + auto groupIdsSplit = GeneralUtils::SplitString(animationGroupIDs, ','); + for (auto& groupId : groupIdsSplit) { + int32_t groupIdInt; + if (!GeneralUtils::TryParse(groupId, groupIdInt)) { + Game::logger->Log("RenderComponent", "bad animation group Id %s", groupId.c_str()); + continue; + } + m_animationGroupIds.push_back(groupIdInt); + animationsTable->CacheAnimationGroup(groupIdInt); + } } } - result.finalize(); - */ } RenderComponent::~RenderComponent() { @@ -224,3 +186,47 @@ void RenderComponent::StopEffect(const std::string& name, const bool killImmedia std::vector& RenderComponent::GetEffects() { return m_Effects; } + + +float RenderComponent::PlayAnimation(Entity* self, const std::u16string& animation, float priority, float scale) { + if (!self) return 0.0f; + return RenderComponent::PlayAnimation(self, GeneralUtils::UTF16ToWTF8(animation), priority, scale); +} + +float RenderComponent::PlayAnimation(Entity* self, const std::string& animation, float priority, float scale) { + if (!self) return 0.0f; + return RenderComponent::DoAnimation(self, animation, true, priority, scale); +} + +float RenderComponent::GetAnimationTime(Entity* self, const std::u16string& animation) { + if (!self) return 0.0f; + return RenderComponent::GetAnimationTime(self, GeneralUtils::UTF16ToWTF8(animation)); +} + +float RenderComponent::GetAnimationTime(Entity* self, const std::string& animation) { + if (!self) return 0.0f; + return RenderComponent::DoAnimation(self, animation, false); +} + + +float RenderComponent::DoAnimation(Entity* self, const std::string& animation, bool sendAnimation, float priority, float scale) { + if (!self) return 0.0f; + auto* renderComponent = self->GetComponent(); + if (!renderComponent) return 0.0f; + + Game::logger->Log("RenderComponent", "looking up animation %s playing anim %i priority %f scale %f", animation.c_str(), sendAnimation, priority, scale); + auto* animationsTable = CDClientManager::Instance().GetTable(); + for (auto& groupId : renderComponent->m_animationGroupIds) { + Game::logger->Log("RenderComponent", "checking id %i with previous being %s", groupId, renderComponent->GetLastAnimationName().c_str()); + auto animationGroup = animationsTable->GetAnimation(animation, renderComponent->GetLastAnimationName(), groupId); + if (animationGroup.FoundData()) { + auto data = animationGroup.Data(); + Game::logger->Log("RenderComponent", "animation %s priority %f length %f", data.animation_name.c_str(), data.priority, data.animation_length); + if (sendAnimation) GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(animation), priority, scale); + renderComponent->SetLastAnimationName(data.animation_name); + return data.animation_length; + } + } + Game::logger->Log("RenderComponent", "unable to find animation %s for lot %i", animation.c_str(), self->GetLOT()); + return 0.0f; +} diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index de8b2907..ef916396 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -58,7 +58,7 @@ class RenderComponent : public Component { public: static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER; - RenderComponent(Entity* entity); + RenderComponent(Entity* entity, int32_t componentId = -1); ~RenderComponent() override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); @@ -104,6 +104,16 @@ public: */ std::vector& GetEffects(); + static float DoAnimation(Entity* self, const std::string& animation, bool sendAnimation, float priority = 0.0f, float scale = 1.0f); + + static float PlayAnimation(Entity* self, const std::u16string& animation, float priority = 0.0f, float scale = 1.0f); + static float PlayAnimation(Entity* self, const std::string& animation, float priority = 0.0f, float scale = 1.0f); + static float GetAnimationTime(Entity* self, const std::string& animation); + static float GetAnimationTime(Entity* self, const std::u16string& animation); + + const std::string& GetLastAnimationName() const { return m_LastAnimationName; }; + void SetLastAnimationName(const std::string& name) { m_LastAnimationName = name; }; + private: /** @@ -111,6 +121,11 @@ private: */ std::vector m_Effects; + std::vector m_animationGroupIds; + + // The last animationName that was played + std::string m_LastAnimationName; + /** * Cache of queries that look for the length of each effect, indexed by effect ID */ diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index bafa1faa..d6700ab2 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -26,13 +26,13 @@ #include "CDActivityRewardsTable.h" #include "CDActivitiesTable.h" -ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { +ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID): Component(parent) { m_ActivityID = activityID; CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); - std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); + auto activityResult = activitiesTable->GetActivity(m_ActivityID); - for (CDActivities activity : activities) { - m_ActivityInfo = activity; + if (activityResult.FoundData()) { + m_ActivityInfo = activityResult.Data(); const auto mapID = m_ActivityInfo.instanceMapID; @@ -57,6 +57,7 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit if (destroyableComponent) { // check for LMIs and set the loot LMIs + Game::logger->Log("ScriptedActivityComponent", "i am %i with lmi %i", m_Parent->GetLOT(), destroyableComponent->GetLootMatrixID()); CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable(); std::vector activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) {return (entry.LootMatrixIndex == destroyableComponent->GetLootMatrixID()); }); @@ -64,13 +65,13 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit if (activityRewards.size() > 0) { startingLMI = activityRewards[0].LootMatrixIndex; + Game::logger->Log("ScriptedActivityComponent", "index 0 is %i %i", activityRewards[0].LootMatrixIndex, activityRewards[0].objectTemplate); } if (startingLMI > 0) { - // now time for bodge :) - std::vector objectTemplateActivities = activityRewardsTable->Query([=](CDActivityRewards entry) {return (activityRewards[0].objectTemplate == entry.objectTemplate); }); for (const auto& item : objectTemplateActivities) { + Game::logger->Log("ScriptedActivityComponent", "%i added loot matrix with rating %i index %i objectTemplate %i", m_Parent->GetLOT(), item.activityRating, item.LootMatrixIndex, item.objectTemplate); if (item.activityRating > 0 && item.activityRating < 5) { m_ActivityLootMatrices.insert({ item.activityRating, item.LootMatrixIndex }); } @@ -99,21 +100,22 @@ void ScriptedActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool void ScriptedActivityComponent::ReloadConfig() { CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); - std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); - for (auto activity : activities) { - auto mapID = m_ActivityInfo.instanceMapID; + auto activityResult = activitiesTable->GetActivity(m_ActivityID); + if (activityResult.FoundData()) { + auto data = activityResult.Data(); + auto mapID = data.instanceMapID; if ((mapID == 1203 || mapID == 1261 || mapID == 1303 || mapID == 1403) && Game::config->GetValue("solo_racing") == "1") { m_ActivityInfo.minTeamSize = 1; m_ActivityInfo.minTeams = 1; } else { - m_ActivityInfo.minTeamSize = activity.minTeamSize; - m_ActivityInfo.minTeams = activity.minTeams; + m_ActivityInfo.minTeamSize = data.minTeamSize; + m_ActivityInfo.minTeams = data.minTeams; } } } void ScriptedActivityComponent::HandleMessageBoxResponse(Entity* player, const std::string& id) { - if (m_ActivityInfo.ActivityID == 103) { + if (m_ActivityID == 103) { return; } @@ -125,7 +127,7 @@ void ScriptedActivityComponent::HandleMessageBoxResponse(Entity* player, const s } void ScriptedActivityComponent::PlayerJoin(Entity* player) { - if (m_ActivityInfo.ActivityID == 103 || PlayerIsInQueue(player) || !IsValidActivity(player)) { + if (m_ActivityID == 103 || PlayerIsInQueue(player) || !IsValidActivity(player)) { return; } @@ -390,7 +392,7 @@ void ScriptedActivityComponent::PlayerReady(Entity* player, bool bReady) { } ActivityInstance* ScriptedActivityComponent::NewInstance() { - auto* instance = new ActivityInstance(m_Parent, m_ActivityInfo); + auto* instance = new ActivityInstance(m_Parent, this, m_ActivityInfo); m_Instances.push_back(instance); return instance; } @@ -557,12 +559,12 @@ void ActivityInstance::StartZone() { void ActivityInstance::RewardParticipant(Entity* participant) { auto* missionComponent = participant->GetComponent(); if (missionComponent) { - missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityInfo.ActivityID); + missionComponent->Progress(eMissionTaskType::ACTIVITY, m_OwningComponent->GetActivityID()); } // First, get the activity data auto* activityRewardsTable = CDClientManager::Instance().GetTable(); - std::vector activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) { return (entry.objectTemplate == m_ActivityInfo.ActivityID); }); + std::vector activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) { return (entry.objectTemplate == m_OwningComponent->GetActivityID()); }); if (!activityRewards.empty()) { uint32_t minCoins = 0; diff --git a/dGame/dComponents/ScriptedActivityComponent.h b/dGame/dComponents/ScriptedActivityComponent.h index 1d49a62d..84ac0bc2 100644 --- a/dGame/dComponents/ScriptedActivityComponent.h +++ b/dGame/dComponents/ScriptedActivityComponent.h @@ -15,13 +15,18 @@ #include "CDActivitiesTable.h" +class ScriptedActivityComponent; + /** * Represents an instance of an activity, having participants and score */ class ActivityInstance { public: - ActivityInstance(Entity* parent, CDActivities activityInfo) { m_Parent = parent; m_ActivityInfo = activityInfo; }; - //~ActivityInstance(); + ActivityInstance(Entity* parent, ScriptedActivityComponent* parentComponent, CDActivities activityInfo) { + m_Parent = parent; + m_OwningComponent = parentComponent; + m_ActivityInfo = activityInfo; + }; /** * Adds an entity to this activity @@ -88,6 +93,11 @@ private: */ Entity* m_Parent; + /** + * The component that owns this activity (the ScriptedActivityComponent) + */ + ScriptedActivityComponent* m_OwningComponent; + /** * All the participants of this activity */ @@ -212,7 +222,7 @@ public: * Returns the ID of this activity * @return the ID of this activity */ - int GetActivityID() { return m_ActivityInfo.ActivityID; } + int GetActivityID() { return m_ActivityID; } /** * Returns if this activity has a lobby, e.g. if it needs to instance players to some other map diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index dbdf37a9..d2c1dd50 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -1,6 +1,7 @@ #include "SwitchComponent.h" #include "EntityManager.h" #include "eTriggerEventType.h" +#include "RenderComponent.h" std::vector SwitchComponent::petSwitches; @@ -59,7 +60,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { if (m_PetBouncer != nullptr) { GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 2602, u"pettriggeractive", "BounceEffect", LWOOBJID_EMPTY, 1, 1, true); - GameMessages::SendPlayAnimation(m_Parent, u"engaged", 0, 1); + RenderComponent::PlayAnimation(m_Parent, u"engaged"); m_PetBouncer->SetPetBouncerEnabled(true); } else { EntityManager::Instance()->SerializeEntity(m_Parent); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 33a7f104..062fece7 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -34,6 +34,7 @@ #include "eRacingTaskParam.h" #include "eMissionTaskType.h" #include "eMissionState.h" +#include "RenderComponent.h" #include #include @@ -5110,7 +5111,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (emote) sAnimationName = emote->animationName; } - GameMessages::SendPlayAnimation(entity, GeneralUtils::ASCIIToUTF16(sAnimationName)); + RenderComponent::PlayAnimation(entity, sAnimationName); } void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { diff --git a/dGame/dUtilities/Loot.cpp b/dGame/dUtilities/Loot.cpp index da0f2487..d1f30e41 100644 --- a/dGame/dUtilities/Loot.cpp +++ b/dGame/dUtilities/Loot.cpp @@ -17,6 +17,7 @@ #include "MissionComponent.h" #include "eMissionState.h" #include "eReplicaComponentType.h" +#include "Metrics.hpp" LootGenerator::LootGenerator() { CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable(); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 0278136b..d426ac12 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -76,6 +76,7 @@ #include "TriggerComponent.h" #include "eServerDisconnectIdentifiers.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" #include "CDObjectsTable.h" #include "CDZoneTableTable.h" @@ -418,11 +419,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { std::u16string anim = GeneralUtils::ASCIIToUTF16(args[0], args[0].size()); - GameMessages::SendPlayAnimation(entity, anim); + RenderComponent::PlayAnimation(entity, anim); auto* possessorComponent = entity->GetComponent(); if (possessorComponent) { auto* possessedComponent = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); - if (possessedComponent) GameMessages::SendPlayAnimation(possessedComponent, anim); + if (possessedComponent) RenderComponent::PlayAnimation(possessedComponent, anim); } } @@ -1955,7 +1956,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(closest); } else if (args[1] == "-a" && args.size() >= 3) { - GameMessages::SendPlayAnimation(closest, GeneralUtils::UTF8ToUTF16(args[2])); + RenderComponent::PlayAnimation(closest, args.at(2)); } else if (args[1] == "-s") { for (auto* entry : closest->GetSettings()) { ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::UTF8ToUTF16(entry->GetString())); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index cc2bdd90..7bb70391 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -49,6 +49,7 @@ namespace Game { dConfig* config = nullptr; AssetManager* assetManager = nullptr; bool shouldShutdown = false; + std::mt19937 randomEngine; } //namespace Game bool shutdownSequenceStarted = false; @@ -290,6 +291,7 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } + Game::randomEngine = std::mt19937(time(0)); uint32_t maxClients = 999; uint32_t ourPort = 1000; if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); @@ -332,8 +334,7 @@ int main(int argc, char** argv) { if (Game::config->GetValue("prestart_servers") != "" && Game::config->GetValue("prestart_servers") == "1") { StartChatServer(); - Game::im->GetInstance(0, false, 0); - Game::im->GetInstance(1000, false, 0); + Game::im->GetInstance(1800, false, 0); StartAuthServer(); } diff --git a/dScripts/02_server/DLU/DLUVanityNPC.cpp b/dScripts/02_server/DLU/DLUVanityNPC.cpp index e3db2353..ba2c6604 100644 --- a/dScripts/02_server/DLU/DLUVanityNPC.cpp +++ b/dScripts/02_server/DLU/DLUVanityNPC.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "dServer.h" #include "VanityUtilities.h" +#include "RenderComponent.h" void DLUVanityNPC::OnStartup(Entity* self) { m_NPC = VanityUtilities::GetNPC("averysumner - Destroyer of Worlds"); @@ -17,7 +18,7 @@ void DLUVanityNPC::OnStartup(Entity* self) { void DLUVanityNPC::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "setupTeleport") { - GameMessages::SendPlayAnimation(self, u"interact"); + RenderComponent::PlayAnimation(self, u"interact"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportRings", "teleportRings"); diff --git a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp index c584f05b..aa04f571 100644 --- a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp @@ -14,6 +14,7 @@ #include "GameMessages.h" #include "SkillComponent.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" #include @@ -695,11 +696,11 @@ float BossSpiderQueenEnemyServer::PlayAnimAndReturnTime(Entity* self, const std: //TODO: Get the actual animation time // Get the anim time - float animTimer = defaultAnimPause; //self:GetAnimationTime{animationID = animID}.time + float animTimer = RenderComponent::GetAnimationTime(self, animID); // If we have an animation play it if (animTimer > 0) { - GameMessages::SendPlayAnimation(self, animID); + animTimer = RenderComponent::PlayAnimation(self, animID); } // If the anim time is less than the the default time use default diff --git a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp index 28ba0044..0ee5431b 100644 --- a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp +++ b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp @@ -7,6 +7,7 @@ #include "BaseCombatAIComponent.h" #include "EntityInfo.h" #include "eAninmationFlags.h" +#include "RenderComponent.h" void AmDarklingDragon::OnStartup(Entity* self) { self->SetVar(u"weakspot", 0); @@ -70,9 +71,9 @@ void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t self->SetVar(u"weakpoint", 2); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendPlayAnimation(self, u"stunstart", 1.7f); + float animationTime = RenderComponent::PlayAnimation(self, u"stunstart", 1.7f); - self->AddTimer("timeToStunLoop", 1); + self->AddTimer("timeToStunLoop", animationTime); auto position = self->GetPosition(); auto forward = self->GetRotation().GetForwardVector(); @@ -121,9 +122,9 @@ void AmDarklingDragon::OnTimerDone(Entity* self, std::string timerName) { } else if (timerName == "ExposeWeakSpotTimer") { self->SetVar(u"weakspot", 1); } else if (timerName == "timeToStunLoop") { - GameMessages::SendPlayAnimation(self, u"stunloop", 1.8f); + RenderComponent::PlayAnimation(self, u"stunloop", 1.8f); } else if (timerName == "ReviveTimer") { - GameMessages::SendPlayAnimation(self, u"stunend", 2.0f); + RenderComponent::PlayAnimation(self, u"stunend", 2.0f); self->AddTimer("backToAttack", 1); } else if (timerName == "backToAttack") { auto* baseCombatAIComponent = self->GetComponent(); @@ -153,5 +154,5 @@ void AmDarklingDragon::OnFireEventServerSide(Entity* self, Entity* sender, std:: self->SetVar(u"Golem", sender->GetObjectID()); - GameMessages::SendPlayAnimation(self, u"quickbuildhold", 1.9f); + RenderComponent::PlayAnimation(self, u"quickbuildhold", 1.9f); } diff --git a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp index e78f537f..664d8b67 100644 --- a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp +++ b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp @@ -5,6 +5,7 @@ #include "DestroyableComponent.h" #include "eAninmationFlags.h" #include "EntityInfo.h" +#include "RenderComponent.h" void FvMaelstromDragon::OnStartup(Entity* self) { self->SetVar(u"weakspot", 0); @@ -86,9 +87,9 @@ void FvMaelstromDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_ self->SetVar(u"weakpoint", 2); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendPlayAnimation(self, u"stunstart", 1.7f); + RenderComponent::PlayAnimation(self, u"stunstart", 1.7f); - self->AddTimer("timeToStunLoop", 1); + self->AddTimer("timeToStunLoop", 1.0f); auto position = self->GetPosition(); auto forward = self->GetRotation().GetForwardVector(); @@ -137,10 +138,10 @@ void FvMaelstromDragon::OnTimerDone(Entity* self, std::string timerName) { } else if (timerName == "ExposeWeakSpotTimer") { self->SetVar(u"weakspot", 1); } else if (timerName == "timeToStunLoop") { - GameMessages::SendPlayAnimation(self, u"stunloop", 1.8f); + RenderComponent::PlayAnimation(self, u"stunloop", 1.8f); } else if (timerName == "ReviveTimer") { - GameMessages::SendPlayAnimation(self, u"stunend", 2.0f); - self->AddTimer("backToAttack", 1); + RenderComponent::PlayAnimation(self, u"stunend", 2.0f); + self->AddTimer("backToAttack", 1.0f); } else if (timerName == "backToAttack") { auto* baseCombatAIComponent = self->GetComponent(); auto* skillComponent = self->GetComponent(); @@ -174,5 +175,5 @@ FvMaelstromDragon::OnFireEventServerSide(Entity* self, Entity* sender, std::stri self->SetVar(u"Golem", sender->GetObjectID()); - GameMessages::SendPlayAnimation(self, u"quickbuildhold", 1.9f); + RenderComponent::PlayAnimation(self, u"quickbuildhold", 1.9f); } diff --git a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp index ea3ce9b8..50108ffb 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp @@ -6,6 +6,7 @@ #include "EntityInfo.h" #include "SkillComponent.h" #include "eAninmationFlags.h" +#include "RenderComponent.h" void BaseEnemyApe::OnStartup(Entity* self) { self->SetVar(u"timesStunned", 2); @@ -37,7 +38,7 @@ void BaseEnemyApe::OnHit(Entity* self, Entity* attacker) { if (skillComponent) { skillComponent->Reset(); } - GameMessages::SendPlayAnimation(self, u"disable", 1.7f); + RenderComponent::PlayAnimation(self, u"disable", 1.7f); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); const auto reviveTime = self->GetVar(u"reviveTime") != 0.0f ? self->GetVar(u"reviveTime") : 12.0f; diff --git a/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp b/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp index 5bba6450..40cc88f4 100644 --- a/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp +++ b/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp @@ -1,6 +1,8 @@ #include "GfApeSmashingQB.h" #include "EntityManager.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" void GfApeSmashingQB::OnStartup(Entity* self) { self->SetNetworkVar(u"lootTagOwner", self->GetVar(u"lootTagOwner")); @@ -16,7 +18,7 @@ void GfApeSmashingQB::OnRebuildComplete(Entity* self, Entity* target) { auto* ape = EntityManager::Instance()->GetEntity(self->GetVar(u"ape")); if (ape != nullptr) { ape->OnFireEventServerSide(target, "rebuildDone"); - GameMessages::SendPlayAnimation(self, u"smash", 1.7f); + RenderComponent::PlayAnimation(self, u"smash", 1.7f); self->AddTimer("anchorBreakTime", 1.0f); } } diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp index c01d2362..f02c0568 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp @@ -4,19 +4,15 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" void MaestromExtracticatorServer::OnStartup(Entity* self) { - //self:SetNetworkVar("current_anim", failAnim) - GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(failAnim)); - - self->AddTimer("PlayFail", defaultTime); + self->AddTimer("PlayFail", RenderComponent::PlayAnimation(self, failAnim)); self->AddTimer("RemoveSample", destroyAfterNoSampleTime); } -void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, - int32_t param2, int32_t param3) { - if (sender == nullptr) - return; +void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { + if (sender == nullptr) return; if (args == "attemptCollection") { Entity* player = EntityManager::Instance()->GetEntity(self->GetSpawnerID()); @@ -32,20 +28,17 @@ void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* se } void MaestromExtracticatorServer::CollectSample(Entity* self, LWOOBJID sampleObj) { - PlayAnimAndReturnTime(self, collectAnim); - self->AddTimer("RemoveSample", defaultTime); + self->AddTimer("RemoveSample", PlayAnimAndReturnTime(self, collectAnim)); } -void MaestromExtracticatorServer::PlayAnimAndReturnTime(Entity* self, std::string animID) { - GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(animID)); +float MaestromExtracticatorServer::PlayAnimAndReturnTime(Entity* self, std::string animID) { + return RenderComponent::PlayAnimation(self, animID); } void MaestromExtracticatorServer::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "RemoveSample") { self->ScheduleKillAfterUpdate(); - } - - if (timerName == "PlayFail") { - GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(failAnim)); + } else if (timerName == "PlayFail") { + RenderComponent::PlayAnimation(self, failAnim); } } diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.h b/dScripts/02_server/Equipment/MaestromExtracticatorServer.h index c4adb51e..c93a1cde 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.h +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.h @@ -7,12 +7,11 @@ public: void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3); void CollectSample(Entity* self, LWOOBJID sampleObj); - void PlayAnimAndReturnTime(Entity* self, std::string animID); + float PlayAnimAndReturnTime(Entity* self, std::string animID); void OnTimerDone(Entity* self, std::string timerName); private: const std::string failAnim = "idle_maelstrom"; const std::string collectAnim = "collect_maelstrom"; - const float defaultTime = 4.0f; const float destroyAfterNoSampleTime = 8.0f; }; diff --git a/dScripts/02_server/Map/AG/AgMonumentBirds.cpp b/dScripts/02_server/Map/AG/AgMonumentBirds.cpp index ad3417a4..9d4a3349 100644 --- a/dScripts/02_server/Map/AG/AgMonumentBirds.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentBirds.cpp @@ -1,5 +1,8 @@ #include "AgMonumentBirds.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" +#include "EntityManager.h" //-------------------------------------------------------------- //Makes the ag birds fly away when you get close and smashes them. @@ -16,7 +19,7 @@ void AgMonumentBirds::OnProximityUpdate(Entity* self, Entity* entering, std::str if (name == "MonumentBirds" && status == "ENTER") { self->AddTimer("killBird", 1.0f); - GameMessages::SendPlayAnimation(self, sOnProximityAnim); + RenderComponent::PlayAnimation(self, sOnProximityAnim); self->SetVar(u"IsFlying", true); self->SetVar(u"PlayerID", entering->GetObjectID()); } diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp index da1954d6..4bdf6492 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp @@ -5,6 +5,7 @@ #include "ProximityMonitorComponent.h" #include "MissionComponent.h" #include "EntityInfo.h" +#include "RenderComponent.h" void AmSkullkinDrill::OnStartup(Entity* self) { self->SetNetworkVar(u"bIsInUse", false); @@ -70,7 +71,7 @@ void AmSkullkinDrill::OnSkillEventFired(Entity* self, Entity* caster, const std: } void AmSkullkinDrill::TriggerDrill(Entity* self) { - GameMessages::SendPlayAnimation(self, u"slowdown"); + RenderComponent::PlayAnimation(self, u"slowdown"); self->AddTimer("killDrill", 10.0f); @@ -170,7 +171,7 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) { auto* standObj = GetStandObj(self); if (waypointIndex == 1) { - GameMessages::SendPlayAnimation(self, u"no-spin"); + RenderComponent::PlayAnimation(self, u"no-spin"); GameMessages::SendStopFXEffect(self, true, "active"); GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"indicator", "indicator"); @@ -190,7 +191,7 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) { return; } else { - GameMessages::SendPlayAnimation(self, u"idle"); + RenderComponent::PlayAnimation(self, u"idle"); GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"spin", "active"); GameMessages::SendStopFXEffect(self, true, "indicator"); } @@ -215,7 +216,7 @@ void AmSkullkinDrill::PlayCinematic(Entity* self) { void AmSkullkinDrill::PlayAnim(Entity* self, Entity* player, const std::string& animName) { const auto animTime = animName == "spinjitzu-staff-end" ? 0.5f : 1.0f; - GameMessages::SendPlayAnimation(player, GeneralUtils::ASCIIToUTF16(animName)); + RenderComponent::PlayAnimation(player, animName); self->AddTimer("AnimDone_" + animName, animTime); } @@ -308,7 +309,7 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { if (animName == "spinjitzu-staff-windup") { TriggerDrill(self); - GameMessages::SendPlayAnimation(player, u"spinjitzu-staff-loop"); + RenderComponent::PlayAnimation(player, u"spinjitzu-staff-loop"); } else if (animName == "spinjitzu-staff-end") { FreezePlayer(self, player, false); diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp index 628d616a..5493dc24 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp @@ -1,6 +1,8 @@ #include "AmSkullkinDrillStand.h" #include "GameMessages.h" #include "dpEntity.h" +#include "Entity.h" +#include "RenderComponent.h" void AmSkullkinDrillStand::OnStartup(Entity* self) { self->SetVar(u"bActive", true); @@ -31,5 +33,5 @@ void AmSkullkinDrillStand::OnProximityUpdate(Entity* self, Entity* entering, std GameMessages::SendPlayFXEffect(entering->GetObjectID(), 1378, u"create", "pushBack"); - GameMessages::SendPlayAnimation(entering, u"knockback-recovery"); + RenderComponent::PlayAnimation(entering, u"knockback-recovery"); } diff --git a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp index 01acdeaf..f7825f8f 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp @@ -5,6 +5,7 @@ #include "EntityInfo.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" void AmSkullkinTower::OnStartup(Entity* self) { self->SetProximityRadius(20, "Tower"); @@ -117,13 +118,13 @@ void AmSkullkinTower::OnChildRemoved(Entity* self, Entity* child) { self->SetVar(u"legTable", legTable); if (legTable.size() == 2) { - GameMessages::SendPlayAnimation(self, u"wobble-1"); + RenderComponent::PlayAnimation(self, u"wobble-1"); } else if (legTable.size() == 1) { - GameMessages::SendPlayAnimation(self, u"wobble-2"); + RenderComponent::PlayAnimation(self, u"wobble-2"); } else if (legTable.empty()) { const auto animTime = 2.5f; - GameMessages::SendPlayAnimation(self, u"fall"); + RenderComponent::PlayAnimation(self, u"fall"); self->AddTimer("spawnGuys", animTime - 0.2f); diff --git a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp index eeabeef6..2b40db3c 100644 --- a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp +++ b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "EntityManager.h" #include "MissionComponent.h" +#include "RenderComponent.h" void GfCaptainsCannon::OnUse(Entity* self, Entity* user) { if (self->GetVar(u"bIsInUse")) { @@ -27,7 +28,7 @@ void GfCaptainsCannon::OnUse(Entity* self, Entity* user) { GameMessages::SendTeleport(user->GetObjectID(), position, rotation, user->GetSystemAddress()); - GameMessages::SendPlayAnimation(user, u"cannon-strike-no-equip"); + RenderComponent::PlayAnimation(user, u"cannon-strike-no-equip"); GameMessages::SendPlayFXEffect(user->GetObjectID(), 6039, u"hook", "hook", LWOOBJID_EMPTY, 1, 1, true); @@ -58,7 +59,7 @@ void GfCaptainsCannon::OnTimerDone(Entity* self, std::string timerName) { for (auto* shark : sharkObjects) { if (shark->GetLOT() != m_SharkItemID) continue; - GameMessages::SendPlayAnimation(shark, u"cannon"); + RenderComponent::PlayAnimation(shark, u"cannon"); } GameMessages::SendPlay2DAmbientSound(player, "{7457d85c-4537-4317-ac9d-2f549219ea87}"); diff --git a/dScripts/02_server/Map/GF/GfTikiTorch.cpp b/dScripts/02_server/Map/GF/GfTikiTorch.cpp index 22420679..a4f36da2 100644 --- a/dScripts/02_server/Map/GF/GfTikiTorch.cpp +++ b/dScripts/02_server/Map/GF/GfTikiTorch.cpp @@ -5,6 +5,7 @@ #include "RenderComponent.h" #include "eMissionTaskType.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" void GfTikiTorch::OnStartup(Entity* self) { LightTorch(self); @@ -16,7 +17,7 @@ void GfTikiTorch::OnUse(Entity* self, Entity* killer) { return; } - GameMessages::SendPlayAnimation(self, u"interact"); + RenderComponent::PlayAnimation(self, u"interact"); self->SetI64(u"userID", killer->GetObjectID()); for (int i = 0; i < m_numspawn; i++) { @@ -55,7 +56,7 @@ void GfTikiTorch::LightTorch(Entity* self) { void GfTikiTorch::OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) { if (self->GetBoolean(u"isBurning") && message == "waterspray") { - GameMessages::SendPlayAnimation(self, u"water"); + RenderComponent::PlayAnimation(self, u"water"); auto* renderComponent = self->GetComponent(); if (renderComponent != nullptr) { diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index 6e50c6ec..fd2fe96d 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -8,6 +8,7 @@ #define _USE_MATH_DEFINES #include #endif +#include "RenderComponent.h" void MastTeleport::OnStartup(Entity* self) { self->SetNetworkVar(u"hookPreconditions", "154;44", UNASSIGNED_SYSTEM_ADDRESS); @@ -58,11 +59,12 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendPlayFXEffect(playerId, 6039, u"hook", "hook", LWOOBJID_EMPTY, 1, 1, true); - GameMessages::SendPlayAnimation(player, u"crow-swing-no-equip", 4.0f); + float animationTime = 6.25f; + animationTime = RenderComponent::PlayAnimation(player, "crow-swing-no-equip", 4.0f); - GameMessages::SendPlayAnimation(self, u"swing"); + RenderComponent::PlayAnimation(self, u"swing"); - self->AddTimer("PlayerAnimDone", 6.25f); + self->AddTimer("PlayerAnimDone", animationTime); } else if (timerName == "PlayerAnimDone") { GameMessages::SendStopFXEffect(player, true, "hook"); diff --git a/dScripts/02_server/Map/General/ExplodingAsset.cpp b/dScripts/02_server/Map/General/ExplodingAsset.cpp index 16340ee6..ee8f8e68 100644 --- a/dScripts/02_server/Map/General/ExplodingAsset.cpp +++ b/dScripts/02_server/Map/General/ExplodingAsset.cpp @@ -4,6 +4,7 @@ #include "MissionComponent.h" #include "SkillComponent.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" //TODO: this has to be updated so that you only get killed if you're in a certain radius. //And so that all entities in a certain radius are killed, not just the attacker. @@ -69,23 +70,6 @@ void ExplodingAsset::OnHit(Entity* self, Entity* attacker) { } void ExplodingAsset::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - /* - if msg.objId:BelongsToFaction{factionID = 1}.bIsInFaction then - if (msg.status == "ENTER") then - self:PlayAnimation{ animationID = "bounce" } - self:PlayFXEffect{ name = "bouncin", effectType = "anim" } - self:SetVar("playersNearChest", (self:GetVar("playersNearChest") + 1 )) - elseif (msg.status == "LEAVE") then - self:SetVar("playersNearChest", (self:GetVar("playersNearChest") - 1 )) - if self:GetVar("playersNearChest") < 1 then - self:PlayAnimation{ animationID = "idle" } - self:StopFXEffect{ name = "bouncin" } - self:SetVar("playersNearChest", 0) - end - end - end - */ - auto* destuctableComponent = entering->GetComponent(); if (destuctableComponent == nullptr) return; @@ -95,14 +79,14 @@ void ExplodingAsset::OnProximityUpdate(Entity* self, Entity* entering, std::stri if (!std::count(factions.begin(), factions.end(), 1)) return; if (status == "ENTER") { - GameMessages::SendPlayAnimation(self, u"bounce"); + RenderComponent::PlayAnimation(self, u"bounce"); GameMessages::SendPlayFXEffect(self, -1, u"anim", "bouncin", LWOOBJID_EMPTY, 1, 1, true); self->SetVar(u"playersNearChest", self->GetVar(u"playersNearChest") + 1); } else if (status == "LEAVE") { self->SetVar(u"playersNearChest", self->GetVar(u"playersNearChest") - 1); if (self->GetVar(u"playersNearChest") < 1) { - GameMessages::SendPlayAnimation(self, u"idle"); + RenderComponent::PlayAnimation(self, u"idle"); GameMessages::SendStopFXEffect(self, true, "bouncin"); self->SetVar(u"playersNearChest", 0); } diff --git a/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp b/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp index 2549cd0f..8a9230d9 100644 --- a/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp +++ b/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp @@ -1,6 +1,8 @@ #include "NjIceRailActivator.h" #include "EntityManager.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" void NjIceRailActivator::OnPlayerRailArrived(Entity* self, Entity* sender, const std::u16string& pathName, int32_t waypoint) { @@ -9,7 +11,7 @@ void NjIceRailActivator::OnPlayerRailArrived(Entity* self, Entity* sender, const const auto& blockGroup = self->GetVar(BlockGroupVariable); for (auto* block : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(blockGroup))) { - GameMessages::SendPlayAnimation(block, u"explode"); + RenderComponent::PlayAnimation(block, u"explode"); const auto blockID = block->GetObjectID(); diff --git a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp index b4d75296..26da3aca 100644 --- a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp +++ b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp @@ -4,6 +4,7 @@ #include "MissionComponent.h" #include "eMissionTaskType.h" #include "eMissionState.h" +#include "RenderComponent.h" void NtAssemblyTubeServer::OnStartup(Entity* self) { self->SetProximityRadius(5, "teleport"); @@ -49,7 +50,7 @@ void NtAssemblyTubeServer::RunAssemblyTube(Entity* self, Entity* player) { ); } - GameMessages::SendPlayAnimation(player, u"tube-sucker", 4.0f); + RenderComponent::PlayAnimation(player, u"tube-sucker", 4.0f); const auto animTime = 3; @@ -82,7 +83,7 @@ void NtAssemblyTubeServer::TeleportPlayer(Entity* self, Entity* player) { GameMessages::SendTeleport(player->GetObjectID(), destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"tube-resurrect", 4.0f); + RenderComponent::PlayAnimation(player, u"tube-resurrect", 4.0f); const auto animTime = 2; diff --git a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp index 0cb0bec4..f7e27711 100644 --- a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp @@ -4,6 +4,7 @@ #include "EntityManager.h" #include "Character.h" #include "eMissionState.h" +#include "RenderComponent.h" void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"bActive", 1, 0, user->GetObjectID(), "", user->GetSystemAddress()); @@ -32,18 +33,18 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { player->GetCharacter()->SetPlayerFlag(flag, true); - GameMessages::SendPlayAnimation(player, u"rebuild-celebrate"); + RenderComponent::PlayAnimation(player, u"rebuild-celebrate"); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SparkStop", 0, 0, player->GetObjectID(), "", player->GetSystemAddress()); GameMessages::SendSetStunned(player->GetObjectID(), eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); self->SetVar(u"bActive", false); }); - GameMessages::SendPlayAnimation(user, u"nexus-powerpanel", 6.0f); + RenderComponent::PlayAnimation(user, u"nexus-powerpanel", 6.0f); GameMessages::SendSetStunned(user->GetObjectID(), eStateChangeType::PUSH, user->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); return; } - GameMessages::SendPlayAnimation(user, shockAnim); + RenderComponent::PlayAnimation(user, shockAnim); const auto dir = self->GetRotation().GetRightVector(); diff --git a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp index 8b4f19fe..e3ec8d7d 100644 --- a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" void NtParadoxTeleServer::OnStartup(Entity* self) { self->SetProximityRadius(5, "teleport"); @@ -27,7 +28,7 @@ void NtParadoxTeleServer::OnProximityUpdate(Entity* self, Entity* entering, std: true, true, true, true, true, true, true ); - GameMessages::SendPlayAnimation(player, u"teledeath", 4.0f); + RenderComponent::PlayAnimation(player, u"teledeath", 4.0f); const auto animTime = 2; @@ -73,7 +74,7 @@ void NtParadoxTeleServer::TeleportPlayer(Entity* self, Entity* player) { GameMessages::SendTeleport(player->GetObjectID(), destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"paradox-teleport-in", 4.0f); + RenderComponent::PlayAnimation(player, u"paradox-teleport-in", 4.0f); const auto animTime = 2; diff --git a/dScripts/02_server/Map/NT/NtSleepingGuard.cpp b/dScripts/02_server/Map/NT/NtSleepingGuard.cpp index 145df6c8..92a80582 100644 --- a/dScripts/02_server/Map/NT/NtSleepingGuard.cpp +++ b/dScripts/02_server/Map/NT/NtSleepingGuard.cpp @@ -1,6 +1,7 @@ #include "NtSleepingGuard.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" void NtSleepingGuard::OnStartup(Entity* self) { self->SetNetworkVar(u"asleep", true); @@ -17,7 +18,7 @@ void NtSleepingGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* // Set asleep to false self->SetNetworkVar(u"asleep", false); - GameMessages::SendPlayAnimation(self, u"greet"); + RenderComponent::PlayAnimation(self, u"greet"); auto* missionComponent = target->GetComponent(); diff --git a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp index e6cd2df6..c1f07bbd 100644 --- a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp +++ b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp @@ -1,6 +1,9 @@ #include "NtVentureCannonServer.h" #include "GameMessages.h" #include "EntityManager.h" +#include "Entity.h" +#include "GeneralUtils.h" +#include "RenderComponent.h" void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { auto* player = user; @@ -26,7 +29,7 @@ void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { GameMessages::SendTeleport(playerID, destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"scale-down", 4.0f); + RenderComponent::PlayAnimation(player, u"scale-down", 4.0f); const auto enterCinematicUname = enterCinematic; GameMessages::SendPlayCinematic(player->GetObjectID(), enterCinematicUname, player->GetSystemAddress()); @@ -118,5 +121,5 @@ void NtVentureCannonServer::FirePlayer(Entity* self, Entity* player) { GameMessages::SendTeleport(player->GetObjectID(), destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"venture-cannon-out", 4.0f); + RenderComponent::PlayAnimation(player, u"venture-cannon-out", 4.0f); } diff --git a/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp b/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp index fda103b0..55935c62 100644 --- a/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp +++ b/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp @@ -1,6 +1,8 @@ #include "CatapultBaseServer.h" #include "GameMessages.h" #include "EntityManager.h" +#include "Entity.h" +#include "RenderComponent.h" void CatapultBaseServer::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) { if (name == "BouncerBuilt") { @@ -21,7 +23,7 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { // tell the arm to the play the platform animation, which is just the arm laying there but with bouncer for (auto* obj : arm) { - GameMessages::SendPlayAnimation(obj, u"idle-platform"); + RenderComponent::PlayAnimation(obj, u"idle-platform"); GameMessages::SendPlayNDAudioEmitter(obj, UNASSIGNED_SYSTEM_ADDRESS, "{8cccf912-69e3-4041-a20b-63e4afafc993}"); // set the art so we can use it again self->SetVar(u"Arm", obj->GetObjectID()); @@ -38,7 +40,7 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { // tell the arm to player the launcher animation auto animTime = 1; self->AddTimer("resetArm", animTime); - GameMessages::SendPlayAnimation(arm, u"launch"); + RenderComponent::PlayAnimation(arm, u"launch"); } else if (timerName == "bounce") { auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"Bouncer")); if (bouncer == nullptr) return; @@ -52,7 +54,7 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { if (arm == nullptr) return; // set the arm back to natural state - GameMessages::SendPlayAnimation(arm, u"idle"); + RenderComponent::PlayAnimation(arm, u"idle"); auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"Bouncer")); if (bouncer == nullptr) return; diff --git a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp index 0df91884..14cf6719 100644 --- a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp +++ b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp @@ -4,6 +4,7 @@ #include "GameMessages.h" #include "Character.h" #include "dZoneManager.h" +#include "RenderComponent.h" void CavePrisonCage::OnStartup(Entity* self) { const auto& myNum = self->GetVar(u"myNumber"); @@ -101,7 +102,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { } // Play the 'down' animation on the button - GameMessages::SendPlayAnimation(button, u"down"); + RenderComponent::PlayAnimation(button, u"down"); // Setup a timer named 'buttonGoingDown' to be triggered in 5 seconds self->AddTimer("buttonGoingDown", 5.0f); @@ -136,13 +137,13 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { // the anim of the button down is over if (timerName == "buttonGoingDown") { // Play the 'up' animation - GameMessages::SendPlayAnimation(self, u"up"); + RenderComponent::PlayAnimation(self, u"up"); // Setup a timer named 'CageOpen' to be triggered in 1 second self->AddTimer("CageOpen", 1.0f); } else if (timerName == "CageOpen") { // play the idle open anim - GameMessages::SendPlayAnimation(self, u"idle-up"); + RenderComponent::PlayAnimation(self, u"idle-up"); // Get the villeger auto* villager = EntityManager::Instance()->GetEntity(self->GetVar(u"villager")); @@ -199,13 +200,13 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { } // Play the 'up' animation on the button - GameMessages::SendPlayAnimation(button, u"up"); + RenderComponent::PlayAnimation(button, u"up"); // Setup a timer named 'CageClosed' to be triggered in 1 second self->AddTimer("CageClosed", 1.0f); } else if (timerName == "CageClosed") { // play the idle closed anim - GameMessages::SendPlayAnimation(self, u"idle"); + RenderComponent::PlayAnimation(self, u"idle"); // Setup a timer named 'ResetPrison' to be triggered in 10 seconds self->AddTimer("ResetPrison", 10.0f); diff --git a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp index dbab7365..d5880029 100644 --- a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp +++ b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp @@ -9,6 +9,7 @@ #include "SkillComponent.h" #include "TeamManager.h" #include +#include "RenderComponent.h" // // // // // // // // Event handling // @@ -261,7 +262,7 @@ void NjMonastryBossInstance::HandleCounterWeightSpawned(Entity* self, Entity* co skillComponent->CalculateBehavior(1635, 39097, frakjaw->GetObjectID(), true, false); } - GameMessages::SendPlayAnimation(frakjaw, StunnedAnimation); + RenderComponent::PlayAnimation(frakjaw, StunnedAnimation); GameMessages::SendPlayNDAudioEmitter(frakjaw, UNASSIGNED_SYSTEM_ADDRESS, CounterSmashAudio); // Before wave 4 we should lower frakjaw from the ledge @@ -281,7 +282,7 @@ void NjMonastryBossInstance::HandleCounterWeightSpawned(Entity* self, Entity* co } void NjMonastryBossInstance::HandleLowerFrakjawSpawned(Entity* self, Entity* lowerFrakjaw) { - GameMessages::SendPlayAnimation(lowerFrakjaw, TeleportInAnimation); + RenderComponent::PlayAnimation(lowerFrakjaw, TeleportInAnimation); self->SetVar(LowerFrakjawVariable, lowerFrakjaw->GetObjectID()); auto* combatAI = lowerFrakjaw->GetComponent(); @@ -401,7 +402,7 @@ void NjMonastryBossInstance::TeleportPlayer(Entity* player, uint32_t position) { void NjMonastryBossInstance::SummonWave(Entity* self, Entity* frakjaw) { GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, LedgeFrakSummon, UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendPlayAnimation(frakjaw, SummonAnimation); + RenderComponent::PlayAnimation(frakjaw, SummonAnimation); // Stop the music for the first, fourth and fifth wave const auto wave = self->GetVar(WaveNumberVariable); @@ -425,7 +426,7 @@ void NjMonastryBossInstance::LowerFrakjawSummon(Entity* self, Entity* frakjaw) { GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, BottomFrakSummon, UNASSIGNED_SYSTEM_ADDRESS); ActivityTimerStart(self, SpawnWaveTimer, 2.0f, 2.0f); - GameMessages::SendPlayAnimation(frakjaw, SummonAnimation); + RenderComponent::PlayAnimation(frakjaw, SummonAnimation); } void NjMonastryBossInstance::RemovePoison(Entity* self) { @@ -444,7 +445,7 @@ void NjMonastryBossInstance::RemovePoison(Entity* self) { } void NjMonastryBossInstance::LowerFrakjaw(Entity* self, Entity* frakjaw) { - GameMessages::SendPlayAnimation(frakjaw, TeleportOutAnimation); + RenderComponent::PlayAnimation(frakjaw, TeleportOutAnimation); ActivityTimerStart(self, LowerFrakjawCamTimer, 2.0f, 2.0f); GameMessages::SendNotifyClientObject(frakjaw->GetObjectID(), StopMusicNotification, 0, 0, diff --git a/dScripts/BaseConsoleTeleportServer.cpp b/dScripts/BaseConsoleTeleportServer.cpp index d0162e9c..073b7826 100644 --- a/dScripts/BaseConsoleTeleportServer.cpp +++ b/dScripts/BaseConsoleTeleportServer.cpp @@ -1,6 +1,8 @@ #include "BaseConsoleTeleportServer.h" #include "GameMessages.h" #include "Player.h" +#include "RenderComponent.h" +#include "EntityManager.h" void BaseConsoleTeleportServer::BaseOnUse(Entity* self, Entity* user) { auto* player = user; @@ -31,13 +33,12 @@ void BaseConsoleTeleportServer::BaseOnMessageBoxResponse(Entity* self, Entity* s } const auto& teleIntroAnim = self->GetVar(u"teleportAnim"); - + Game::logger->Log("BaseConsoleTeleportServer", "%s",GeneralUtils::UTF16ToWTF8(teleIntroAnim).c_str()); + auto animTime = 3.32999992370605f; if (!teleIntroAnim.empty()) { - GameMessages::SendPlayAnimation(player, teleIntroAnim); + animTime = RenderComponent::PlayAnimation(player, teleIntroAnim); } - const auto animTime = 3.32999992370605f; - UpdatePlayerTable(self, player, true); const auto playerID = player->GetObjectID(); diff --git a/dScripts/ai/AG/AgFans.cpp b/dScripts/ai/AG/AgFans.cpp index e05fe68d..aaff9c0d 100644 --- a/dScripts/ai/AG/AgFans.cpp +++ b/dScripts/ai/AG/AgFans.cpp @@ -5,6 +5,8 @@ #include "PhantomPhysicsComponent.h" #include "RenderComponent.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" +#include "Entity.h" void AgFans::OnStartup(Entity* self) { self->SetVar(u"alive", true); @@ -34,7 +36,7 @@ void AgFans::ToggleFX(Entity* self, bool hit) { if (fanVolumes.size() == 0 || !self->GetVar(u"alive")) return; if (self->GetVar(u"on")) { - GameMessages::SendPlayAnimation(self, u"fan-off"); + RenderComponent::PlayAnimation(self, u"fan-off"); renderComponent->StopEffect("fanOn"); self->SetVar(u"on", false); @@ -46,11 +48,11 @@ void AgFans::ToggleFX(Entity* self, bool hit) { EntityManager::Instance()->SerializeEntity(volume); if (!hit) { Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0]; - GameMessages::SendPlayAnimation(fxObj, u"trigger"); + RenderComponent::PlayAnimation(fxObj, u"trigger"); } } } else if (!self->GetVar(u"on") && self->GetVar(u"alive")) { - GameMessages::SendPlayAnimation(self, u"fan-on"); + RenderComponent::PlayAnimation(self, u"fan-on"); renderComponent->PlayEffect(495, u"fanOn", "fanOn"); self->SetVar(u"on", true); @@ -62,7 +64,7 @@ void AgFans::ToggleFX(Entity* self, bool hit) { EntityManager::Instance()->SerializeEntity(volume); if (!hit) { Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0]; - GameMessages::SendPlayAnimation(fxObj, u"idle"); + RenderComponent::PlayAnimation(fxObj, u"idle"); } } } diff --git a/dScripts/ai/AG/AgJetEffectServer.cpp b/dScripts/ai/AG/AgJetEffectServer.cpp index 9546bc4d..37e2e573 100644 --- a/dScripts/ai/AG/AgJetEffectServer.cpp +++ b/dScripts/ai/AG/AgJetEffectServer.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "SkillComponent.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" void AgJetEffectServer::OnUse(Entity* self, Entity* user) { if (inUse) { @@ -54,7 +55,7 @@ void AgJetEffectServer::OnRebuildComplete(Entity* self, Entity* target) { const auto group = groups[0]; - GameMessages::SendPlayAnimation(effect, u"jetFX"); + RenderComponent::PlayAnimation(effect, u"jetFX"); self->AddTimer("PlayEffect", 2.5f); diff --git a/dScripts/ai/AG/AgSalutingNpcs.cpp b/dScripts/ai/AG/AgSalutingNpcs.cpp index 4e4d8b2c..d3bbe9ab 100644 --- a/dScripts/ai/AG/AgSalutingNpcs.cpp +++ b/dScripts/ai/AG/AgSalutingNpcs.cpp @@ -1,11 +1,10 @@ #include "AgSalutingNpcs.h" -#include "GameMessages.h" - +#include "RenderComponent.h" void AgSalutingNpcs::OnEmoteReceived(Entity* self, const int32_t emote, Entity* target) { if (emote != 356) { return; } - GameMessages::SendPlayAnimation(self, u"salutePlayer"); + RenderComponent::PlayAnimation(self, u"salutePlayer"); } diff --git a/dScripts/ai/AG/AgShipPlayerShockServer.cpp b/dScripts/ai/AG/AgShipPlayerShockServer.cpp index 2bed8152..0eb1d9c8 100644 --- a/dScripts/ai/AG/AgShipPlayerShockServer.cpp +++ b/dScripts/ai/AG/AgShipPlayerShockServer.cpp @@ -1,5 +1,7 @@ #include "AgShipPlayerShockServer.h" #include "GameMessages.h" +#include "RenderComponent.h" +#include "Entity.h" void AgShipPlayerShockServer::OnUse(Entity* self, Entity* user) { GameMessages::SendTerminateInteraction(user->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID()); @@ -7,7 +9,7 @@ void AgShipPlayerShockServer::OnUse(Entity* self, Entity* user) { return; } active = true; - GameMessages::SendPlayAnimation(user, shockAnim); + RenderComponent::PlayAnimation(user, shockAnim); GameMessages::SendKnockback(user->GetObjectID(), self->GetObjectID(), self->GetObjectID(), 0, NiPoint3(-20, 10, -20)); GameMessages::SendPlayFXEffect(self, 1430, u"create", "console_sparks", LWOOBJID_EMPTY, 1.0, 1.0, true); diff --git a/dScripts/ai/AG/AgSpaceStuff.cpp b/dScripts/ai/AG/AgSpaceStuff.cpp index 30929ebf..0887608e 100644 --- a/dScripts/ai/AG/AgSpaceStuff.cpp +++ b/dScripts/ai/AG/AgSpaceStuff.cpp @@ -3,6 +3,8 @@ #include "GeneralUtils.h" #include "GameMessages.h" #include "EntityManager.h" +#include "RenderComponent.h" +#include "Entity.h" void AgSpaceStuff::OnStartup(Entity* self) { self->AddTimer("FloaterScale", 5.0f); @@ -27,13 +29,13 @@ void AgSpaceStuff::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "FloaterScale") { int scaleType = GeneralUtils::GenerateRandomNumber(1, 5); - GameMessages::SendPlayAnimation(self, u"scale_0" + GeneralUtils::to_u16string(scaleType)); + RenderComponent::PlayAnimation(self, u"scale_0" + GeneralUtils::to_u16string(scaleType)); self->AddTimer("FloaterPath", 0.4); } else if (timerName == "FloaterPath") { int pathType = GeneralUtils::GenerateRandomNumber(1, 4); int randTime = GeneralUtils::GenerateRandomNumber(20, 25); - GameMessages::SendPlayAnimation(self, u"path_0" + (GeneralUtils::to_u16string(pathType))); + RenderComponent::PlayAnimation(self, u"path_0" + (GeneralUtils::to_u16string(pathType))); self->AddTimer("FloaterScale", randTime); } else if (timerName == "ShipShakeExplode") { DoShake(self, true); @@ -76,16 +78,16 @@ void AgSpaceStuff::DoShake(Entity* self, bool explodeIdle) { auto* shipFxObject2 = GetEntityInGroup(ShipFX2); if (shipFxObject2) - GameMessages::SendPlayAnimation(shipFxObject2, u"explosion"); + RenderComponent::PlayAnimation(shipFxObject2, u"explosion"); } else { auto* shipFxObject = GetEntityInGroup(ShipFX); auto* shipFxObject2 = GetEntityInGroup(ShipFX2); if (shipFxObject) - GameMessages::SendPlayAnimation(shipFxObject, u"idle"); + RenderComponent::PlayAnimation(shipFxObject, u"idle"); if (shipFxObject2) - GameMessages::SendPlayAnimation(shipFxObject2, u"idle"); + RenderComponent::PlayAnimation(shipFxObject2, u"idle"); } } diff --git a/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp b/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp index a9d38aa5..d46173fd 100644 --- a/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp +++ b/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp @@ -1,6 +1,8 @@ #include "FvDragonSmashingGolemQb.h" #include "GameMessages.h" #include "EntityManager.h" +#include "RenderComponent.h" +#include "Entity.h" void FvDragonSmashingGolemQb::OnStartup(Entity* self) { self->AddTimer("GolemBreakTimer", 10.5f); @@ -14,7 +16,7 @@ void FvDragonSmashingGolemQb::OnTimerDone(Entity* self, std::string timerName) { void FvDragonSmashingGolemQb::OnRebuildNotifyState(Entity* self, eRebuildState state) { if (state == eRebuildState::REBUILD_COMPLETED) { - GameMessages::SendPlayAnimation(self, u"dragonsmash"); + RenderComponent::PlayAnimation(self, u"dragonsmash"); const auto dragonId = self->GetVar(u"Dragon"); diff --git a/dScripts/ai/FV/FvFlyingCreviceDragon.cpp b/dScripts/ai/FV/FvFlyingCreviceDragon.cpp index 16eda512..cb0fe3d0 100644 --- a/dScripts/ai/FV/FvFlyingCreviceDragon.cpp +++ b/dScripts/ai/FV/FvFlyingCreviceDragon.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "SkillComponent.h" #include "GeneralUtils.h" +#include "RenderComponent.h" void FvFlyingCreviceDragon::OnStartup(Entity* self) { self->AddTimer("waypoint", 5); @@ -67,10 +68,10 @@ void FvFlyingCreviceDragon::OnArrived(Entity* self) { auto point = self->GetVar(u"waypoint"); if (point == 4) { - GameMessages::SendPlayAnimation(self, u"attack1", 2); + RenderComponent::PlayAnimation(self, u"attack1", 2.0f); self->AddTimer("platform1attack", 1.75f); } else if (point == 12) { - GameMessages::SendPlayAnimation(self, u"attack2", 2); + RenderComponent::PlayAnimation(self, u"attack2", 2.0f); const auto& group2 = EntityManager::Instance()->GetEntitiesInGroup("dragonFireballs2"); @@ -101,7 +102,7 @@ void FvFlyingCreviceDragon::OnArrived(Entity* self) { } } } else if (point == 16) { - GameMessages::SendPlayAnimation(self, u"attack3", 2); + RenderComponent::PlayAnimation(self, u"attack3", 2.0f); self->AddTimer("platform3attack", 0.5f); } } diff --git a/dScripts/ai/FV/FvNinjaGuard.cpp b/dScripts/ai/FV/FvNinjaGuard.cpp index 58267999..c487f5cc 100644 --- a/dScripts/ai/FV/FvNinjaGuard.cpp +++ b/dScripts/ai/FV/FvNinjaGuard.cpp @@ -1,6 +1,8 @@ #include "FvNinjaGuard.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" +#include "EntityManager.h" void FvNinjaGuard::OnStartup(Entity* self) { if (self->GetLOT() == 7412) { @@ -12,24 +14,24 @@ void FvNinjaGuard::OnStartup(Entity* self) { void FvNinjaGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* target) { if (emote != 392) { - GameMessages::SendPlayAnimation(self, u"no"); + RenderComponent::PlayAnimation(self, u"no"); return; } - GameMessages::SendPlayAnimation(self, u"scared"); + RenderComponent::PlayAnimation(self, u"scared"); if (self->GetLOT() == 7412) { auto* rightGuard = EntityManager::Instance()->GetEntity(m_RightGuard); if (rightGuard != nullptr) { - GameMessages::SendPlayAnimation(rightGuard, u"laugh_rt"); + RenderComponent::PlayAnimation(rightGuard, u"laugh_rt"); } } else if (self->GetLOT() == 11128) { auto* leftGuard = EntityManager::Instance()->GetEntity(m_LeftGuard); if (leftGuard != nullptr) { - GameMessages::SendPlayAnimation(leftGuard, u"laugh_lt"); + RenderComponent::PlayAnimation(leftGuard, u"laugh_lt"); } } } diff --git a/dScripts/ai/GENERAL/LegoDieRoll.cpp b/dScripts/ai/GENERAL/LegoDieRoll.cpp index 89819271..add3cd06 100644 --- a/dScripts/ai/GENERAL/LegoDieRoll.cpp +++ b/dScripts/ai/GENERAL/LegoDieRoll.cpp @@ -2,6 +2,7 @@ #include "Entity.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" #include "eMissionState.h" void LegoDieRoll::OnStartup(Entity* self) { @@ -17,23 +18,23 @@ void LegoDieRoll::OnTimerDone(Entity* self, std::string timerName) { switch (dieRoll) { case 1: - GameMessages::SendPlayAnimation(self, u"roll-die-1"); + RenderComponent::PlayAnimation(self, u"roll-die-1"); break; case 2: - GameMessages::SendPlayAnimation(self, u"roll-die-2"); + RenderComponent::PlayAnimation(self, u"roll-die-2"); break; case 3: - GameMessages::SendPlayAnimation(self, u"roll-die-3"); + RenderComponent::PlayAnimation(self, u"roll-die-3"); break; case 4: - GameMessages::SendPlayAnimation(self, u"roll-die-4"); + RenderComponent::PlayAnimation(self, u"roll-die-4"); break; case 5: - GameMessages::SendPlayAnimation(self, u"roll-die-5"); + RenderComponent::PlayAnimation(self, u"roll-die-5"); break; case 6: { - GameMessages::SendPlayAnimation(self, u"roll-die-6"); + RenderComponent::PlayAnimation(self, u"roll-die-6"); // tracking the It's Truly Random Achievement auto* owner = self->GetOwner(); auto* missionComponent = owner->GetComponent(); diff --git a/dScripts/ai/GF/GfOrgan.cpp b/dScripts/ai/GF/GfOrgan.cpp index 372ed3a2..3184aa82 100644 --- a/dScripts/ai/GF/GfOrgan.cpp +++ b/dScripts/ai/GF/GfOrgan.cpp @@ -1,5 +1,7 @@ #include "GfOrgan.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" void GfOrgan::OnUse(Entity* self, Entity* user) { if (self->GetBoolean(u"bIsInUse")) { @@ -11,7 +13,7 @@ void GfOrgan::OnUse(Entity* self, Entity* user) { self->SetBoolean(u"bIsInUse", true); self->AddTimer("reset", 5.0f); - GameMessages::SendPlayAnimation(user, u"jig"); + RenderComponent::PlayAnimation(user, u"jig"); } void GfOrgan::OnTimerDone(Entity* self, std::string timerName) { diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 703c6bbd..a62f6ee5 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -15,6 +15,7 @@ #include "InventoryComponent.h" #include "eMissionTaskType.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" void SGCannon::OnStartup(Entity* self) { Game::logger->Log("SGCannon", "OnStartup"); @@ -508,17 +509,17 @@ void SGCannon::RecordPlayerScore(Entity* self) { void SGCannon::PlaySceneAnimation(Entity* self, const std::u16string& animationName, bool onCannon, bool onPlayer, float_t priority) { for (auto* cannon : EntityManager::Instance()->GetEntitiesInGroup("cannongroup")) { - GameMessages::SendPlayAnimation(cannon, animationName, priority); + RenderComponent::PlayAnimation(cannon, animationName, priority); } if (onCannon) { - GameMessages::SendPlayAnimation(self, animationName, priority); + RenderComponent::PlayAnimation(self, animationName, priority); } if (onPlayer) { auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { - GameMessages::SendPlayAnimation(player, animationName, priority); + RenderComponent::PlayAnimation(player, animationName, priority); } } } diff --git a/dScripts/ai/NS/NsConcertInstrument.cpp b/dScripts/ai/NS/NsConcertInstrument.cpp index c7478a05..08464e5a 100644 --- a/dScripts/ai/NS/NsConcertInstrument.cpp +++ b/dScripts/ai/NS/NsConcertInstrument.cpp @@ -9,6 +9,7 @@ #include "MissionComponent.h" #include "eMissionState.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" // Constants are at the bottom @@ -122,7 +123,7 @@ void NsConcertInstrument::StartPlayingInstrument(Entity* self, Entity* player) { player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendPlayCinematic(player->GetObjectID(), cinematics.at(instrumentLot), UNASSIGNED_SYSTEM_ADDRESS); self->AddCallbackTimer(1.0f, [player, instrumentLot]() { - GameMessages::SendPlayAnimation(player, animations.at(instrumentLot), 2.0f); + RenderComponent::PlayAnimation(player, animations.at(instrumentLot), 2.0f); }); for (auto* soundBox : EntityManager::Instance()->GetEntitiesInGroup("Audio-Concert")) { @@ -153,7 +154,7 @@ void NsConcertInstrument::StopPlayingInstrument(Entity* self, Entity* player) { } GameMessages::SendEndCinematic(player->GetObjectID(), cinematics.at(instrumentLot), UNASSIGNED_SYSTEM_ADDRESS, 1.0f); - GameMessages::SendPlayAnimation(player, smashAnimations.at(instrumentLot), 2.0f); + RenderComponent::PlayAnimation(player, smashAnimations.at(instrumentLot), 2.0f); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stopCheckingMovement", 0, 0, player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); } diff --git a/dScripts/ai/NS/WhFans.cpp b/dScripts/ai/NS/WhFans.cpp index 44354127..8500e824 100644 --- a/dScripts/ai/NS/WhFans.cpp +++ b/dScripts/ai/NS/WhFans.cpp @@ -4,6 +4,8 @@ #include "GameMessages.h" #include "EntityManager.h" #include "PhantomPhysicsComponent.h" +#include "RenderComponent.h" +#include "Entity.h" void WhFans::OnStartup(Entity* self) { self->SetVar(u"alive", true); @@ -30,7 +32,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { if (fanVolumes.size() == 0 || !self->GetVar(u"alive")) return; if (self->GetVar(u"on")) { - GameMessages::SendPlayAnimation(self, u"fan-off"); + RenderComponent::PlayAnimation(self, u"fan-off"); renderComponent->StopEffect("fanOn"); self->SetVar(u"on", false); @@ -42,7 +44,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { EntityManager::Instance()->SerializeEntity(volume); } } else if (!self->GetVar(u"on") && self->GetVar(u"alive")) { - GameMessages::SendPlayAnimation(self, u"fan-on"); + RenderComponent::PlayAnimation(self, u"fan-on"); self->SetVar(u"on", true); diff --git a/dScripts/ai/WILD/WildAmbients.cpp b/dScripts/ai/WILD/WildAmbients.cpp index 16dfa043..c21b6d76 100644 --- a/dScripts/ai/WILD/WildAmbients.cpp +++ b/dScripts/ai/WILD/WildAmbients.cpp @@ -1,6 +1,7 @@ #include "WildAmbients.h" #include "GameMessages.h" +#include "RenderComponent.h" void WildAmbients::OnUse(Entity* self, Entity* user) { - GameMessages::SendPlayAnimation(self, u"interact"); + RenderComponent::PlayAnimation(self, u"interact"); } From 426bc963fe54376b421089d8de9cadd1a13a73fc Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 26 Mar 2023 03:09:04 -0700 Subject: [PATCH 002/116] Add Animation Table logic --- dCommon/DluAssert.h | 2 - dCommon/Metrics.cpp | 1 - dCommon/Metrics.hpp | 1 - dDatabase/Tables/CDActivitiesTable.cpp | 54 ++++++++--- dDatabase/Tables/CDActivitiesTable.h | 45 ++++----- dDatabase/Tables/CDActivityRewardsTable.h | 14 +-- dDatabase/Tables/CDAnimationsTable.cpp | 21 ++--- dDatabase/Tables/CDAnimationsTable.h | 55 ++++++++--- .../Tables/CDComponentsRegistryTable.cpp | 94 +++++++++++++++---- dDatabase/Tables/CDComponentsRegistryTable.h | 14 ++- dDatabase/Tables/CDItemComponentTable.cpp | 26 ++--- dDatabase/Tables/CDItemComponentTable.h | 58 ++++++------ dDatabase/Tables/CDLootMatrixTable.cpp | 2 +- dDatabase/Tables/CDLootMatrixTable.h | 2 +- dDatabase/Tables/CDMissionTasksTable.cpp | 12 +-- dDatabase/Tables/CDMissionTasksTable.h | 12 +-- dDatabase/Tables/CDMissionsTable.cpp | 6 +- dDatabase/Tables/CDMissionsTable.h | 6 +- dDatabase/Tables/CDObjectsTable.cpp | 20 ++-- dDatabase/Tables/CDObjectsTable.h | 20 ++-- dDatabase/Tables/CDPhysicsComponentTable.cpp | 16 ++-- dDatabase/Tables/CDPhysicsComponentTable.h | 16 ++-- dDatabase/Tables/CDSkillBehaviorTable.cpp | 28 +++--- dDatabase/Tables/CDSkillBehaviorTable.h | 28 +++--- dDatabase/Tables/CDTable.h | 3 + dDatabase/Tables/CDZoneTableTable.cpp | 18 ++-- dDatabase/Tables/CDZoneTableTable.h | 18 ++-- dGame/Entity.cpp | 6 +- dGame/LeaderboardManager.cpp | 10 +- dGame/dComponents/RenderComponent.cpp | 18 ++-- dGame/dComponents/RenderComponent.h | 16 ++++ .../dComponents/ScriptedActivityComponent.cpp | 34 ++++--- dGame/dComponents/ScriptedActivityComponent.h | 16 +--- dGame/dUtilities/Loot.cpp | 1 - dMasterServer/MasterServer.cpp | 3 +- .../02_server/Enemy/AM/AmDarklingDragon.cpp | 2 +- .../Equipment/MaestromExtracticatorServer.cpp | 5 +- .../Equipment/MaestromExtracticatorServer.h | 1 + .../02_server/Map/NT/NtParadoxTeleServer.cpp | 5 +- dScripts/BaseConsoleTeleportServer.cpp | 1 - 40 files changed, 419 insertions(+), 291 deletions(-) diff --git a/dCommon/DluAssert.h b/dCommon/DluAssert.h index ce971122..c54dd54e 100644 --- a/dCommon/DluAssert.h +++ b/dCommon/DluAssert.h @@ -3,8 +3,6 @@ #include -#define _DEBUG - #ifdef _DEBUG # define DluAssert(expression) assert(expression) #else diff --git a/dCommon/Metrics.cpp b/dCommon/Metrics.cpp index 3a3b7d78..b97b5435 100644 --- a/dCommon/Metrics.cpp +++ b/dCommon/Metrics.cpp @@ -14,7 +14,6 @@ std::vector Metrics::m_Variables = { MetricVariable::CPUTime, MetricVariable::Sleep, MetricVariable::Frame, - MetricVariable::Database, }; void Metrics::AddMeasurement(MetricVariable variable, int64_t value) { diff --git a/dCommon/Metrics.hpp b/dCommon/Metrics.hpp index b7ac748f..c03c914f 100644 --- a/dCommon/Metrics.hpp +++ b/dCommon/Metrics.hpp @@ -20,7 +20,6 @@ enum class MetricVariable : int32_t CPUTime, Sleep, Frame, - Database, }; struct Metric diff --git a/dDatabase/Tables/CDActivitiesTable.cpp b/dDatabase/Tables/CDActivitiesTable.cpp index 2c2da31e..e1660d66 100644 --- a/dDatabase/Tables/CDActivitiesTable.cpp +++ b/dDatabase/Tables/CDActivitiesTable.cpp @@ -1,11 +1,27 @@ #include "CDActivitiesTable.h" -CDActivitiesTable::CDActivitiesTable() { +CDActivitiesTable::CDActivitiesTable(void) { + + // First, get the size of the table + unsigned int size = 0; + auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Activities"); + while (!tableSize.eof()) { + size = tableSize.getIntField(0, 0); + + tableSize.nextRow(); + } + + tableSize.finalize(); + + // Reserve the size + this->entries.reserve(size); + + // Now get the data auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Activities"); while (!tableData.eof()) { CDActivities entry; - ActivityID activityId = tableData.getIntField("ActivityID", -1); - UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); + entry.ActivityID = tableData.getIntField("ActivityID", -1); + entry.locStatus = tableData.getIntField("locStatus", -1); entry.instanceMapID = tableData.getIntField("instanceMapID", -1); entry.minTeams = tableData.getIntField("minTeams", -1); entry.maxTeams = tableData.getIntField("maxTeams", -1); @@ -13,26 +29,34 @@ CDActivitiesTable::CDActivitiesTable() { entry.maxTeamSize = tableData.getIntField("maxTeamSize", -1); entry.waitTime = tableData.getIntField("waitTime", -1); entry.startDelay = tableData.getIntField("startDelay", -1); - UNUSED_COLUMN(entry.requiresUniqueData = tableData.getIntField("requiresUniqueData", -1)); + entry.requiresUniqueData = tableData.getIntField("requiresUniqueData", -1); entry.leaderboardType = tableData.getIntField("leaderboardType", -1); - UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1)); + entry.localize = tableData.getIntField("localize", -1); entry.optionalCostLOT = tableData.getIntField("optionalCostLOT", -1); entry.optionalCostCount = tableData.getIntField("optionalCostCount", -1); - UNUSED_COLUMN(entry.showUIRewards = tableData.getIntField("showUIRewards", -1)); - UNUSED_COLUMN(entry.CommunityActivityFlagID = tableData.getIntField("CommunityActivityFlagID", -1)); - UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); + entry.showUIRewards = tableData.getIntField("showUIRewards", -1); + entry.CommunityActivityFlagID = tableData.getIntField("CommunityActivityFlagID", -1); + entry.gate_version = tableData.getStringField("gate_version", ""); entry.noTeamLootOnDeath = tableData.getIntField("noTeamLootOnDeath", -1); - UNUSED_COLUMN(entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f)); - - auto insertedElement = this->entries.insert_or_assign(activityId, entry); - DluAssert(insertedElement.second == true); + entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f); + this->entries.push_back(entry); tableData.nextRow(); } + tableData.finalize(); } -CDActivitiesResult CDActivitiesTable::GetActivity(ActivityID id) { - const auto foundElement = this->entries.find(id); - return foundElement != this->entries.end() ? CDActivitiesResult(foundElement->second) : CDActivitiesResult(); +std::vector CDActivitiesTable::Query(std::function predicate) { + + std::vector data = cpplinq::from(this->entries) + >> cpplinq::where(predicate) + >> cpplinq::to_vector(); + + return data; } + +std::vector CDActivitiesTable::GetEntries(void) const { + return this->entries; +} + diff --git a/dDatabase/Tables/CDActivitiesTable.h b/dDatabase/Tables/CDActivitiesTable.h index ed454b6e..4b60afbd 100644 --- a/dDatabase/Tables/CDActivitiesTable.h +++ b/dDatabase/Tables/CDActivitiesTable.h @@ -1,37 +1,38 @@ #pragma once +// Custom Classes #include "CDTable.h" -typedef uint32_t ActivityID; - struct CDActivities { - UNUSED_COLUMN(uint32_t locStatus); - uint32_t instanceMapID; - uint32_t minTeams; - uint32_t maxTeams; - uint32_t minTeamSize; - uint32_t maxTeamSize; - uint32_t waitTime; - uint32_t startDelay; - UNUSED_COLUMN(bool requiresUniqueData); - uint32_t leaderboardType; - UNUSED_COLUMN(bool localize); - int32_t optionalCostLOT; - int32_t optionalCostCount; - UNUSED_COLUMN(bool showUIRewards); - UNUSED_COLUMN(uint32_t CommunityActivityFlagID); - UNUSED_COLUMN(std::string gate_version); + unsigned int ActivityID; + unsigned int locStatus; + unsigned int instanceMapID; + unsigned int minTeams; + unsigned int maxTeams; + unsigned int minTeamSize; + unsigned int maxTeamSize; + unsigned int waitTime; + unsigned int startDelay; + bool requiresUniqueData; + unsigned int leaderboardType; + bool localize; + int optionalCostLOT; + int optionalCostCount; + bool showUIRewards; + unsigned int CommunityActivityFlagID; + std::string gate_version; bool noTeamLootOnDeath; - UNUSED_COLUMN(float optionalPercentage); + float optionalPercentage; }; -typedef LookupResult CDActivitiesResult; class CDActivitiesTable : public CDTable { private: - std::map entries; + std::vector entries; public: CDActivitiesTable(); // Queries the table with a custom "where" clause - CDActivitiesResult GetActivity(ActivityID predicate); + std::vector Query(std::function predicate); + + std::vector GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDActivityRewardsTable.h b/dDatabase/Tables/CDActivityRewardsTable.h index 9a4a4ce8..b5503fb6 100644 --- a/dDatabase/Tables/CDActivityRewardsTable.h +++ b/dDatabase/Tables/CDActivityRewardsTable.h @@ -4,13 +4,13 @@ #include "CDTable.h" struct CDActivityRewards { - unsigned int objectTemplate; - unsigned int ActivityRewardIndex; - int activityRating; - unsigned int LootMatrixIndex; - unsigned int CurrencyIndex; - unsigned int ChallengeRating; - std::string description; + unsigned int objectTemplate; //!< The object template (?) + unsigned int ActivityRewardIndex; //!< The activity reward index + int activityRating; //!< The activity rating + unsigned int LootMatrixIndex; //!< The loot matrix index + unsigned int CurrencyIndex; //!< The currency index + unsigned int ChallengeRating; //!< The challenge rating + std::string description; //!< The description }; class CDActivityRewardsTable : public CDTable { diff --git a/dDatabase/Tables/CDAnimationsTable.cpp b/dDatabase/Tables/CDAnimationsTable.cpp index 4f4730de..76ce0e5a 100644 --- a/dDatabase/Tables/CDAnimationsTable.cpp +++ b/dDatabase/Tables/CDAnimationsTable.cpp @@ -2,7 +2,7 @@ #include "GeneralUtils.h" #include "Game.h" -bool CDAnimationsTable::CacheData(CppSQLite3Statement queryToCache) { +bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) { auto tableData = queryToCache.execQuery(); // If we received a bad lookup, cache it anyways so we do not run the query again. if (tableData.eof()) return false; @@ -16,15 +16,15 @@ bool CDAnimationsTable::CacheData(CppSQLite3Statement queryToCache) { CDAnimation entry; entry.animation_name = tableData.getStringField("animation_name", ""); entry.chance_to_play = tableData.getFloatField("chance_to_play", 1.0f); - entry.min_loops = tableData.getIntField("min_loops", 0); - entry.max_loops = tableData.getIntField("max_loops", 0); + UNUSED_COLUMN(entry.min_loops = tableData.getIntField("min_loops", 0);) + UNUSED_COLUMN(entry.max_loops = tableData.getIntField("max_loops", 0);) entry.animation_length = tableData.getFloatField("animation_length", 0.0f); - entry.hideEquip = tableData.getIntField("hideEquip", 0) == 1; - entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", 0) == 1; - entry.restartable = tableData.getIntField("restartable", 0) == 1; - entry.face_animation_name = tableData.getStringField("face_animation_name", ""); - entry.priority = tableData.getFloatField("priority", 0.0f); - entry.blendTime = tableData.getFloatField("blendTime", 0.0f); + UNUSED_COLUMN(entry.hideEquip = tableData.getIntField("hideEquip", 0) == 1;) + UNUSED_COLUMN(entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", 0) == 1;) + UNUSED_COLUMN(entry.restartable = tableData.getIntField("restartable", 0) == 1;) + UNUSED_COLUMN(entry.face_animation_name = tableData.getStringField("face_animation_name", "");) + UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);) + UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);) this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry); tableData.nextRow(); @@ -61,18 +61,17 @@ void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) { CDAnimationLookupResult CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) { CDAnimationKey animationKey(animationType, animationGroupID); - auto randomAnimation = GeneralUtils::GenerateRandomNumber(0, 1); auto animationEntryCached = this->animations.find(animationKey); if (animationEntryCached == this->animations.end()) { this->CacheAnimations(animationKey); } auto animationEntry = this->animations.find(animationKey); - // If we have only one animation, return it regardless of the chance to play. if (animationEntry->second.size() == 1) { return CDAnimationLookupResult(animationEntry->second.front()); } + auto randomAnimation = GeneralUtils::GenerateRandomNumber(0, 1); for (auto& animationEntry : animationEntry->second) { randomAnimation -= animationEntry.chance_to_play; diff --git a/dDatabase/Tables/CDAnimationsTable.h b/dDatabase/Tables/CDAnimationsTable.h index b92e37cc..65f54d98 100644 --- a/dDatabase/Tables/CDAnimationsTable.h +++ b/dDatabase/Tables/CDAnimationsTable.h @@ -1,7 +1,7 @@ #pragma once -// Custom Classes #include "CDTable.h" +#include struct CDAnimation { // unsigned int animationGroupID; @@ -9,15 +9,15 @@ struct CDAnimation { // The above two are a pair to represent a primary key in the map. std::string animation_name; //!< The animation name float chance_to_play; //!< The chance to play the animation - unsigned int min_loops; //!< The minimum number of loops - unsigned int max_loops; //!< The maximum number of loops + UNUSED_COLUMN(unsigned int min_loops;) //!< The minimum number of loops + UNUSED_COLUMN(unsigned int max_loops;) //!< The maximum number of loops float animation_length; //!< The animation length - bool hideEquip; //!< Whether or not to hide the equip - bool ignoreUpperBody; //!< Whether or not to ignore the upper body - bool restartable; //!< Whether or not the animation is restartable - std::string face_animation_name; //!< The face animation name - float priority; //!< The priority - float blendTime; //!< The blend time + UNUSED_COLUMN(bool hideEquip;) //!< Whether or not to hide the equip + UNUSED_COLUMN(bool ignoreUpperBody;) //!< Whether or not to ignore the upper body + UNUSED_COLUMN(bool restartable;) //!< Whether or not the animation is restartable + UNUSED_COLUMN(std::string face_animation_name;) //!< The face animation name + UNUSED_COLUMN(float priority;) //!< The priority + UNUSED_COLUMN(float blendTime;) //!< The blend time }; typedef LookupResult CDAnimationLookupResult; @@ -27,13 +27,40 @@ class CDAnimationsTable : public CDTable { typedef std::string AnimationID; typedef std::pair CDAnimationKey; public: - CDAnimationLookupResult GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID); + /** + * Given an animationType and the previousAnimationName played, return the next animationType to play. + * If there are more than 1 animationTypes that can be played, one is selected at random but also does not allow + * the previousAnimationName to be played twice. + * + * @param animationType The animationID to lookup + * @param previousAnimationName The previously played animation + * @param animationGroupID The animationGroupID to lookup + * @return CDAnimationLookupResult + */ + [[nodiscard]] CDAnimationLookupResult GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID); + + /** + * Cache a full AnimationGroup by its ID. + */ void CacheAnimationGroup(AnimationGroupID animationGroupID); private: - void CacheAnimations(const CDAnimationKey animationKey); - bool CacheData(CppSQLite3Statement queryToCache); + /** - * Each animation type has a vector of animations. This is because there can be animations have a percent chance to play so one is selected at random. + * Cache all animations given a premade key */ - std::map> animations; + void CacheAnimations(const CDAnimationKey animationKey); + + /** + * Run the query responsible for caching the data. + * @param queryToCache + * @return true + * @return false + */ + bool CacheData(CppSQLite3Statement& queryToCache); + + /** + * Each animation is key'd by its animationName and its animationGroupID. Each + * animation has a possible list of animations. This is because there can be animations have a percent chance to play so one is selected at random. + */ + std::map> animations; }; diff --git a/dDatabase/Tables/CDComponentsRegistryTable.cpp b/dDatabase/Tables/CDComponentsRegistryTable.cpp index f553e23c..32012f6c 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.cpp +++ b/dDatabase/Tables/CDComponentsRegistryTable.cpp @@ -1,31 +1,93 @@ #include "CDComponentsRegistryTable.h" #include "eReplicaComponentType.h" -#include "dLogger.h" -#include "Game.h" -uint64_t CalculateId(uint64_t lhs, uint64_t rhs) { - return (lhs << 32) | rhs; -} +#define CDCLIENT_CACHE_ALL -void CDComponentsRegistryTable::ReadRow(CppSQLite3Query& rowData) { - uint32_t id = rowData.getIntField("id", -1); - eReplicaComponentType component_type = static_cast(rowData.getIntField("component_type", 0)); - uint32_t component_id = rowData.getIntField("component_id", -1); +CDComponentsRegistryTable::CDComponentsRegistryTable(void) { - auto insertedEntry = this->mappedEntries.insert_or_assign(CalculateId(id, static_cast(component_type)), component_id); - DluAssert(insertedEntry.second == true); -} +#ifdef CDCLIENT_CACHE_ALL + // First, get the size of the table + unsigned int size = 0; + auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ComponentsRegistry"); + while (!tableSize.eof()) { + size = tableSize.getIntField(0, 0); -CDComponentsRegistryTable::CDComponentsRegistryTable() { + tableSize.nextRow(); + } + + tableSize.finalize(); + + // Reserve the size + //this->entries.reserve(size); + + // Now get the data auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry"); while (!tableData.eof()) { - ReadRow(tableData); + CDComponentsRegistry entry; + entry.id = tableData.getIntField("id", -1); + entry.component_type = static_cast(tableData.getIntField("component_type", 0)); + entry.component_id = tableData.getIntField("component_id", -1); + + this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id); + tableData.nextRow(); } + tableData.finalize(); +#endif } int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) { - const auto iter = this->mappedEntries.find(CalculateId(id, static_cast(componentType))); - return iter != this->mappedEntries.end() ? iter->second : defaultValue; + const auto& iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); + + if (iter == this->mappedEntries.end()) { + return defaultValue; + } + + return iter->second; + +#ifndef CDCLIENT_CACHE_ALL + // Now get the data + std::stringstream query; + + query << "SELECT * FROM ComponentsRegistry WHERE id = " << std::to_string(id); + + auto tableData = CDClientDatabase::ExecuteQuery(query.str()); + while (!tableData.eof()) { + CDComponentsRegistry entry; + entry.id = tableData.getIntField("id", -1); + entry.component_type = tableData.getIntField("component_type", -1); + entry.component_id = tableData.getIntField("component_id", -1); + + //this->entries.push_back(entry); + + //Darwin's stuff: + const auto& it = this->mappedEntries.find(entry.id); + if (it != mappedEntries.end()) { + const auto& iter = it->second.find(entry.component_type); + if (iter == it->second.end()) { + it->second.insert(std::make_pair(entry.component_type, entry.component_id)); + } + } else { + std::map map; + map.insert(std::make_pair(entry.component_type, entry.component_id)); + this->mappedEntries.insert(std::make_pair(entry.id, map)); + } + + tableData.nextRow(); + } + + tableData.finalize(); + + const auto& it2 = this->mappedEntries.find(id); + if (it2 != mappedEntries.end()) { + const auto& iter = it2->second.find(componentType); + if (iter != it2->second.end()) { + return iter->second; + } + } + + return defaultValue; +#endif } + diff --git a/dDatabase/Tables/CDComponentsRegistryTable.h b/dDatabase/Tables/CDComponentsRegistryTable.h index 2e45f293..990072c9 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.h +++ b/dDatabase/Tables/CDComponentsRegistryTable.h @@ -1,15 +1,21 @@ #pragma once +// Custom Classes #include "CDTable.h" enum class eReplicaComponentType : uint32_t; +struct CDComponentsRegistry { + unsigned int id; //!< The LOT is used as the ID + eReplicaComponentType component_type; //!< See ComponentTypes enum for values + unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0 +}; + class CDComponentsRegistryTable : public CDTable { +private: + std::map mappedEntries; //id, component_type, component_id + public: CDComponentsRegistryTable(); int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0); -private: - void ReadRow(CppSQLite3Query& rowData); -private: - std::unordered_map mappedEntries; }; diff --git a/dDatabase/Tables/CDItemComponentTable.cpp b/dDatabase/Tables/CDItemComponentTable.cpp index d53269c2..54afc417 100644 --- a/dDatabase/Tables/CDItemComponentTable.cpp +++ b/dDatabase/Tables/CDItemComponentTable.cpp @@ -3,7 +3,8 @@ CDItemComponent CDItemComponentTable::Default = {}; -CDItemComponentTable::CDItemComponentTable() { +//! Constructor +CDItemComponentTable::CDItemComponentTable(void) { Default = CDItemComponent(); #ifdef CDCLIENT_CACHE_ALL @@ -54,13 +55,13 @@ CDItemComponentTable::CDItemComponentTable() { entry.currencyLOT = tableData.getIntField("currencyLOT", -1); entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1); entry.subItems = tableData.getStringField("subItems", ""); - UNUSED_COLUMN(entry.audioEventUse = tableData.getStringField("audioEventUse", "");) + entry.audioEventUse = tableData.getStringField("audioEventUse", ""); entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false; entry.commendationLOT = tableData.getIntField("commendationLOT", -1); entry.commendationCost = tableData.getIntField("commendationCost", -1); - UNUSED_COLUMN(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "");) + entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", ""); entry.currencyCosts = tableData.getStringField("currencyCosts", ""); - UNUSED_COLUMN(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "");) + entry.ingredientInfo = tableData.getStringField("ingredientInfo", ""); entry.locStatus = tableData.getIntField("locStatus", -1); entry.forgeType = tableData.getIntField("forgeType", -1); entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f); @@ -73,8 +74,8 @@ CDItemComponentTable::CDItemComponentTable() { #endif } -const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int id) { - const auto& it = this->entries.find(id); +const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int skillID) { + const auto& it = this->entries.find(skillID); if (it != this->entries.end()) { return it->second; } @@ -82,11 +83,11 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int i #ifndef CDCLIENT_CACHE_ALL std::stringstream query; - query << "SELECT * FROM ItemComponent WHERE id = " << std::to_string(id); + query << "SELECT * FROM ItemComponent WHERE id = " << std::to_string(skillID); auto tableData = CDClientDatabase::ExecuteQuery(query.str()); if (tableData.eof()) { - entries.insert(std::make_pair(id, Default)); + entries.insert(std::make_pair(skillID, Default)); return Default; } @@ -124,13 +125,13 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int i entry.currencyLOT = tableData.getIntField("currencyLOT", -1); entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1); entry.subItems = tableData.getStringField("subItems", ""); - UNUSED_COLUMN(entry.audioEventUse = tableData.getStringField("audioEventUse", "")); + UNUSED(entry.audioEventUse = tableData.getStringField("audioEventUse", "")); entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false; entry.commendationLOT = tableData.getIntField("commendationLOT", -1); entry.commendationCost = tableData.getIntField("commendationCost", -1); - UNUSED_COLUMN(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "")); + UNUSED(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "")); entry.currencyCosts = tableData.getStringField("currencyCosts", ""); - UNUSED_COLUMN(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "")); + UNUSED(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "")); entry.locStatus = tableData.getIntField("locStatus", -1); entry.forgeType = tableData.getIntField("forgeType", -1); entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f); @@ -139,7 +140,7 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int i tableData.nextRow(); } - const auto& it2 = this->entries.find(id); + const auto& it2 = this->entries.find(skillID); if (it2 != this->entries.end()) { return it2->second; } @@ -168,3 +169,4 @@ std::map CDItemComponentTable::ParseCraftingCurrencies(const CDIt return currencies; } + diff --git a/dDatabase/Tables/CDItemComponentTable.h b/dDatabase/Tables/CDItemComponentTable.h index 1cc46b4a..11c34dd6 100644 --- a/dDatabase/Tables/CDItemComponentTable.h +++ b/dDatabase/Tables/CDItemComponentTable.h @@ -5,60 +5,60 @@ #include "dCommonVars.h" struct CDItemComponent { - uint32_t id; //!< The Component ID + unsigned int id; //!< The Component ID std::string equipLocation; //!< The equip location - uint32_t baseValue; //!< The monetary base value of the item + unsigned int baseValue; //!< The monetary base value of the item bool isKitPiece; //!< Whether or not the item belongs to a kit - uint32_t rarity; //!< The rarity of the item - uint32_t itemType; //!< The item type + unsigned int rarity; //!< The rarity of the item + unsigned int itemType; //!< The item type int64_t itemInfo; //!< The item info bool inLootTable; //!< Whether or not the item is in a loot table bool inVendor; //!< Whether or not the item is in a vendor inventory bool isUnique; //!< ??? bool isBOP; //!< ??? bool isBOE; //!< ??? - uint32_t reqFlagID; //!< User must have completed this flag to get the item - uint32_t reqSpecialtyID; //!< ??? - uint32_t reqSpecRank; //!< ??? - uint32_t reqAchievementID; //!< The required achievement must be completed - uint32_t stackSize; //!< The stack size of the item - uint32_t color1; //!< Something to do with item color... - uint32_t decal; //!< The decal of the item - uint32_t offsetGroupID; //!< Something to do with group IDs - uint32_t buildTypes; //!< Something to do with building + unsigned int reqFlagID; //!< User must have completed this flag to get the item + unsigned int reqSpecialtyID; //!< ??? + unsigned int reqSpecRank; //!< ??? + unsigned int reqAchievementID; //!< The required achievement must be completed + unsigned int stackSize; //!< The stack size of the item + unsigned int color1; //!< Something to do with item color... + unsigned int decal; //!< The decal of the item + unsigned int offsetGroupID; //!< Something to do with group IDs + unsigned int buildTypes; //!< Something to do with building std::string reqPrecondition; //!< The required precondition - uint32_t animationFlag; //!< The Animation Flag - uint32_t equipEffects; //!< The effect played when the item is equipped + unsigned int animationFlag; //!< The Animation Flag + unsigned int equipEffects; //!< The effect played when the item is equipped bool readyForQA; //!< ??? - uint32_t itemRating; //!< ??? + unsigned int itemRating; //!< ??? bool isTwoHanded; //!< Whether or not the item is double handed - uint32_t minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object? - uint32_t delResIndex; //!< ??? - uint32_t currencyLOT; //!< ??? - uint32_t altCurrencyCost; //!< ??? + unsigned int minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object? + unsigned int delResIndex; //!< ??? + unsigned int currencyLOT; //!< ??? + unsigned int altCurrencyCost; //!< ??? std::string subItems; //!< A comma seperate string of sub items (maybe for multi-itemed things like faction test gear set) - UNUSED_COLUMN(std::string audioEventUse); //!< ??? + UNUSED(std::string audioEventUse); //!< ??? bool noEquipAnimation; //!< Whether or not there is an equip animation - uint32_t commendationLOT; //!< The commendation LOT - uint32_t commendationCost; //!< The commendation cost - UNUSED_COLUMN(std::string audioEquipMetaEventSet); //!< ??? + unsigned int commendationLOT; //!< The commendation LOT + unsigned int commendationCost; //!< The commendation cost + UNUSED(std::string audioEquipMetaEventSet); //!< ??? std::string currencyCosts; //!< Used for crafting - UNUSED_COLUMN(std::string ingredientInfo); //!< Unused - uint32_t locStatus; //!< ??? - uint32_t forgeType; //!< Forge Type + UNUSED(std::string ingredientInfo); //!< Unused + unsigned int locStatus; //!< ??? + unsigned int forgeType; //!< Forge Type float SellMultiplier; //!< Something to do with early vendors perhaps (but replaced) }; class CDItemComponentTable : public CDTable { private: - std::map entries; + std::map entries; public: CDItemComponentTable(); static std::map ParseCraftingCurrencies(const CDItemComponent& itemComponent); // Gets an entry by ID - const CDItemComponent& GetItemComponentByID(uint32_t id); + const CDItemComponent& GetItemComponentByID(unsigned int skillID); static CDItemComponent Default; }; diff --git a/dDatabase/Tables/CDLootMatrixTable.cpp b/dDatabase/Tables/CDLootMatrixTable.cpp index c6c5cd8e..8f25e8a3 100644 --- a/dDatabase/Tables/CDLootMatrixTable.cpp +++ b/dDatabase/Tables/CDLootMatrixTable.cpp @@ -29,7 +29,7 @@ CDLootMatrixTable::CDLootMatrixTable(void) { entry.maxToDrop = tableData.getIntField("maxToDrop", -1); entry.id = tableData.getIntField("id", -1); entry.flagID = tableData.getIntField("flagID", -1); - UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); this->entries.push_back(entry); tableData.nextRow(); diff --git a/dDatabase/Tables/CDLootMatrixTable.h b/dDatabase/Tables/CDLootMatrixTable.h index c56be7a8..c6035841 100644 --- a/dDatabase/Tables/CDLootMatrixTable.h +++ b/dDatabase/Tables/CDLootMatrixTable.h @@ -12,7 +12,7 @@ struct CDLootMatrix { unsigned int maxToDrop; //!< The maximum amount of loot from this matrix to drop unsigned int id; //!< The ID of the Loot Matrix unsigned int flagID; //!< ??? - UNUSED_COLUMN(std::string gate_version); //!< The Gate Version + UNUSED(std::string gate_version); //!< The Gate Version }; class CDLootMatrixTable : public CDTable { diff --git a/dDatabase/Tables/CDMissionTasksTable.cpp b/dDatabase/Tables/CDMissionTasksTable.cpp index ca65c85f..f32dca1b 100644 --- a/dDatabase/Tables/CDMissionTasksTable.cpp +++ b/dDatabase/Tables/CDMissionTasksTable.cpp @@ -22,18 +22,18 @@ CDMissionTasksTable::CDMissionTasksTable(void) { while (!tableData.eof()) { CDMissionTasks entry; entry.id = tableData.getIntField("id", -1); - UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); entry.taskType = tableData.getIntField("taskType", -1); entry.target = tableData.getIntField("target", -1); entry.targetGroup = tableData.getStringField("targetGroup", ""); entry.targetValue = tableData.getIntField("targetValue", -1); entry.taskParam1 = tableData.getStringField("taskParam1", ""); - UNUSED_COLUMN(entry.largeTaskIcon = tableData.getStringField("largeTaskIcon", "")); - UNUSED_COLUMN(entry.IconID = tableData.getIntField("IconID", -1)); + UNUSED(entry.largeTaskIcon = tableData.getStringField("largeTaskIcon", "")); + UNUSED(entry.IconID = tableData.getIntField("IconID", -1)); entry.uid = tableData.getIntField("uid", -1); - UNUSED_COLUMN(entry.largeTaskIconID = tableData.getIntField("largeTaskIconID", -1)); - UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); - UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.largeTaskIconID = tableData.getIntField("largeTaskIconID", -1)); + UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); this->entries.push_back(entry); tableData.nextRow(); diff --git a/dDatabase/Tables/CDMissionTasksTable.h b/dDatabase/Tables/CDMissionTasksTable.h index f5e780f5..fa213faf 100644 --- a/dDatabase/Tables/CDMissionTasksTable.h +++ b/dDatabase/Tables/CDMissionTasksTable.h @@ -5,18 +5,18 @@ struct CDMissionTasks { unsigned int id; //!< The Mission ID that the task belongs to - UNUSED_COLUMN(unsigned int locStatus); //!< ??? + UNUSED(unsigned int locStatus); //!< ??? unsigned int taskType; //!< The task type unsigned int target; //!< The mission target std::string targetGroup; //!< The mission target group int targetValue; //!< The target value std::string taskParam1; //!< The task param 1 - UNUSED_COLUMN(std::string largeTaskIcon); //!< ??? - UNUSED_COLUMN(unsigned int IconID); //!< ??? + UNUSED(std::string largeTaskIcon); //!< ??? + UNUSED(unsigned int IconID); //!< ??? unsigned int uid; //!< ??? - UNUSED_COLUMN(unsigned int largeTaskIconID); //!< ??? - UNUSED_COLUMN(bool localize); //!< Whether or not the task should be localized - UNUSED_COLUMN(std::string gate_version); //!< ??? + UNUSED(unsigned int largeTaskIconID); //!< ??? + UNUSED(bool localize); //!< Whether or not the task should be localized + UNUSED(std::string gate_version); //!< ??? }; class CDMissionTasksTable : public CDTable { diff --git a/dDatabase/Tables/CDMissionsTable.cpp b/dDatabase/Tables/CDMissionsTable.cpp index 53137560..d4ee40ae 100644 --- a/dDatabase/Tables/CDMissionsTable.cpp +++ b/dDatabase/Tables/CDMissionsTable.cpp @@ -71,9 +71,9 @@ CDMissionsTable::CDMissionsTable(void) { entry.isRandom = tableData.getIntField("isRandom", -1) == 1 ? true : false; entry.randomPool = tableData.getStringField("randomPool", ""); entry.UIPrereqID = tableData.getIntField("UIPrereqID", -1); - UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED_COLUMN(entry.HUDStates = tableData.getStringField("HUDStates", "")); - UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.HUDStates = tableData.getStringField("HUDStates", "")); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1); this->entries.push_back(entry); diff --git a/dDatabase/Tables/CDMissionsTable.h b/dDatabase/Tables/CDMissionsTable.h index 8e3f2039..e6a44b02 100644 --- a/dDatabase/Tables/CDMissionsTable.h +++ b/dDatabase/Tables/CDMissionsTable.h @@ -54,9 +54,9 @@ struct CDMissions { bool isRandom; //!< ??? std::string randomPool; //!< ??? int UIPrereqID; //!< ??? - UNUSED_COLUMN(std::string gate_version); //!< The gate version - UNUSED_COLUMN(std::string HUDStates); //!< ??? - UNUSED_COLUMN(int locStatus); //!< ??? + UNUSED(std::string gate_version); //!< The gate version + UNUSED(std::string HUDStates); //!< ??? + UNUSED(int locStatus); //!< ??? int reward_bankinventory; //!< The amount of bank space this mission rewards }; diff --git a/dDatabase/Tables/CDObjectsTable.cpp b/dDatabase/Tables/CDObjectsTable.cpp index e28fb100..c68c3e6a 100644 --- a/dDatabase/Tables/CDObjectsTable.cpp +++ b/dDatabase/Tables/CDObjectsTable.cpp @@ -65,18 +65,18 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) { CDObjects entry; entry.id = tableData.getIntField("id", -1); entry.name = tableData.getStringField("name", ""); - UNUSED_COLUMN(entry.placeable = tableData.getIntField("placeable", -1)); + UNUSED(entry.placeable = tableData.getIntField("placeable", -1)); entry.type = tableData.getStringField("type", ""); - UNUSED_COLUMN(ntry.description = tableData.getStringField(4, "")); - UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1)); - UNUSED_COLUMN(entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1)); - UNUSED_COLUMN(entry.displayName = tableData.getStringField("displayName", "")); + UNUSED(ntry.description = tableData.getStringField(4, "")); + UNUSED(entry.localize = tableData.getIntField("localize", -1)); + UNUSED(entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1)); + UNUSED(entry.displayName = tableData.getStringField("displayName", "")); entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f); - UNUSED_COLUMN(entry.nametag = tableData.getIntField("nametag", -1)); - UNUSED_COLUMN(entry._internalNotes = tableData.getStringField("_internalNotes", "")); - UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); - UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED_COLUMN(entry.HQ_valid = tableData.getIntField("HQ_valid", -1)); + UNUSED(entry.nametag = tableData.getIntField("nametag", -1)); + UNUSED(entry._internalNotes = tableData.getStringField("_internalNotes", "")); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.HQ_valid = tableData.getIntField("HQ_valid", -1)); this->entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); diff --git a/dDatabase/Tables/CDObjectsTable.h b/dDatabase/Tables/CDObjectsTable.h index dc6cc884..171eddef 100644 --- a/dDatabase/Tables/CDObjectsTable.h +++ b/dDatabase/Tables/CDObjectsTable.h @@ -6,18 +6,18 @@ struct CDObjects { unsigned int id; //!< The LOT of the object std::string name; //!< The internal name of the object - UNUSED_COLUMN(unsigned int placeable); //!< Whether or not the object is placable + UNUSED(unsigned int placeable); //!< Whether or not the object is placable std::string type; //!< The object type - UNUSED_COLUMN(std::string description); //!< An internal description of the object - UNUSED_COLUMN(unsigned int localize); //!< Whether or not the object should localize - UNUSED_COLUMN(unsigned int npcTemplateID); //!< Something related to NPCs... - UNUSED_COLUMN(std::string displayName); //!< The display name of the object + UNUSED(std::string description); //!< An internal description of the object + UNUSED(unsigned int localize); //!< Whether or not the object should localize + UNUSED(unsigned int npcTemplateID); //!< Something related to NPCs... + UNUSED(std::string displayName); //!< The display name of the object float interactionDistance; //!< The interaction distance of the object - UNUSED_COLUMN(unsigned int nametag); //!< ??? - UNUSED_COLUMN(std::string _internalNotes); //!< Some internal notes (rarely used) - UNUSED_COLUMN(unsigned int locStatus); //!< ??? - UNUSED_COLUMN(std::string gate_version); //!< The gate version for the object - UNUSED_COLUMN(unsigned int HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com + UNUSED(unsigned int nametag); //!< ??? + UNUSED(std::string _internalNotes); //!< Some internal notes (rarely used) + UNUSED(unsigned int locStatus); //!< ??? + UNUSED(std::string gate_version); //!< The gate version for the object + UNUSED(unsigned int HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com }; class CDObjectsTable : public CDTable { diff --git a/dDatabase/Tables/CDPhysicsComponentTable.cpp b/dDatabase/Tables/CDPhysicsComponentTable.cpp index 8c705f5b..bb21ed7f 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.cpp +++ b/dDatabase/Tables/CDPhysicsComponentTable.cpp @@ -7,19 +7,19 @@ CDPhysicsComponentTable::CDPhysicsComponentTable(void) { entry->id = tableData.getIntField("id", -1); entry->bStatic = tableData.getIntField("static", -1) != 0; entry->physicsAsset = tableData.getStringField("physics_asset", ""); - UNUSED_COLUMN(entry->jump = tableData.getIntField("jump", -1) != 0); - UNUSED_COLUMN(entry->doublejump = tableData.getIntField("doublejump", -1) != 0); + UNUSED(entry->jump = tableData.getIntField("jump", -1) != 0); + UNUSED(entry->doublejump = tableData.getIntField("doublejump", -1) != 0); entry->speed = tableData.getFloatField("speed", -1); - UNUSED_COLUMN(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1)); + UNUSED(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1)); entry->playerHeight = tableData.getFloatField("playerHeight"); entry->playerRadius = tableData.getFloatField("playerRadius"); entry->pcShapeType = tableData.getIntField("pcShapeType"); entry->collisionGroup = tableData.getIntField("collisionGroup"); - UNUSED_COLUMN(entry->airSpeed = tableData.getFloatField("airSpeed")); - UNUSED_COLUMN(entry->boundaryAsset = tableData.getStringField("boundaryAsset")); - UNUSED_COLUMN(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed")); - UNUSED_COLUMN(entry->friction = tableData.getFloatField("friction")); - UNUSED_COLUMN(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset")); + UNUSED(entry->airSpeed = tableData.getFloatField("airSpeed")); + UNUSED(entry->boundaryAsset = tableData.getStringField("boundaryAsset")); + UNUSED(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed")); + UNUSED(entry->friction = tableData.getFloatField("friction")); + UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset")); m_entries.insert(std::make_pair(entry->id, entry)); tableData.nextRow(); diff --git a/dDatabase/Tables/CDPhysicsComponentTable.h b/dDatabase/Tables/CDPhysicsComponentTable.h index ee4dddc1..e63d337d 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.h +++ b/dDatabase/Tables/CDPhysicsComponentTable.h @@ -6,19 +6,19 @@ struct CDPhysicsComponent { int id; bool bStatic; std::string physicsAsset; - UNUSED_COLUMN(bool jump); - UNUSED_COLUMN(bool doublejump); + UNUSED(bool jump); + UNUSED(bool doublejump); float speed; - UNUSED_COLUMN(float rotSpeed); + UNUSED(float rotSpeed); float playerHeight; float playerRadius; int pcShapeType; int collisionGroup; - UNUSED_COLUMN(float airSpeed); - UNUSED_COLUMN(std::string boundaryAsset); - UNUSED_COLUMN(float jumpAirSpeed); - UNUSED_COLUMN(float friction); - UNUSED_COLUMN(std::string gravityVolumeAsset); + UNUSED(float airSpeed); + UNUSED(std::string boundaryAsset); + UNUSED(float jumpAirSpeed); + UNUSED(float friction); + UNUSED(std::string gravityVolumeAsset); }; class CDPhysicsComponentTable : public CDTable { diff --git a/dDatabase/Tables/CDSkillBehaviorTable.cpp b/dDatabase/Tables/CDSkillBehaviorTable.cpp index 8420a8c6..c5df78ef 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.cpp +++ b/dDatabase/Tables/CDSkillBehaviorTable.cpp @@ -24,24 +24,24 @@ CDSkillBehaviorTable::CDSkillBehaviorTable(void) { while (!tableData.eof()) { CDSkillBehavior entry; entry.skillID = tableData.getIntField("skillID", -1); - UNUSED_COLUMN(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); entry.behaviorID = tableData.getIntField("behaviorID", -1); entry.imaginationcost = tableData.getIntField("imaginationcost", -1); entry.cooldowngroup = tableData.getIntField("cooldowngroup", -1); entry.cooldown = tableData.getFloatField("cooldown", -1.0f); - UNUSED_COLUMN(entry.isNpcEditor = tableData.getIntField("isNpcEditor", -1) == 1 ? true : false); - UNUSED_COLUMN(entry.skillIcon = tableData.getIntField("skillIcon", -1)); - UNUSED_COLUMN(entry.oomSkillID = tableData.getStringField("oomSkillID", "")); - UNUSED_COLUMN(entry.oomBehaviorEffectID = tableData.getIntField("oomBehaviorEffectID", -1)); - UNUSED_COLUMN(entry.castTypeDesc = tableData.getIntField("castTypeDesc", -1)); - UNUSED_COLUMN(entry.imBonusUI = tableData.getIntField("imBonusUI", -1)); - UNUSED_COLUMN(entry.lifeBonusUI = tableData.getIntField("lifeBonusUI", -1)); - UNUSED_COLUMN(entry.armorBonusUI = tableData.getIntField("armorBonusUI", -1)); - UNUSED_COLUMN(entry.damageUI = tableData.getIntField("damageUI", -1)); - UNUSED_COLUMN(entry.hideIcon = tableData.getIntField("hideIcon", -1) == 1 ? true : false); - UNUSED_COLUMN(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); - UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED_COLUMN(entry.cancelType = tableData.getIntField("cancelType", -1)); + UNUSED(entry.isNpcEditor = tableData.getIntField("isNpcEditor", -1) == 1 ? true : false); + UNUSED(entry.skillIcon = tableData.getIntField("skillIcon", -1)); + UNUSED(entry.oomSkillID = tableData.getStringField("oomSkillID", "")); + UNUSED(entry.oomBehaviorEffectID = tableData.getIntField("oomBehaviorEffectID", -1)); + UNUSED(entry.castTypeDesc = tableData.getIntField("castTypeDesc", -1)); + UNUSED(entry.imBonusUI = tableData.getIntField("imBonusUI", -1)); + UNUSED(entry.lifeBonusUI = tableData.getIntField("lifeBonusUI", -1)); + UNUSED(entry.armorBonusUI = tableData.getIntField("armorBonusUI", -1)); + UNUSED(entry.damageUI = tableData.getIntField("damageUI", -1)); + UNUSED(entry.hideIcon = tableData.getIntField("hideIcon", -1) == 1 ? true : false); + UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.cancelType = tableData.getIntField("cancelType", -1)); this->entries.insert(std::make_pair(entry.skillID, entry)); //this->entries.push_back(entry); diff --git a/dDatabase/Tables/CDSkillBehaviorTable.h b/dDatabase/Tables/CDSkillBehaviorTable.h index 4e6bddb9..eb3094e0 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.h +++ b/dDatabase/Tables/CDSkillBehaviorTable.h @@ -5,24 +5,24 @@ struct CDSkillBehavior { unsigned int skillID; //!< The Skill ID of the skill - UNUSED_COLUMN(unsigned int locStatus); //!< ?? + UNUSED(unsigned int locStatus); //!< ?? unsigned int behaviorID; //!< The Behavior ID of the skill unsigned int imaginationcost; //!< The imagination cost of the skill unsigned int cooldowngroup; //!< The cooldown group ID of the skill float cooldown; //!< The cooldown time of the skill - UNUSED_COLUMN(bool isNpcEditor); //!< ??? - UNUSED_COLUMN(unsigned int skillIcon); //!< The Skill Icon ID - UNUSED_COLUMN(std::string oomSkillID); //!< ??? - UNUSED_COLUMN(unsigned int oomBehaviorEffectID); //!< ??? - UNUSED_COLUMN(unsigned int castTypeDesc); //!< The cast type description(?) - UNUSED_COLUMN(unsigned int imBonusUI); //!< The imagination bonus of the skill - UNUSED_COLUMN(nsigned int lifeBonusUI); //!< The life bonus of the skill - UNUSED_COLUMN(unsigned int armorBonusUI); //!< The armor bonus of the skill - UNUSED_COLUMN(unsigned int damageUI); //!< ??? - UNUSED_COLUMN(bool hideIcon); //!< Whether or not to show the icon - UNUSED_COLUMN(bool localize); //!< ??? - UNUSED_COLUMN(std::string gate_version); //!< ??? - UNUSED_COLUMN(unsigned int cancelType); //!< The cancel type (?) + UNUSED(bool isNpcEditor); //!< ??? + UNUSED(unsigned int skillIcon); //!< The Skill Icon ID + UNUSED(std::string oomSkillID); //!< ??? + UNUSED(unsigned int oomBehaviorEffectID); //!< ??? + UNUSED(unsigned int castTypeDesc); //!< The cast type description(?) + UNUSED(unsigned int imBonusUI); //!< The imagination bonus of the skill + UNUSED(nsigned int lifeBonusUI); //!< The life bonus of the skill + UNUSED(unsigned int armorBonusUI); //!< The armor bonus of the skill + UNUSED(unsigned int damageUI); //!< ??? + UNUSED(bool hideIcon); //!< Whether or not to show the icon + UNUSED(bool localize); //!< ??? + UNUSED(std::string gate_version); //!< ??? + UNUSED(unsigned int cancelType); //!< The cancel type (?) }; class CDSkillBehaviorTable : public CDTable { diff --git a/dDatabase/Tables/CDTable.h b/dDatabase/Tables/CDTable.h index 45c67b0d..e4c11fb9 100644 --- a/dDatabase/Tables/CDTable.h +++ b/dDatabase/Tables/CDTable.h @@ -16,6 +16,9 @@ #endif #include "cpplinq.hpp" +// Used for legacy +#define UNUSED(x) + // Enable this to skip some unused columns in some tables #define UNUSED_COLUMN(v) diff --git a/dDatabase/Tables/CDZoneTableTable.cpp b/dDatabase/Tables/CDZoneTableTable.cpp index 89158dd7..bafbf8fe 100644 --- a/dDatabase/Tables/CDZoneTableTable.cpp +++ b/dDatabase/Tables/CDZoneTableTable.cpp @@ -26,25 +26,25 @@ CDZoneTableTable::CDZoneTableTable(void) { entry.ghostdistance = tableData.getFloatField("ghostdistance", -1.0f); entry.population_soft_cap = tableData.getIntField("population_soft_cap", -1); entry.population_hard_cap = tableData.getIntField("population_hard_cap", -1); - UNUSED_COLUMN(entry.DisplayDescription = tableData.getStringField("DisplayDescription", "")); - UNUSED_COLUMN(entry.mapFolder = tableData.getStringField("mapFolder", "")); + UNUSED(entry.DisplayDescription = tableData.getStringField("DisplayDescription", "")); + UNUSED(entry.mapFolder = tableData.getStringField("mapFolder", "")); entry.smashableMinDistance = tableData.getFloatField("smashableMinDistance", -1.0f); entry.smashableMaxDistance = tableData.getFloatField("smashableMaxDistance", -1.0f); - UNUSED_COLUMN(entry.mixerProgram = tableData.getStringField("mixerProgram", "")); - UNUSED_COLUMN(entry.clientPhysicsFramerate = tableData.getStringField("clientPhysicsFramerate", "")); - UNUSED_COLUMN(entry.serverPhysicsFramerate = tableData.getStringField("serverPhysicsFramerate", "")); + UNUSED(entry.mixerProgram = tableData.getStringField("mixerProgram", "")); + UNUSED(entry.clientPhysicsFramerate = tableData.getStringField("clientPhysicsFramerate", "")); + UNUSED(entry.serverPhysicsFramerate = tableData.getStringField("serverPhysicsFramerate", "")); entry.zoneControlTemplate = tableData.getIntField("zoneControlTemplate", -1); entry.widthInChunks = tableData.getIntField("widthInChunks", -1); entry.heightInChunks = tableData.getIntField("heightInChunks", -1); entry.petsAllowed = tableData.getIntField("petsAllowed", -1) == 1 ? true : false; entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false; entry.fZoneWeight = tableData.getFloatField("fZoneWeight", -1.0f); - UNUSED_COLUMN(entry.thumbnail = tableData.getStringField("thumbnail", "")); + UNUSED(entry.thumbnail = tableData.getStringField("thumbnail", "")); entry.PlayerLoseCoinsOnDeath = tableData.getIntField("PlayerLoseCoinsOnDeath", -1) == 1 ? true : false; - UNUSED_COLUMN(entry.disableSaveLoc = tableData.getIntField("disableSaveLoc", -1) == 1 ? true : false); + UNUSED(entry.disableSaveLoc = tableData.getIntField("disableSaveLoc", -1) == 1 ? true : false); entry.teamRadius = tableData.getFloatField("teamRadius", -1.0f); - UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "")); - UNUSED_COLUMN(entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false); this->m_Entries.insert(std::make_pair(entry.zoneID, entry)); tableData.nextRow(); diff --git a/dDatabase/Tables/CDZoneTableTable.h b/dDatabase/Tables/CDZoneTableTable.h index e46a87ee..f844fd25 100644 --- a/dDatabase/Tables/CDZoneTableTable.h +++ b/dDatabase/Tables/CDZoneTableTable.h @@ -12,25 +12,25 @@ struct CDZoneTable { float ghostdistance; //!< The ghosting distance unsigned int population_soft_cap; //!< The "soft cap" on the world population unsigned int population_hard_cap; //!< The "hard cap" on the world population - UNUSED_COLUMN(std::string DisplayDescription); //!< The display description of the world - UNUSED_COLUMN(std::string mapFolder); //!< ??? + UNUSED(std::string DisplayDescription); //!< The display description of the world + UNUSED(std::string mapFolder); //!< ??? float smashableMinDistance; //!< The minimum smashable distance? float smashableMaxDistance; //!< The maximum smashable distance? - UNUSED_COLUMN(std::string mixerProgram); //!< ??? - UNUSED_COLUMN(std::string clientPhysicsFramerate); //!< The client physics framerate - UNUSED_COLUMN(std::string serverPhysicsFramerate); //!< The server physics framerate + UNUSED(std::string mixerProgram); //!< ??? + UNUSED(std::string clientPhysicsFramerate); //!< The client physics framerate + UNUSED(std::string serverPhysicsFramerate); //!< The server physics framerate unsigned int zoneControlTemplate; //!< The Zone Control template unsigned int widthInChunks; //!< The width of the world in chunks unsigned int heightInChunks; //!< The height of the world in chunks bool petsAllowed; //!< Whether or not pets are allowed in the world bool localize; //!< Whether or not the world should be localized float fZoneWeight; //!< ??? - UNUSED_COLUMN(std::string thumbnail); //!< The thumbnail of the world + UNUSED(std::string thumbnail); //!< The thumbnail of the world bool PlayerLoseCoinsOnDeath; //!< Whether or not the user loses coins on death - UNUSED_COLUMN(bool disableSaveLoc); //!< Disables the saving location? + UNUSED(bool disableSaveLoc); //!< Disables the saving location? float teamRadius; //!< ??? - UNUSED_COLUMN(std::string gate_version); //!< The gate version - UNUSED_COLUMN(bool mountsAllowed); //!< Whether or not mounts are allowed + UNUSED(std::string gate_version); //!< The gate version + UNUSED(bool mountsAllowed); //!< Whether or not mounts are allowed }; class CDZoneTableTable : public CDTable { diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 4b0e1506..1e03f108 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -593,9 +593,9 @@ void Entity::Initialize() { m_Components.insert(std::make_pair(eReplicaComponentType::BOUNCER, comp)); } - int32_t renderaComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER); - if ((renderaComponentId > 0 && m_TemplateID != 2365) || m_Character) { - RenderComponent* render = new RenderComponent(this, renderaComponentId); + int32_t renderComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER); + if ((renderComponentId > 0 && m_TemplateID != 2365) || m_Character) { + RenderComponent* render = new RenderComponent(this, renderComponentId); m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render)); } diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 5a4754b9..d85a95d4 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -277,11 +277,13 @@ void LeaderboardManager::SendLeaderboard(uint32_t gameID, InfoType infoType, boo } LeaderboardType LeaderboardManager::GetLeaderboardType(uint32_t gameID) { - CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); - auto activityResult = activitiesTable->GetActivity(gameID); + auto* activitiesTable = CDClientManager::Instance().GetTable(); + std::vector activities = activitiesTable->Query([=](const CDActivities& entry) { + return (entry.ActivityID == gameID); + }); - if (activityResult.FoundData()) { - return static_cast(activityResult.Data().leaderboardType); + for (const auto& activity : activities) { + return static_cast(activity.leaderboardType); } return LeaderboardType::None; diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index bccd6207..94f5fb5d 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -18,6 +18,8 @@ std::unordered_map RenderComponent::m_DurationCache{}; RenderComponent::RenderComponent(Entity* parent, int32_t componentId): Component(parent) { m_Effects = std::vector(); m_LastAnimationName = ""; + if (componentId == -1) return; + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM RenderComponent WHERE id = ?;"); query.bind(1, componentId); auto result = query.execQuery(); @@ -210,23 +212,21 @@ float RenderComponent::GetAnimationTime(Entity* self, const std::string& animati float RenderComponent::DoAnimation(Entity* self, const std::string& animation, bool sendAnimation, float priority, float scale) { - if (!self) return 0.0f; + float returnlength = 0.0f; + if (!self) return returnlength; auto* renderComponent = self->GetComponent(); - if (!renderComponent) return 0.0f; + if (!renderComponent) return returnlength; - Game::logger->Log("RenderComponent", "looking up animation %s playing anim %i priority %f scale %f", animation.c_str(), sendAnimation, priority, scale); auto* animationsTable = CDClientManager::Instance().GetTable(); for (auto& groupId : renderComponent->m_animationGroupIds) { - Game::logger->Log("RenderComponent", "checking id %i with previous being %s", groupId, renderComponent->GetLastAnimationName().c_str()); auto animationGroup = animationsTable->GetAnimation(animation, renderComponent->GetLastAnimationName(), groupId); if (animationGroup.FoundData()) { auto data = animationGroup.Data(); - Game::logger->Log("RenderComponent", "animation %s priority %f length %f", data.animation_name.c_str(), data.priority, data.animation_length); - if (sendAnimation) GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(animation), priority, scale); renderComponent->SetLastAnimationName(data.animation_name); - return data.animation_length; + returnlength = data.animation_length; } } - Game::logger->Log("RenderComponent", "unable to find animation %s for lot %i", animation.c_str(), self->GetLOT()); - return 0.0f; + if (sendAnimation) GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(animation), priority, scale); + if (returnlength == 0.0f) Game::logger->Log("RenderComponent", "WARNING: Unable to find animation %s for lot %i in any group.", animation.c_str(), self->GetLOT()); + return returnlength; } diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index ef916396..a0b21919 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -104,6 +104,22 @@ public: */ std::vector& GetEffects(); + /** + * Verifies that an animation can be played on this entity by checking + * if it has the animation assigned to its group. If it does, the animation is echo'd + * down to all clients to be played and the duration of the played animation is returned. + * If the animation did not exist or the function was called in an invalid state, 0 is returned. + * + * The logic here matches the exact client logic. + * + * @param self The entity that wants to play an animation + * @param animation The animation_type (animationID in the client) to be played. + * @param sendAnimation Whether or not to echo the animation down to all clients. + * @param priority The priority of the animation. Only used if sendAnimation is true. + * @param scale The scale of the animation. Only used if sendAnimation is true. + * + * @return The duration of the animation that was played. + */ static float DoAnimation(Entity* self, const std::string& animation, bool sendAnimation, float priority = 0.0f, float scale = 1.0f); static float PlayAnimation(Entity* self, const std::u16string& animation, float priority = 0.0f, float scale = 1.0f); diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 4f1e15d8..1bc8c01f 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -26,13 +26,13 @@ #include "CDActivityRewardsTable.h" #include "CDActivitiesTable.h" -ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID): Component(parent) { +ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { m_ActivityID = activityID; CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); - auto activityResult = activitiesTable->GetActivity(m_ActivityID); + std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); - if (activityResult.FoundData()) { - m_ActivityInfo = activityResult.Data(); + for (CDActivities activity : activities) { + m_ActivityInfo = activity; const auto mapID = m_ActivityInfo.instanceMapID; @@ -57,7 +57,6 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit if (destroyableComponent) { // check for LMIs and set the loot LMIs - Game::logger->Log("ScriptedActivityComponent", "i am %i with lmi %i", m_Parent->GetLOT(), destroyableComponent->GetLootMatrixID()); CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable(); std::vector activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) {return (entry.LootMatrixIndex == destroyableComponent->GetLootMatrixID()); }); @@ -65,13 +64,13 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit if (activityRewards.size() > 0) { startingLMI = activityRewards[0].LootMatrixIndex; - Game::logger->Log("ScriptedActivityComponent", "index 0 is %i %i", activityRewards[0].LootMatrixIndex, activityRewards[0].objectTemplate); } if (startingLMI > 0) { + // now time for bodge :) + std::vector objectTemplateActivities = activityRewardsTable->Query([=](CDActivityRewards entry) {return (activityRewards[0].objectTemplate == entry.objectTemplate); }); for (const auto& item : objectTemplateActivities) { - Game::logger->Log("ScriptedActivityComponent", "%i added loot matrix with rating %i index %i objectTemplate %i", m_Parent->GetLOT(), item.activityRating, item.LootMatrixIndex, item.objectTemplate); if (item.activityRating > 0 && item.activityRating < 5) { m_ActivityLootMatrices.insert({ item.activityRating, item.LootMatrixIndex }); } @@ -100,22 +99,21 @@ void ScriptedActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool void ScriptedActivityComponent::ReloadConfig() { CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); - auto activityResult = activitiesTable->GetActivity(m_ActivityID); - if (activityResult.FoundData()) { - auto data = activityResult.Data(); - auto mapID = data.instanceMapID; + std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); + for (auto activity : activities) { + auto mapID = m_ActivityInfo.instanceMapID; if ((mapID == 1203 || mapID == 1261 || mapID == 1303 || mapID == 1403) && Game::config->GetValue("solo_racing") == "1") { m_ActivityInfo.minTeamSize = 1; m_ActivityInfo.minTeams = 1; } else { - m_ActivityInfo.minTeamSize = data.minTeamSize; - m_ActivityInfo.minTeams = data.minTeams; + m_ActivityInfo.minTeamSize = activity.minTeamSize; + m_ActivityInfo.minTeams = activity.minTeams; } } } void ScriptedActivityComponent::HandleMessageBoxResponse(Entity* player, const std::string& id) { - if (m_ActivityID == 103) { + if (m_ActivityInfo.ActivityID == 103) { return; } @@ -127,7 +125,7 @@ void ScriptedActivityComponent::HandleMessageBoxResponse(Entity* player, const s } void ScriptedActivityComponent::PlayerJoin(Entity* player) { - if (m_ActivityID == 103 || PlayerIsInQueue(player) || !IsValidActivity(player)) { + if (m_ActivityInfo.ActivityID == 103 || PlayerIsInQueue(player) || !IsValidActivity(player)) { return; } @@ -392,7 +390,7 @@ void ScriptedActivityComponent::PlayerReady(Entity* player, bool bReady) { } ActivityInstance* ScriptedActivityComponent::NewInstance() { - auto* instance = new ActivityInstance(m_Parent, this, m_ActivityInfo); + auto* instance = new ActivityInstance(m_Parent, m_ActivityInfo); m_Instances.push_back(instance); return instance; } @@ -559,12 +557,12 @@ void ActivityInstance::StartZone() { void ActivityInstance::RewardParticipant(Entity* participant) { auto* missionComponent = participant->GetComponent(); if (missionComponent) { - missionComponent->Progress(eMissionTaskType::ACTIVITY, m_OwningComponent->GetActivityID()); + missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityInfo.ActivityID); } // First, get the activity data auto* activityRewardsTable = CDClientManager::Instance().GetTable(); - std::vector activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) { return (entry.objectTemplate == m_OwningComponent->GetActivityID()); }); + std::vector activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) { return (entry.objectTemplate == m_ActivityInfo.ActivityID); }); if (!activityRewards.empty()) { uint32_t minCoins = 0; diff --git a/dGame/dComponents/ScriptedActivityComponent.h b/dGame/dComponents/ScriptedActivityComponent.h index 84ac0bc2..1d49a62d 100644 --- a/dGame/dComponents/ScriptedActivityComponent.h +++ b/dGame/dComponents/ScriptedActivityComponent.h @@ -15,18 +15,13 @@ #include "CDActivitiesTable.h" -class ScriptedActivityComponent; - /** * Represents an instance of an activity, having participants and score */ class ActivityInstance { public: - ActivityInstance(Entity* parent, ScriptedActivityComponent* parentComponent, CDActivities activityInfo) { - m_Parent = parent; - m_OwningComponent = parentComponent; - m_ActivityInfo = activityInfo; - }; + ActivityInstance(Entity* parent, CDActivities activityInfo) { m_Parent = parent; m_ActivityInfo = activityInfo; }; + //~ActivityInstance(); /** * Adds an entity to this activity @@ -93,11 +88,6 @@ private: */ Entity* m_Parent; - /** - * The component that owns this activity (the ScriptedActivityComponent) - */ - ScriptedActivityComponent* m_OwningComponent; - /** * All the participants of this activity */ @@ -222,7 +212,7 @@ public: * Returns the ID of this activity * @return the ID of this activity */ - int GetActivityID() { return m_ActivityID; } + int GetActivityID() { return m_ActivityInfo.ActivityID; } /** * Returns if this activity has a lobby, e.g. if it needs to instance players to some other map diff --git a/dGame/dUtilities/Loot.cpp b/dGame/dUtilities/Loot.cpp index d1f30e41..da0f2487 100644 --- a/dGame/dUtilities/Loot.cpp +++ b/dGame/dUtilities/Loot.cpp @@ -17,7 +17,6 @@ #include "MissionComponent.h" #include "eMissionState.h" #include "eReplicaComponentType.h" -#include "Metrics.hpp" LootGenerator::LootGenerator() { CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable(); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 7bb70391..78c93328 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -334,7 +334,8 @@ int main(int argc, char** argv) { if (Game::config->GetValue("prestart_servers") != "" && Game::config->GetValue("prestart_servers") == "1") { StartChatServer(); - Game::im->GetInstance(1800, false, 0); + Game::im->GetInstance(0, false, 0); + Game::im->GetInstance(1000, false, 0); StartAuthServer(); } diff --git a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp index 0ee5431b..ff30f8e8 100644 --- a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp +++ b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp @@ -73,7 +73,7 @@ void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); float animationTime = RenderComponent::PlayAnimation(self, u"stunstart", 1.7f); - self->AddTimer("timeToStunLoop", animationTime); + self->AddTimer("timeToStunLoop", 1.0f); auto position = self->GetPosition(); auto forward = self->GetRotation().GetForwardVector(); diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp index f02c0568..4de8a998 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp @@ -7,7 +7,10 @@ #include "RenderComponent.h" void MaestromExtracticatorServer::OnStartup(Entity* self) { - self->AddTimer("PlayFail", RenderComponent::PlayAnimation(self, failAnim)); + float animTime = RenderComponent::PlayAnimation(self, failAnim); + if (animTime == 0.0f) animTime = defaultTime; + + self->AddTimer("PlayFail", animTime); self->AddTimer("RemoveSample", destroyAfterNoSampleTime); } diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.h b/dScripts/02_server/Equipment/MaestromExtracticatorServer.h index c93a1cde..f0e976f3 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.h +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.h @@ -13,5 +13,6 @@ public: private: const std::string failAnim = "idle_maelstrom"; const std::string collectAnim = "collect_maelstrom"; + const float defaultTime = 4.0f; const float destroyAfterNoSampleTime = 8.0f; }; diff --git a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp index e3ec8d7d..dc8a195f 100644 --- a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp @@ -28,9 +28,8 @@ void NtParadoxTeleServer::OnProximityUpdate(Entity* self, Entity* entering, std: true, true, true, true, true, true, true ); - RenderComponent::PlayAnimation(player, u"teledeath", 4.0f); - - const auto animTime = 2; + auto animTime = RenderComponent::PlayAnimation(player, u"teledeath", 4.0f); + if (animTime == 0.0f) animTime = 2.0f; self->AddCallbackTimer(animTime, [this, self, playerID]() { auto* player = EntityManager::Instance()->GetEntity(playerID); diff --git a/dScripts/BaseConsoleTeleportServer.cpp b/dScripts/BaseConsoleTeleportServer.cpp index 073b7826..41dde4c4 100644 --- a/dScripts/BaseConsoleTeleportServer.cpp +++ b/dScripts/BaseConsoleTeleportServer.cpp @@ -33,7 +33,6 @@ void BaseConsoleTeleportServer::BaseOnMessageBoxResponse(Entity* self, Entity* s } const auto& teleIntroAnim = self->GetVar(u"teleportAnim"); - Game::logger->Log("BaseConsoleTeleportServer", "%s",GeneralUtils::UTF16ToWTF8(teleIntroAnim).c_str()); auto animTime = 3.32999992370605f; if (!teleIntroAnim.empty()) { animTime = RenderComponent::PlayAnimation(player, teleIntroAnim); From 47445ada54570d6599af1b1b79550b9fd3ff2b4f Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 27 Mar 2023 01:13:34 -0700 Subject: [PATCH 003/116] Fix Wingreaper birds not moving Fix an issue where the Wingreaper birds no longer moved. The client seems to do the following: Default speed set to 10.0f Check the PhysicsComponent table for the column speed and if it exists set speed to that value and if the value was null set it to the default again. --- dGame/dComponents/MovementAIComponent.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 278e9106..3db76bee 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -307,13 +307,12 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) { foundComponent: - float speed; + // Client defaults speed to 10 and if the speed is also null in the table, it defaults to 10. + float speed = 10.0f; - if (physicsComponent == nullptr) { - speed = 8; - } else { - speed = physicsComponent->speed; - } + if (physicsComponent) speed = physicsComponent->speed; + + if (speed == -1.0f) speed = 10.0f; m_PhysicsSpeedCache[lot] = speed; From 308d56968a767cbe64be7bea093b4ba0c791b276 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 11 Apr 2023 22:25:02 -0700 Subject: [PATCH 004/116] Use epsilon comparison --- dGame/dComponents/MovementAIComponent.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 3db76bee..7acec5f7 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -312,7 +312,9 @@ foundComponent: if (physicsComponent) speed = physicsComponent->speed; - if (speed == -1.0f) speed = 10.0f; + float delta = fabs(speed) - 1.0f; + + if (delta <= std::numeric_limits::epsilon()) speed = 10.0f; m_PhysicsSpeedCache[lot] = speed; From c02963013bd0dfd7d04753e79a53ed2d1efb3a2d Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 12 Apr 2023 21:57:58 -0700 Subject: [PATCH 005/116] first draft --- dGame/LeaderboardManager.cpp | 353 ++++----------------------------- dGame/LeaderboardManager.h | 128 ++++++------ dMasterServer/MasterServer.cpp | 6 + 3 files changed, 109 insertions(+), 378 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d85a95d4..72101e64 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -13,17 +13,20 @@ #include "CDActivitiesTable.h" -Leaderboard::Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector entries, - LWOOBJID relatedPlayer, LeaderboardType leaderboardType) { +Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type leaderboardType) { this->relatedPlayer = relatedPlayer; this->gameID = gameID; this->weekly = weekly; this->infoType = infoType; - this->entries = std::move(entries); + this->entries = entries; this->leaderboardType = leaderboardType; } -std::u16string Leaderboard::ToString() const { +bool Leaderboard::IsScoreBetter(const uint32_t score) const { + +} + +void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { std::string leaderboard; leaderboard += "ADO.Result=7:1\n"; @@ -50,19 +53,14 @@ std::u16string Leaderboard::ToString() const { index++; } - return GeneralUtils::UTF8ToUTF16(leaderboard); + // Serialize the thing to a BitStream + bitStream->WriteAlignedBytes((const unsigned char*)leaderboard.c_str(), leaderboard.size()); } -std::vector Leaderboard::GetEntries() { - return entries; -} - -uint32_t Leaderboard::GetGameID() const { - return gameID; -} - -uint32_t Leaderboard::GetInfoType() const { - return infoType; +void Leaderboard::SetupLeaderboard() { + // Setup query based on activity. + // Where clause will vary based on what query we are doing + } void Leaderboard::Send(LWOOBJID targetID) const { @@ -78,10 +76,10 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t return; auto* character = player->GetCharacter(); - if (character == nullptr) + if (!character) return; - auto* select = Database::CreatePreppedStmt("SELECT time, score FROM leaderboard WHERE character_id = ? AND game_id = ?;"); + std::unique_ptr select(Database::CreatePreppedStmt("SELECT time, score FROM leaderboard WHERE character_id = ? AND game_id = ?;")); select->setUInt64(1, character->GetID()); select->setInt(2, gameID); @@ -100,23 +98,23 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1"; switch (leaderboardType) { - case ShootingGallery: + case Leaderboard::Type::ShootingGallery: if (score <= storedScore) highscore = false; break; - case Racing: + case Leaderboard::Type::Racing: if (time >= storedTime) highscore = false; break; - case MonumentRace: + case Leaderboard::Type::MonumentRace: if (time >= storedTime) highscore = false; break; - case FootRace: + case Leaderboard::Type::FootRace: if (time <= storedTime) highscore = false; break; - case Survival: + case Leaderboard::Type::Survival: if (classicSurvivalScoring) { if (time <= storedTime) { // Based on time (LU live) highscore = false; @@ -126,7 +124,7 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t highscore = false; } break; - case SurvivalNS: + case Leaderboard::Type::SurvivalNS: if (!(score > storedScore || (time < storedTime && score >= storedScore))) highscore = false; break; @@ -135,13 +133,11 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t } if (!highscore) { - delete select; delete result; return; } } - delete select; delete result; if (any) { @@ -166,305 +162,24 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t } } -Leaderboard* LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID playerID) { - auto leaderboardType = GetLeaderboardType(gameID); - - std::string query; - bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1"; - switch (infoType) { - case InfoType::Standings: - switch (leaderboardType) { - case ShootingGallery: - query = standingsScoreQuery; // Shooting gallery is based on the highest score. - break; - case FootRace: - query = standingsTimeQuery; // The higher your time, the better for FootRace. - break; - case Survival: - query = classicSurvivalScoring ? standingsTimeQuery : standingsScoreQuery; - break; - case SurvivalNS: - query = standingsScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time. - break; - default: - query = standingsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. - } - break; - case InfoType::Friends: - switch (leaderboardType) { - case ShootingGallery: - query = friendsScoreQuery; // Shooting gallery is based on the highest score. - break; - case FootRace: - query = friendsTimeQuery; // The higher your time, the better for FootRace. - break; - case Survival: - query = classicSurvivalScoring ? friendsTimeQuery : friendsScoreQuery; - break; - case SurvivalNS: - query = friendsScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time. - break; - default: - query = friendsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. - } - break; - - default: - switch (leaderboardType) { - case ShootingGallery: - query = topPlayersScoreQuery; // Shooting gallery is based on the highest score. - break; - case FootRace: - query = topPlayersTimeQuery; // The higher your time, the better for FootRace. - break; - case Survival: - query = classicSurvivalScoring ? topPlayersTimeQuery : topPlayersScoreQuery; - break; - case SurvivalNS: - query = topPlayersScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time. - break; - default: - query = topPlayersTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. - } - } - - auto* statement = Database::CreatePreppedStmt(query); - statement->setUInt(1, gameID); - - // Only the standings and friends leaderboards require the character ID to be set - if (infoType == Standings || infoType == Friends) { - auto characterID = 0; - - const auto* player = EntityManager::Instance()->GetEntity(playerID); - if (player != nullptr) { - auto* character = player->GetCharacter(); - if (character != nullptr) - characterID = character->GetID(); - } - - statement->setUInt64(2, characterID); - } - - auto* res = statement->executeQuery(); - - std::vector entries{}; - - uint32_t index = 0; - while (res->next()) { - LeaderboardEntry entry; - entry.playerID = res->getUInt64(4); - entry.playerName = res->getString(5); - entry.time = res->getUInt(1); - entry.score = res->getUInt(2); - entry.placement = res->getUInt(3); - entry.lastPlayed = res->getUInt(6); - - entries.push_back(entry); - index++; - } - - delete res; - delete statement; - - return new Leaderboard(gameID, infoType, weekly, entries, playerID, leaderboardType); -} - -void LeaderboardManager::SendLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID targetID, +void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { - const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, infoType, weekly, playerID); - leaderboard->Send(targetID); - delete leaderboard; + // Create the leaderboard here and then send it right after. On the stack. + Leaderboard leaderboard(gameID, infoType, weekly, GetLeaderboardType(gameID)); + leaderboard.SetupLeaderboard(); + leaderboard.Send(targetID); } -LeaderboardType LeaderboardManager::GetLeaderboardType(uint32_t gameID) { +// Done +Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { + auto lookup = leaderboardCache.find(gameID); + if (lookup != leaderboardCache.end()) return lookup->second; + auto* activitiesTable = CDClientManager::Instance().GetTable(); std::vector activities = activitiesTable->Query([=](const CDActivities& entry) { return (entry.ActivityID == gameID); }); - - for (const auto& activity : activities) { - return static_cast(activity.leaderboardType); - } - - return LeaderboardType::None; + auto type = activities.empty() ? static_cast(activities.at(0).leaderboardType) : Leaderboard::Type::None; + leaderboardCache.insert_or_assign(gameID, type); + return type; } - -const std::string LeaderboardManager::topPlayersScoreQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsScoreQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsScoreQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; - -const std::string LeaderboardManager::topPlayersScoreQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsScoreQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsScoreQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; - -const std::string LeaderboardManager::topPlayersTimeQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsTimeQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsTimeQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; - -const std::string LeaderboardManager::topPlayersTimeQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsTimeQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsTimeQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index cabdf2d6..5f3fa0b2 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -1,80 +1,90 @@ #pragma once #include #include + +#include "Singleton.h" #include "dCommonVars.h" -struct LeaderboardEntry { - uint64_t playerID; - std::string playerName; - uint32_t time; - uint32_t score; - uint32_t placement; - time_t lastPlayed; +namespace RakNet{ + class BitStream; }; -enum InfoType : uint32_t { - Top, // Top 11 all time players - Standings, // Ranking of the current player - Friends // Ranking between friends -}; - -enum LeaderboardType : uint32_t { - ShootingGallery, - Racing, - MonumentRace, - FootRace, - Survival = 5, - SurvivalNS = 6, - None = UINT_MAX -}; +typedef uint32_t GameID; class Leaderboard { public: - Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector entries, - LWOOBJID relatedPlayer = LWOOBJID_EMPTY, LeaderboardType = None); - std::vector GetEntries(); - [[nodiscard]] std::u16string ToString() const; - [[nodiscard]] uint32_t GetGameID() const; - [[nodiscard]] uint32_t GetInfoType() const; + struct Entry { + uint64_t playerID; + uint32_t time; + uint32_t score; + uint32_t placement; + time_t lastPlayed; + std::string playerName; + }; + typedef std::vector LeaderboardEntries; + + // Enums for leaderboards + enum InfoType : uint32_t { + Top, // Top 11 all time players + MyStanding, // Ranking of the current player + Friends // Ranking between friends + }; + + enum Type : uint32_t { + ShootingGallery, + Racing, + MonumentRace, + FootRace, + Survival = 5, + SurvivalNS = 6, + None = UINT_MAX + }; + + Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type = None); + + /** + * Serialize the Leaderboard to a BitStream + * + * Expensive! Leaderboards are very string intensive so be wary of performatnce calling this method. + */ + void Serialize(RakNet::BitStream* bitStream) const; + + /** + * Based on the associated gameID, return true if the score provided + * is better than the current entries' score + * @param score + * @return true + * @return false + */ + bool IsScoreBetter(const uint32_t score) const; + + /** + * Builds the leaderboard from the database based on the associated gameID + */ + void SetupLeaderboard(); + + /** + * Sends the leaderboard to the client specified by targetID. + */ void Send(LWOOBJID targetID) const; private: - std::vector entries{}; + LeaderboardEntries entries; LWOOBJID relatedPlayer; - uint32_t gameID; - uint32_t infoType; - LeaderboardType leaderboardType; + GameID gameID; + InfoType infoType; + Leaderboard::Type leaderboardType; bool weekly; }; -class LeaderboardManager { +class LeaderboardManager: public Singleton { + typedef std::map LeaderboardCache; public: - static LeaderboardManager* Instance() { - if (address == nullptr) - address = new LeaderboardManager; - return address; - } - static void SendLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID targetID, + void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID = LWOOBJID_EMPTY); - static Leaderboard* GetLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); - static void SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t score, uint32_t time); - static LeaderboardType GetLeaderboardType(uint32_t gameID); + void SaveScore(LWOOBJID playerID, GameID gameID, uint32_t score, uint32_t time); private: - static LeaderboardManager* address; - - // Modified 12/12/2021: Existing queries were renamed to be more descriptive. - static const std::string topPlayersScoreQuery; - static const std::string friendsScoreQuery; - static const std::string standingsScoreQuery; - static const std::string topPlayersScoreQueryAsc; - static const std::string friendsScoreQueryAsc; - static const std::string standingsScoreQueryAsc; - - // Added 12/12/2021: Queries dictated by time are needed for certain minigames. - static const std::string topPlayersTimeQuery; - static const std::string friendsTimeQuery; - static const std::string standingsTimeQuery; - static const std::string topPlayersTimeQueryAsc; - static const std::string friendsTimeQueryAsc; - static const std::string standingsTimeQueryAsc; + Leaderboard::Type GetLeaderboardType(const GameID gameID); + void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); + LeaderboardCache leaderboardCache; }; diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index cc2bdd90..f10b33bf 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -150,6 +150,12 @@ int main(int argc, char** argv) { const bool oldCDServerExists = std::filesystem::exists(Game::assetManager->GetResPath() / "CDServer.sqlite"); const bool fdbExists = std::filesystem::exists(Game::assetManager->GetResPath() / "cdclient.fdb"); + auto query = Database::CreatePreppedStmt("select name, score, time, UNIX_TIMESTAMP(last_played) as lastPlayed from leaderboard as l join charinfo as ci on ci.id = l.character_id where game_id = 1864 order by score desc, time desc limit 11;"); + auto myResult = query->executeQuery(); + while (myResult->next()) { + Game::logger->Log("MasterServer", "%s %i %i %i", myResult->getString("name").c_str(), myResult->getInt("score"), myResult->getInt("time"), myResult->getInt("lastPlayed")); + } + if (!cdServerExists) { if (oldCDServerExists) { // If the file doesn't exist in the new CDServer location, copy it there. We copy because we may not have write permissions from the previous directory. From c91f0d16b3f78700be26a501c61e671c170aba4e Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 13 Apr 2023 00:45:03 -0700 Subject: [PATCH 006/116] Get it compiling, add a test and optimize heavily --- dCommon/Metrics.cpp | 1 + dCommon/Metrics.hpp | 1 + dGame/LeaderboardManager.cpp | 35 ++++----- dGame/LeaderboardManager.h | 13 +++- dGame/dGameMessages/GameMessages.cpp | 24 +++--- .../02_server/Map/AG/NpcAgCourseStarter.cpp | 4 +- dScripts/ActivityManager.cpp | 12 +-- tests/dGameTests/CMakeLists.txt | 1 + tests/dGameTests/LeaderboardTests.cpp | 76 +++++++++++++++++++ 9 files changed, 125 insertions(+), 42 deletions(-) create mode 100644 tests/dGameTests/LeaderboardTests.cpp diff --git a/dCommon/Metrics.cpp b/dCommon/Metrics.cpp index b97b5435..522bcf61 100644 --- a/dCommon/Metrics.cpp +++ b/dCommon/Metrics.cpp @@ -14,6 +14,7 @@ std::vector Metrics::m_Variables = { MetricVariable::CPUTime, MetricVariable::Sleep, MetricVariable::Frame, + MetricVariable::Leaderboard, }; void Metrics::AddMeasurement(MetricVariable variable, int64_t value) { diff --git a/dCommon/Metrics.hpp b/dCommon/Metrics.hpp index c03c914f..7009701b 100644 --- a/dCommon/Metrics.hpp +++ b/dCommon/Metrics.hpp @@ -20,6 +20,7 @@ enum class MetricVariable : int32_t CPUTime, Sleep, Frame, + Leaderboard, }; struct Metric diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 72101e64..9388b183 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -10,9 +10,10 @@ #include "CDClientManager.h" #include "GeneralUtils.h" #include "Entity.h" +#include #include "CDActivitiesTable.h" - +#include "Metrics.hpp" Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type leaderboardType) { this->relatedPlayer = relatedPlayer; this->gameID = gameID; @@ -22,39 +23,35 @@ Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoTy this->leaderboardType = leaderboardType; } -bool Leaderboard::IsScoreBetter(const uint32_t score) const { - -} - void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { - std::string leaderboard; + std::ostringstream leaderboard; - leaderboard += "ADO.Result=7:1\n"; - leaderboard += "Result.Count=1:1\n"; - leaderboard += "Result[0].Index=0:RowNumber\n"; - leaderboard += "Result[0].RowCount=1:" + std::to_string(entries.size()) + "\n"; + leaderboard << "ADO.Result=7:1\n"; // Unused in 1.10.64, but is in captures + leaderboard << "Result.Count=1:1\n"; // number of results, always 1? + leaderboard << "Result[0].Index=0:RowNumber\n"; // "Primary key" + leaderboard << "Result[0].RowCount=1:" << entries.size() << '\n'; // number of rows auto index = 0; for (const auto& entry : entries) { - leaderboard += "Result[0].Row[" + std::to_string(index) + "].LastPlayed=8:" + std::to_string(entry.lastPlayed) + "\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].CharacterID=8:" + std::to_string(entry.playerID) + "\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].NumPlayed=1:1\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].RowNumber=8:" + std::to_string(entry.placement) + "\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].Time=1:" + std::to_string(entry.time) + "\n"; + leaderboard << "Result[0].Row[" << index << "].LastPlayed=8:" << entry.lastPlayed << '\n'; + leaderboard << "Result[0].Row[" << index << "].CharacterID=8:" << entry.playerID << '\n'; + leaderboard << "Result[0].Row[" << index << "].NumPlayed=1:1\n"; // number of times the activity was played + leaderboard << "Result[0].Row[" << index << "].RowNumber=8:" << entry.placement << '\n'; + leaderboard << "Result[0].Row[" << index << "].Time=1:" << entry.time << '\n'; // Only these minigames have a points system if (leaderboardType == Survival || leaderboardType == ShootingGallery) { - leaderboard += "Result[0].Row[" + std::to_string(index) + "].Points=1:" + std::to_string(entry.score) + "\n"; + leaderboard << "Result[0].Row[" << index << "].Points=1:"<< entry.score << '\n'; } else if (leaderboardType == SurvivalNS) { - leaderboard += "Result[0].Row[" + std::to_string(index) + "].Wave=1:" + std::to_string(entry.score) + "\n"; + leaderboard << "Result[0].Row[" << index << "].Wave=1:"<< entry.score << '\n'; } - leaderboard += "Result[0].Row[" + std::to_string(index) + "].name=0:" + entry.playerName + "\n"; + leaderboard << "Result[0].Row[" << index << "].name=0:" << entry.playerName << '\n'; index++; } // Serialize the thing to a BitStream - bitStream->WriteAlignedBytes((const unsigned char*)leaderboard.c_str(), leaderboard.size()); + bitStream->Write(leaderboard.str().c_str(), leaderboard.tellp()); } void Leaderboard::SetupLeaderboard() { diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 5f3fa0b2..bbdf76e5 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -1,6 +1,7 @@ #pragma once -#include #include +#include +#include #include "Singleton.h" #include "dCommonVars.h" @@ -14,7 +15,7 @@ typedef uint32_t GameID; class Leaderboard { public: struct Entry { - uint64_t playerID; + LWOOBJID playerID; uint32_t time; uint32_t score; uint32_t placement; @@ -56,7 +57,7 @@ public: * @return true * @return false */ - bool IsScoreBetter(const uint32_t score) const; + bool IsScoreBetter(const uint32_t score) const { return false; }; /** * Builds the leaderboard from the database based on the associated gameID @@ -67,6 +68,12 @@ public: * Sends the leaderboard to the client specified by targetID. */ void Send(LWOOBJID targetID) const; + + /** + * Adds a new entry to the leaderboard + * Used for debug only! + */ + void AddEntry(Entry entry) { entries.push_back(entry); } private: LeaderboardEntries entries; LWOOBJID relatedPlayer; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 0fc32e2e..df58e8f1 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1630,17 +1630,17 @@ void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, bitStream.Write(objectID); bitStream.Write(GAME_MSG::GAME_MSG_SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA); - - bitStream.Write(leaderboard->GetGameID()); - bitStream.Write(leaderboard->GetInfoType()); + throw ""; + //bitStream.Write(leaderboard->GetGameID()); + //bitStream.Write(leaderboard->GetInfoType()); // Leaderboard is written back as LDF string - const auto leaderboardString = leaderboard->ToString(); - bitStream.Write(leaderboardString.size()); - for (const auto c : leaderboardString) { - bitStream.Write(c); - } - if (!leaderboardString.empty()) bitStream.Write(uint16_t(0)); + //const auto leaderboardString = leaderboard->ToString(); + //bitStream.Write(leaderboardString.size()); + //for (const auto c : leaderboardString) { + // bitStream.Write(c); + //} + //if (!leaderboardString.empty()) bitStream.Write(uint16_t(0)); bitStream.Write0(); bitStream.Write0(); @@ -1666,9 +1666,9 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream->ReadBit(); - const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, (InfoType)queryType, weekly, entity->GetObjectID()); - SendActivitySummaryLeaderboardData(entity->GetObjectID(), leaderboard, sysAddr); - delete leaderboard; + //const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, (InfoType)queryType, weekly, entity->GetObjectID()); + //SendActivitySummaryLeaderboardData(entity->GetObjectID(), leaderboard, sysAddr); + //delete leaderboard; } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index d2cc647e..7da4ccef 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -96,8 +96,8 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std } EntityManager::Instance()->SerializeEntity(self); - LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), - 0, (uint32_t)finish); + //LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), + // 0, (uint32_t)finish); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", scriptedActivityComponent->GetActivityID(), 0, sender->GetObjectID(), diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 078a7a02..acfa5a68 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -74,11 +74,11 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const LootGenerator::Instance().GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID)); // Save the new score to the leaderboard and show the leaderboard to the player - LeaderboardManager::SaveScore(playerID, gameID, score, value1); - const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, InfoType::Standings, - false, player->GetObjectID()); - GameMessages::SendActivitySummaryLeaderboardData(self->GetObjectID(), leaderboard, player->GetSystemAddress()); - delete leaderboard; + //LeaderboardManager::SaveScore(playerID, gameID, score, value1); + //const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, InfoType::Standings, + // false, player->GetObjectID()); + //GameMessages::SendActivitySummaryLeaderboardData(self->GetObjectID(), leaderboard, player->GetSystemAddress()); + //delete leaderboard; // Makes the leaderboard show up for the player GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", @@ -117,7 +117,7 @@ uint32_t ActivityManager::GetActivityID(const Entity* self) { } void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID, const uint32_t activityID, uint32_t numResults) { - LeaderboardManager::SendLeaderboard(activityID, Standings, false, self->GetObjectID(), playerID); + //LeaderboardManager::SendLeaderboard(activityID, Standings, false, self->GetObjectID(), playerID); } void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval, diff --git a/tests/dGameTests/CMakeLists.txt b/tests/dGameTests/CMakeLists.txt index b1fdaa07..30b5e20b 100644 --- a/tests/dGameTests/CMakeLists.txt +++ b/tests/dGameTests/CMakeLists.txt @@ -1,5 +1,6 @@ set(DGAMETEST_SOURCES "GameDependencies.cpp" + "LeaderboardTests.cpp" ) add_subdirectory(dComponentsTests) diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp new file mode 100644 index 00000000..6a45298b --- /dev/null +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -0,0 +1,76 @@ +#include "LeaderboardManager.h" + +#include "BitStream.h" +#include "GameDependencies.h" +#include "Metrics.hpp" +#include + +class LeaderboardTests : public GameDependenciesTest { +protected: + void SetUp() override { + SetUpDependencies(); + } + void TearDown() override { + TearDownDependencies(); + } + + void TestLeaderboard(Leaderboard& leaderboard, int32_t entries) { + Leaderboard::Entry entry; + entry.playerID = UINT64_MAX; + entry.time = 100; + entry.score = 100; + entry.placement = 1; + entry.lastPlayed = 0; + entry.playerName = "TestThreeWords"; + for (int32_t i = 0; i < entries; i++) leaderboard.AddEntry(entry); + Metrics::StartMeasurement(MetricVariable::Leaderboard); + for (int32_t i = 0; i < MAX_MEASURMENT_POINTS; i++) leaderboard.Serialize(&bitStream); + Metrics::EndMeasurement(MetricVariable::Leaderboard); + + auto timePassed = Metrics::GetMetric(MetricVariable::Leaderboard)->average; + Game::logger->Log("LeaderboardManager", "average time passed for %i leaderboard entries is %lluns", entries, timePassed); + bitStream.Reset(); + } + + CBITSTREAM; +}; + +/** + * Initial metrics + * 19: [12-04-23 23:56:31] [LeaderboardManager] average time passed for 1 leaderboard entries is 1671700ns + * 19: [12-04-23 23:56:31] [LeaderboardManager] average time passed for 10 leaderboard entries is 8388900ns + * 19: [12-04-23 23:56:31] [LeaderboardManager] average time passed for 100 leaderboard entries is 54680133ns + * 19: [12-04-23 23:56:33] [LeaderboardManager] average time passed for 1000 leaderboard entries is 506289325ns + + * Only do each std::to_string once + * 19: [12-04-23 23:57:31] [LeaderboardManager] average time passed for 1 leaderboard entries is 1472700ns + * 19: [12-04-23 23:57:31] [LeaderboardManager] average time passed for 10 leaderboard entries is 7035650ns + * 19: [12-04-23 23:57:31] [LeaderboardManager] average time passed for 100 leaderboard entries is 45147466ns + * 19: [12-04-23 23:57:33] [LeaderboardManager] average time passed for 1000 leaderboard entries is 435724550ns + * + * Only do Result[0].Row[index] once + * 19: [12-04-23 23:59:43] [LeaderboardManager] average time passed for 1 leaderboard entries is 1357700ns + * 19: [12-04-23 23:59:43] [LeaderboardManager] average time passed for 10 leaderboard entries is 6635350ns + * 19: [12-04-23 23:59:43] [LeaderboardManager] average time passed for 100 leaderboard entries is 40247800ns + * 19: [12-04-23 23:59:45] [LeaderboardManager] average time passed for 1000 leaderboard entries is 400965900ns + * + * Switch to ostringstream + * 19: [13-04-23 00:24:44] [LeaderboardManager] average time passed for 1 leaderboard entries is 1334300ns + * 19: [13-04-23 00:24:44] [LeaderboardManager] average time passed for 10 leaderboard entries is 5566250ns + * 19: [13-04-23 00:24:44] [LeaderboardManager] average time passed for 100 leaderboard entries is 34640066ns + * 19: [13-04-23 00:24:46] [LeaderboardManager] average time passed for 1000 leaderboard entries is 357226950ns + * + * No more std::to_string and revert "Only do Result[0].Row[index] once" + * 19: [13-04-23 00:39:18] [LeaderboardManager] average time passed for 1 leaderboard entries is 979200ns + * 19: [13-04-23 00:39:18] [LeaderboardManager] average time passed for 10 leaderboard entries is 4053350ns + * 19: [13-04-23 00:39:18] [LeaderboardManager] average time passed for 100 leaderboard entries is 24785233ns + * 19: [13-04-23 00:39:19] [LeaderboardManager] average time passed for 1000 leaderboard entries is 279457375ns + */ + +TEST_F(LeaderboardTests, LeaderboardSpeedTest) { + Leaderboard leaderboard(10, Leaderboard::InfoType::MyStanding, false, Leaderboard::Type::Survival); + TestLeaderboard(leaderboard, 1); + TestLeaderboard(leaderboard, 10); + TestLeaderboard(leaderboard, 100); + TestLeaderboard(leaderboard, 1000); +} From 41355cea58d875b5f5cc18a4d134d1b387b6db57 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 13 Apr 2023 21:55:09 -0700 Subject: [PATCH 007/116] Add remaining enum types --- dGame/LeaderboardManager.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index bbdf76e5..cb3b5455 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -36,8 +36,10 @@ public: Racing, MonumentRace, FootRace, + // There is no 4 Survival = 5, - SurvivalNS = 6, + SurvivalNS, + Donations, None = UINT_MAX }; From ed2639ce4e185b4b95ecc2a129a93f9f7f6f48bd Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 14 Apr 2023 01:32:52 -0700 Subject: [PATCH 008/116] Use inline functions --- dGame/LeaderboardManager.cpp | 73 +++++++++++++++++++++++++++++------- dGame/LeaderboardManager.h | 5 ++- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 9388b183..d3037fae 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -10,19 +10,23 @@ #include "CDClientManager.h" #include "GeneralUtils.h" #include "Entity.h" +#include "LDFFormat.h" #include #include "CDActivitiesTable.h" #include "Metrics.hpp" Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type leaderboardType) { - this->relatedPlayer = relatedPlayer; this->gameID = gameID; this->weekly = weekly; this->infoType = infoType; - this->entries = entries; this->leaderboardType = leaderboardType; } +template +void Leaderboard::WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, const std::string& key, const eLDFType& ldfType, const TypeToWrite& value) const { + leaderboard << "Result[0].Row[" << index << "]." << key << '=' << ldfType << ':' << value << '\n'; +} + void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { std::ostringstream leaderboard; @@ -33,20 +37,61 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { auto index = 0; for (const auto& entry : entries) { - leaderboard << "Result[0].Row[" << index << "].LastPlayed=8:" << entry.lastPlayed << '\n'; - leaderboard << "Result[0].Row[" << index << "].CharacterID=8:" << entry.playerID << '\n'; - leaderboard << "Result[0].Row[" << index << "].NumPlayed=1:1\n"; // number of times the activity was played - leaderboard << "Result[0].Row[" << index << "].RowNumber=8:" << entry.placement << '\n'; - leaderboard << "Result[0].Row[" << index << "].Time=1:" << entry.time << '\n'; + WriteLeaderboardRow(leaderboard, index, "CharacterID", eLDFType::LDF_TYPE_U64, entry.playerID); + WriteLeaderboardRow(leaderboard, index, "LastPlayed", eLDFType::LDF_TYPE_U64, entry.lastPlayed); + WriteLeaderboardRow(leaderboard, index, "NumPlayed", eLDFType::LDF_TYPE_S32, 1); + WriteLeaderboardRow(leaderboard, index, "name", eLDFType::LDF_TYPE_UTF_16, entry.playerName); - // Only these minigames have a points system - if (leaderboardType == Survival || leaderboardType == ShootingGallery) { - leaderboard << "Result[0].Row[" << index << "].Points=1:"<< entry.score << '\n'; - } else if (leaderboardType == SurvivalNS) { - leaderboard << "Result[0].Row[" << index << "].Wave=1:"<< entry.score << '\n'; + // Each minigame has its own "points" system + switch (leaderboardType) { + case Type::ShootingGallery: + WriteLeaderboardRow(leaderboard, index, "HitPercentage", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // HitPercentage:3 between 0 and 1 + WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); + // RowNumber:1 + WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); + // Score:1 + case Type::Racing: + WriteLeaderboardRow(leaderboard, index, "BestLapTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // BestLapTime:3 + WriteLeaderboardRow(leaderboard, index, "BestTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // BestTime:3 + WriteLeaderboardRow(leaderboard, index, "License", eLDFType::LDF_TYPE_S32, 0); + // License:1 + WriteLeaderboardRow(leaderboard, index, "NumWins", eLDFType::LDF_TYPE_S32, 0); + // NumWins:1 + WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_U64, entry.placement); + // RowNumber:8 + case Type::MonumentRace: + WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); + // RowNumber:1 + // Time:1(?) + case Type::FootRace: + WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); + // RowNumber:1 + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, 0); + // Time:1 + case Type::Survival: + WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); + // Points:1 + WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); + // RowNumber:1 + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, 0); + // Time:1 + case Type::SurvivalNS: + WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_U64, entry.placement); + // RowNumber:8 + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1 + WriteLeaderboardRow(leaderboard, index, "Wave", eLDFType::LDF_TYPE_S32, entry.score); + // Wave:1 + case Type::Donations: + // Something? idk yet. + case Type::None: + break; + default: + break; } - - leaderboard << "Result[0].Row[" << index << "].name=0:" << entry.playerName << '\n'; index++; } diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index cb3b5455..6432aa8d 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -5,6 +5,7 @@ #include "Singleton.h" #include "dCommonVars.h" +#include "LDFFormat.h" namespace RakNet{ class BitStream; @@ -36,7 +37,7 @@ public: Racing, MonumentRace, FootRace, - // There is no 4 + // There is no 4 defined anywhere in the client or cdclient Survival = 5, SurvivalNS, Donations, @@ -77,6 +78,8 @@ public: */ void AddEntry(Entry entry) { entries.push_back(entry); } private: +template + inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, const std::string& key, const eLDFType& ldfType, const TypeToWrite& value) const; LeaderboardEntries entries; LWOOBJID relatedPlayer; GameID gameID; From fcb088d263c4081ebc5a4436cc83cf9e8068a383 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 17 Apr 2023 01:16:23 -0700 Subject: [PATCH 009/116] Further work on leaderboards - Modularize tests - Add migrations - Fix switch case so it actually breaks - Add in missing writes - Beginning work on custom migration to move the leaderboard to the final state --- dDatabase/MigrationRunner.cpp | 30 ++++++- dDatabase/MigrationRunner.h | 1 + dGame/LeaderboardManager.cpp | 78 ++++++++++--------- dGame/LeaderboardManager.h | 2 +- dMasterServer/MasterServer.cpp | 9 +-- .../dlu/10_Update_Leaderboard_Columns.sql | 1 + .../dlu/9_Update_Leaderboard_Storage.sql | 8 ++ tests/dGameTests/LeaderboardTests.cpp | 15 ++-- 8 files changed, 93 insertions(+), 51 deletions(-) create mode 100644 migrations/dlu/10_Update_Leaderboard_Columns.sql create mode 100644 migrations/dlu/9_Update_Leaderboard_Storage.sql diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index 5e70c401..d9c5aa38 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -7,6 +7,8 @@ #include "GeneralUtils.h" #include "dLogger.h" #include "BinaryPathFinder.h" +#include "CDActivitiesTable.h" +#include "CDClientManager.h" #include @@ -56,6 +58,8 @@ void MigrationRunner::RunMigrations() { Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str()); if (migration.name == "dlu/5_brick_model_sd0.sql") { runSd0Migrations = true; + } else if (migration.name == "dlu/10_Update_Leaderboard_Columns.sql") { + continue; } else { finalSQL.append(migration.data.c_str()); } @@ -109,7 +113,7 @@ void MigrationRunner::RunSQLiteMigrations() { // Check if there is an entry in the migration history table on the cdclient database. cdstmt = CDClientDatabase::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;"); - cdstmt.bind((int32_t) 1, migration.name.c_str()); + cdstmt.bind((int32_t)1, migration.name.c_str()); auto cdres = cdstmt.execQuery(); bool doExit = !cdres.eof(); cdres.finalize(); @@ -127,7 +131,7 @@ void MigrationRunner::RunSQLiteMigrations() { if (doExit) { // Insert into cdclient database if there is an entry in the main database but not the cdclient database. cdstmt = CDClientDatabase::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); - cdstmt.bind((int32_t) 1, migration.name.c_str()); + cdstmt.bind((int32_t)1, migration.name.c_str()); cdstmt.execQuery().finalize(); cdstmt.finalize(); continue; @@ -148,7 +152,7 @@ void MigrationRunner::RunSQLiteMigrations() { // Insert into cdclient database. cdstmt = CDClientDatabase::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); - cdstmt.bind((int32_t) 1, migration.name.c_str()); + cdstmt.bind((int32_t)1, migration.name.c_str()); cdstmt.execQuery().finalize(); cdstmt.finalize(); CDClientDatabase::ExecuteQuery("COMMIT;"); @@ -156,3 +160,23 @@ void MigrationRunner::RunSQLiteMigrations() { Game::logger->Log("MigrationRunner", "CDServer database is up to date."); } + +void MigrationRunner::MigrateLeaderboard() { + Game::logger->Log("MigrationRunner", "Checking if leaderboard migration needs to be run..."); + { + std::unique_ptr stmt(Database::CreatePreppedStmt("SELECT * FROM migration_history WHERE name = ?;")); + stmt->setString(1, "dlu/10_Update_Leaderboard_Columns.sql"); + std::unique_ptr res(stmt->executeQuery()); + if (res->next()) { + Game::logger->Log("MigrationRunner", "Leaderboard migration has already been run."); + return; + } + } + auto activitiesTable = CDClientManager::Instance().GetTable(); + auto leaderboards = activitiesTable->Query([=](const CDActivities& entry) { + return entry.leaderboardType != -1; + }); + for (auto entry : leaderboards) { + Game::logger->Log("MigrationRunner", "Got leaderboard type %i for activity %i", entry.leaderboardType, entry.ActivityID); + } +} diff --git a/dDatabase/MigrationRunner.h b/dDatabase/MigrationRunner.h index 0cb36d53..00a1d720 100644 --- a/dDatabase/MigrationRunner.h +++ b/dDatabase/MigrationRunner.h @@ -10,4 +10,5 @@ struct Migration { namespace MigrationRunner { void RunMigrations(); void RunSQLiteMigrations(); + void MigrateLeaderboard(); }; diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d3037fae..cc47c109 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -41,53 +41,59 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { WriteLeaderboardRow(leaderboard, index, "LastPlayed", eLDFType::LDF_TYPE_U64, entry.lastPlayed); WriteLeaderboardRow(leaderboard, index, "NumPlayed", eLDFType::LDF_TYPE_S32, 1); WriteLeaderboardRow(leaderboard, index, "name", eLDFType::LDF_TYPE_UTF_16, entry.playerName); + WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); // Each minigame has its own "points" system switch (leaderboardType) { case Type::ShootingGallery: - WriteLeaderboardRow(leaderboard, index, "HitPercentage", eLDFType::LDF_TYPE_FLOAT, 0.0f); - // HitPercentage:3 between 0 and 1 - WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); - // RowNumber:1 - WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); - // Score:1 + WriteLeaderboardRow(leaderboard, index, "HitPercentage", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // HitPercentage:3 between 0 and 1 + WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); + // Score:1 + WriteLeaderboardRow(leaderboard, index, "Streak", eLDFType::LDF_TYPE_S32, 0); + // Streak:1 + break; case Type::Racing: - WriteLeaderboardRow(leaderboard, index, "BestLapTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); - // BestLapTime:3 - WriteLeaderboardRow(leaderboard, index, "BestTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); - // BestTime:3 - WriteLeaderboardRow(leaderboard, index, "License", eLDFType::LDF_TYPE_S32, 0); - // License:1 - WriteLeaderboardRow(leaderboard, index, "NumWins", eLDFType::LDF_TYPE_S32, 0); - // NumWins:1 - WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_U64, entry.placement); - // RowNumber:8 + WriteLeaderboardRow(leaderboard, index, "BestLapTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // BestLapTime:3 + WriteLeaderboardRow(leaderboard, index, "BestTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // BestTime:3 + WriteLeaderboardRow(leaderboard, index, "License", eLDFType::LDF_TYPE_S32, 0); + // License:1 + WriteLeaderboardRow(leaderboard, index, "NumWins", eLDFType::LDF_TYPE_S32, 0); + // NumWins:1 + break; + case Type::UnusedLeaderboard4: + WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); + // Points:1 + break; case Type::MonumentRace: - WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); - // RowNumber:1 - // Time:1(?) + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1(?) + break; case Type::FootRace: - WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); - // RowNumber:1 - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, 0); - // Time:1 + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1 + break; case Type::Survival: - WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); - // Points:1 - WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); - // RowNumber:1 - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, 0); - // Time:1 + WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); + // Points:1 + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1 + break; case Type::SurvivalNS: - WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_U64, entry.placement); - // RowNumber:8 - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); - // Time:1 - WriteLeaderboardRow(leaderboard, index, "Wave", eLDFType::LDF_TYPE_S32, entry.score); - // Wave:1 + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1 + WriteLeaderboardRow(leaderboard, index, "Wave", eLDFType::LDF_TYPE_S32, entry.score); + // Wave:1 + break; case Type::Donations: - // Something? idk yet. + WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); + // Score:1 + // Something? idk yet. + break; case Type::None: + // This type is included here simply to resolve a compiler warning on mac about unused enum types break; default: break; diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 6432aa8d..4a42a268 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -37,7 +37,7 @@ public: Racing, MonumentRace, FootRace, - // There is no 4 defined anywhere in the client or cdclient + UnusedLeaderboard4,// There is no 4 defined anywhere in the client or cdclient Survival = 5, SurvivalNS, Donations, diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index f10b33bf..61dbb121 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -150,12 +150,6 @@ int main(int argc, char** argv) { const bool oldCDServerExists = std::filesystem::exists(Game::assetManager->GetResPath() / "CDServer.sqlite"); const bool fdbExists = std::filesystem::exists(Game::assetManager->GetResPath() / "cdclient.fdb"); - auto query = Database::CreatePreppedStmt("select name, score, time, UNIX_TIMESTAMP(last_played) as lastPlayed from leaderboard as l join charinfo as ci on ci.id = l.character_id where game_id = 1864 order by score desc, time desc limit 11;"); - auto myResult = query->executeQuery(); - while (myResult->next()) { - Game::logger->Log("MasterServer", "%s %i %i %i", myResult->getString("name").c_str(), myResult->getInt("score"), myResult->getInt("time"), myResult->getInt("lastPlayed")); - } - if (!cdServerExists) { if (oldCDServerExists) { // If the file doesn't exist in the new CDServer location, copy it there. We copy because we may not have write permissions from the previous directory. @@ -208,6 +202,9 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } + // This migration relies on cdclient data so run it last + MigrationRunner::MigrateLeaderboard(); + //If the first command line argument is -a or --account then make the user //input a username and password, with the password being hidden. if (argc > 1 && diff --git a/migrations/dlu/10_Update_Leaderboard_Columns.sql b/migrations/dlu/10_Update_Leaderboard_Columns.sql new file mode 100644 index 00000000..c9afb81e --- /dev/null +++ b/migrations/dlu/10_Update_Leaderboard_Columns.sql @@ -0,0 +1 @@ +# This migration is a mock. See the real migration in MigrationRunner::MigrateLeaderboard. diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql new file mode 100644 index 00000000..1b3b1f13 --- /dev/null +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -0,0 +1,8 @@ +ALTER TABLE leaderboard +ADD COLUMN hitPercentage FLOAT NOT NULL DEFAULT 0, +ADD COLUMN streak INT NOT NULL DEFAULT 0, +ADD COLUMN bestLapTime FLOAT NOT NULL DEFAULT 0, +ADD COLUMN numWins INT NOT NULL DEFAULT 0, +MODIFY time FLOAT NOT NULL DEFAULT 0; + +ALTER TABLE leaderboard CHANGE time bestTime float; diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index 6a45298b..86fb6333 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -32,6 +32,15 @@ protected: bitStream.Reset(); } + void RunTests(Leaderboard::Type type) { + Game::logger->Log("LeaderboardTests", "Testing leaderboard %i for Serialize speed", type); + Leaderboard leaderboard(0, Leaderboard::InfoType::Top, false, type); + TestLeaderboard(leaderboard, 1); + TestLeaderboard(leaderboard, 10); + TestLeaderboard(leaderboard, 100); + TestLeaderboard(leaderboard, 1000); + } + CBITSTREAM; }; @@ -68,9 +77,5 @@ protected: */ TEST_F(LeaderboardTests, LeaderboardSpeedTest) { - Leaderboard leaderboard(10, Leaderboard::InfoType::MyStanding, false, Leaderboard::Type::Survival); - TestLeaderboard(leaderboard, 1); - TestLeaderboard(leaderboard, 10); - TestLeaderboard(leaderboard, 100); - TestLeaderboard(leaderboard, 1000); + RunTests(Leaderboard::Type::Racing); } From 42870028e473a3e46ec30a77ca9c79547fea6e1b Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 17 Apr 2023 15:19:13 -0700 Subject: [PATCH 010/116] Remove complex migration Only shooting gallery had a value put in the wrong column. All others were either already correct or unimplemented. --- dDatabase/MigrationRunner.cpp | 23 +------------------ dDatabase/MigrationRunner.h | 1 - dGame/LeaderboardManager.h | 4 ++-- dMasterServer/MasterServer.cpp | 3 --- .../dlu/10_Update_Leaderboard_Columns.sql | 1 - .../dlu/9_Update_Leaderboard_Storage.sql | 14 ++++++----- 6 files changed, 11 insertions(+), 35 deletions(-) delete mode 100644 migrations/dlu/10_Update_Leaderboard_Columns.sql diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index d9c5aa38..40259a74 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -9,6 +9,7 @@ #include "BinaryPathFinder.h" #include "CDActivitiesTable.h" #include "CDClientManager.h" +#include "LeaderboardManager.h" #include @@ -58,8 +59,6 @@ void MigrationRunner::RunMigrations() { Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str()); if (migration.name == "dlu/5_brick_model_sd0.sql") { runSd0Migrations = true; - } else if (migration.name == "dlu/10_Update_Leaderboard_Columns.sql") { - continue; } else { finalSQL.append(migration.data.c_str()); } @@ -160,23 +159,3 @@ void MigrationRunner::RunSQLiteMigrations() { Game::logger->Log("MigrationRunner", "CDServer database is up to date."); } - -void MigrationRunner::MigrateLeaderboard() { - Game::logger->Log("MigrationRunner", "Checking if leaderboard migration needs to be run..."); - { - std::unique_ptr stmt(Database::CreatePreppedStmt("SELECT * FROM migration_history WHERE name = ?;")); - stmt->setString(1, "dlu/10_Update_Leaderboard_Columns.sql"); - std::unique_ptr res(stmt->executeQuery()); - if (res->next()) { - Game::logger->Log("MigrationRunner", "Leaderboard migration has already been run."); - return; - } - } - auto activitiesTable = CDClientManager::Instance().GetTable(); - auto leaderboards = activitiesTable->Query([=](const CDActivities& entry) { - return entry.leaderboardType != -1; - }); - for (auto entry : leaderboards) { - Game::logger->Log("MigrationRunner", "Got leaderboard type %i for activity %i", entry.leaderboardType, entry.ActivityID); - } -} diff --git a/dDatabase/MigrationRunner.h b/dDatabase/MigrationRunner.h index 00a1d720..0cb36d53 100644 --- a/dDatabase/MigrationRunner.h +++ b/dDatabase/MigrationRunner.h @@ -10,5 +10,4 @@ struct Migration { namespace MigrationRunner { void RunMigrations(); void RunSQLiteMigrations(); - void MigrateLeaderboard(); }; diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 4a42a268..ad05a1ca 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -37,8 +37,8 @@ public: Racing, MonumentRace, FootRace, - UnusedLeaderboard4,// There is no 4 defined anywhere in the client or cdclient - Survival = 5, + UnusedLeaderboard4, // There is no 4 defined anywhere in the cdclient, but it takes a Score. + Survival, SurvivalNS, Donations, None = UINT_MAX diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 61dbb121..cc2bdd90 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -202,9 +202,6 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - // This migration relies on cdclient data so run it last - MigrationRunner::MigrateLeaderboard(); - //If the first command line argument is -a or --account then make the user //input a username and password, with the password being hidden. if (argc > 1 && diff --git a/migrations/dlu/10_Update_Leaderboard_Columns.sql b/migrations/dlu/10_Update_Leaderboard_Columns.sql deleted file mode 100644 index c9afb81e..00000000 --- a/migrations/dlu/10_Update_Leaderboard_Columns.sql +++ /dev/null @@ -1 +0,0 @@ -# This migration is a mock. See the real migration in MigrationRunner::MigrateLeaderboard. diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index 1b3b1f13..5e9c5fa2 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -1,8 +1,10 @@ -ALTER TABLE leaderboard -ADD COLUMN hitPercentage FLOAT NOT NULL DEFAULT 0, -ADD COLUMN streak INT NOT NULL DEFAULT 0, -ADD COLUMN bestLapTime FLOAT NOT NULL DEFAULT 0, -ADD COLUMN numWins INT NOT NULL DEFAULT 0, -MODIFY time FLOAT NOT NULL DEFAULT 0; +ALTER TABLE leaderboard + ADD COLUMN hitPercentage FLOAT NOT NULL DEFAULT 0, + ADD COLUMN streak INT NOT NULL DEFAULT 0, + ADD COLUMN bestLapTime FLOAT NOT NULL DEFAULT 0, + ADD COLUMN numWins INT NOT NULL DEFAULT 0, + MODIFY time FLOAT NOT NULL DEFAULT 0; ALTER TABLE leaderboard CHANGE time bestTime float; + +UPDATE leaderboard SET streak = bestTime where game_id = 1864; From 08220d68525082d0dcfdba19246363b6f9e1a72d Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 17 Apr 2023 15:22:44 -0700 Subject: [PATCH 011/116] Remove extra includes --- dDatabase/MigrationRunner.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index 40259a74..3cc4266e 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -7,9 +7,6 @@ #include "GeneralUtils.h" #include "dLogger.h" #include "BinaryPathFinder.h" -#include "CDActivitiesTable.h" -#include "CDClientManager.h" -#include "LeaderboardManager.h" #include From 89f427ace0d29874c8ca6105684cfc55ba2447e5 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 18 Apr 2023 01:26:35 -0700 Subject: [PATCH 012/116] Further work on leaderboards --- dGame/LeaderboardManager.cpp | 156 ++++++++++++-------------- dGame/LeaderboardManager.h | 13 ++- tests/dGameTests/LeaderboardTests.cpp | 17 ++- 3 files changed, 101 insertions(+), 85 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index cc47c109..7473ebad 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -59,7 +59,7 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { WriteLeaderboardRow(leaderboard, index, "BestTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); // BestTime:3 WriteLeaderboardRow(leaderboard, index, "License", eLDFType::LDF_TYPE_S32, 0); - // License:1 + // License:1 - 1 if player has completed mission 637 and 0 otherwise WriteLeaderboardRow(leaderboard, index, "NumWins", eLDFType::LDF_TYPE_S32, 0); // NumWins:1 break; @@ -118,100 +118,92 @@ void Leaderboard::Send(LWOOBJID targetID) const { } } -void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t score, uint32_t time) { - const auto* player = EntityManager::Instance()->GetEntity(playerID); - if (player == nullptr) - return; +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...) { + va_list args; + va_start(args, argumentCount); + SaveScore(playerID, gameID, leaderboardType, args); + va_end(args); +} - auto* character = player->GetCharacter(); - if (!character) - return; +std::string FormatInsert(const char* columns, const char* format, va_list args) { + auto queryBase = "INSERT INTO leaderboard (%s) VALUES (%s)"; + constexpr uint16_t STRING_LENGTH = 400; + char formattedInsert[STRING_LENGTH]; + char finishedQuery[STRING_LENGTH]; + snprintf(formattedInsert, 400, queryBase, columns, format); + vsnprintf(finishedQuery, 400, formattedInsert, args); + return finishedQuery; +} - std::unique_ptr select(Database::CreatePreppedStmt("SELECT time, score FROM leaderboard WHERE character_id = ? AND game_id = ?;")); +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args){ + std::string insertStatement; + // use replace into to update the score if it already exists instead of needing an update and an insert + switch (leaderboardType) { + case Leaderboard::Type::ShootingGallery: { + // Check that the score exists and is better. If the score is better update it. + // If the score is the same but the streak is better, update it. + // If the score is the same and the streak is the same but the hit percentage is better, update it. + // If the score doesn't exist, insert it. + auto lookup = Database::CreatePreppedStmt("SELECT score, streak, hitPercentage FROM leaderboard WHERE playerID = ? AND gameID = ?"); + lookup->setInt64(1, playerID); + lookup->setInt(2, gameID); + auto lookupResult = lookup->executeQuery(); + if (lookupResult->next()) { - select->setUInt64(1, character->GetID()); - select->setInt(2, gameID); - - auto any = false; - auto* result = select->executeQuery(); - auto leaderboardType = GetLeaderboardType(gameID); - - // Check if the new score is a high score - while (result->next()) { - any = true; - - const auto storedTime = result->getInt(1); - const auto storedScore = result->getInt(2); - auto highscore = true; - bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1"; - - switch (leaderboardType) { - case Leaderboard::Type::ShootingGallery: - if (score <= storedScore) - highscore = false; - break; - case Leaderboard::Type::Racing: - if (time >= storedTime) - highscore = false; - break; - case Leaderboard::Type::MonumentRace: - if (time >= storedTime) - highscore = false; - break; - case Leaderboard::Type::FootRace: - if (time <= storedTime) - highscore = false; - break; - case Leaderboard::Type::Survival: - if (classicSurvivalScoring) { - if (time <= storedTime) { // Based on time (LU live) - highscore = false; - } } else { - if (score <= storedScore) // Based on score (DLU) - highscore = false; + auto result = FormatInsert("hitPercentage, score, streak", "%f, %i, %i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); } break; - case Leaderboard::Type::SurvivalNS: - if (!(score > storedScore || (time < storedTime && score >= storedScore))) - highscore = false; - break; - default: - highscore = false; } - - if (!highscore) { - delete result; + case Leaderboard::Type::Racing: { + auto result = FormatInsert("bestLapTime, bestTime", "%f, %f", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::UnusedLeaderboard4: { + auto result = FormatInsert("points", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::MonumentRace: { + auto result = FormatInsert("time", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::FootRace: { + auto result = FormatInsert("time", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::Survival: { + auto result = FormatInsert("points, time", "%i, %i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::SurvivalNS: { + auto result = FormatInsert("time, wave", "%i, %i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::Donations: { + auto result = FormatInsert("score", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::None: { + Game::logger->Log("LeaderboardManager", "Warning: Saving leaderboard of type None. Are you sure this is intended?"); + break; + } + default: { + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); return; } } - delete result; - - if (any) { - auto* statement = Database::CreatePreppedStmt("UPDATE leaderboard SET time = ?, score = ?, last_played=SYSDATE() WHERE character_id = ? AND game_id = ?;"); - statement->setInt(1, time); - statement->setInt(2, score); - statement->setUInt64(3, character->GetID()); - statement->setInt(4, gameID); - statement->execute(); - - delete statement; - } else { - // Note: last_played will be set to SYSDATE() by default when inserting into leaderboard - auto* statement = Database::CreatePreppedStmt("INSERT INTO leaderboard (character_id, game_id, time, score) VALUES (?, ?, ?, ?);"); - statement->setUInt64(1, character->GetID()); - statement->setInt(2, gameID); - statement->setInt(3, time); - statement->setInt(4, score); - statement->execute(); - - delete statement; - } } -void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, - LWOOBJID playerID) { +void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { // Create the leaderboard here and then send it right after. On the stack. Leaderboard leaderboard(gameID, infoType, weekly, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index ad05a1ca..abe679e9 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -93,10 +93,19 @@ class LeaderboardManager: public Singleton { public: void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID = LWOOBJID_EMPTY); - void SaveScore(LWOOBJID playerID, GameID gameID, uint32_t score, uint32_t time); + /** + * @brief Public facing Score saving method. This method is simply a wrapper to ensure va_end is called properly. + * + * @param playerID The player whos score to save + * @param gameID The ID of the game which was played + * @param argumentCount The number of arguments in the va_list + * @param ... + */ + void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...); private: - Leaderboard::Type GetLeaderboardType(const GameID gameID); + void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args); void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); + Leaderboard::Type GetLeaderboardType(const GameID gameID); LeaderboardCache leaderboardCache; }; diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index 86fb6333..e3fa4264 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -77,5 +77,20 @@ protected: */ TEST_F(LeaderboardTests, LeaderboardSpeedTest) { - RunTests(Leaderboard::Type::Racing); + // RunTests(Leaderboard::Type::ShootingGallery); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::ShootingGallery, 3, 3000, 15.0f, 100); + // RunTests(Leaderboard::Type::Racing); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Racing, 2, 260.0f, 250.0f); + // RunTests(Leaderboard::Type::MonumentRace); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::MonumentRace, 1, 150); + // RunTests(Leaderboard::Type::FootRace); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::FootRace, 1, 150); + // RunTests(Leaderboard::Type::UnusedLeaderboard4); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 100); + // RunTests(Leaderboard::Type::Survival); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Survival, 2, 3000, 15); + // RunTests(Leaderboard::Type::SurvivalNS); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::SurvivalNS, 2, 300, 15); + // RunTests(Leaderboard::Type::Donations); + LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Donations, 1, 300000); } From 10a2c24d5e0249669d7532781e2d7bda4593d5d0 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 26 Apr 2023 02:10:57 -0700 Subject: [PATCH 013/116] Add base MyStandings query --- dGame/LeaderboardManager.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 7473ebad..e6aef981 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -15,6 +15,37 @@ #include "CDActivitiesTable.h" #include "Metrics.hpp" + +// DON'T YOU DARE MERGE THIS WITH A GLOBAL I WANT TO TEST FAST + +// The below query creates 2 derived tables +// The first is just a straight ranking of the leaderboard based on a provided ranking parameter. +// The second is a query that finds the ranking of the requested score +// The third and final query takes the score gotten above and gets the rankings as follows:. +// If the requested score is in the top 5, it will return the top 11 scores. +// If the requested score is in the bottom 5, it will return the bottom 11 scores. +// In all other cases, the second query will return the 5 scores above and below the requested score. +std::string myStandingsQueryBase = +"WITH leaderboardsRanked AS (" +" SELECT *," +" RANK() OVER" +" (" +" ORDER BY score desc, streak, hitPercentage DESC" +" ) AS ranking" +" FROM leaderboard WHERE game_id = ?" +")," +"myStanding AS (" +" SELECT ranking as myRank" +" FROM leaderboardsRanked" +" WHERE id = ? LIMIT 1" +")" +"SELECT * FROM leaderboardsRanked, myStanding, (SELECT MAX(leaderboardsRanked.ranking) AS lowestRank FROM leaderboardsRanked) AS lowestRanking" +"WHERE leaderboardsRanked.ranking BETWEEN" +"LEAST(GREATEST(myRank - 5, 1), lowestRanking.lowestRank - 10)" +"AND" +"LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank)" +"ORDER BY ranking ASC;"; + Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type leaderboardType) { this->gameID = gameID; this->weekly = weekly; From 48264e2cf46b15b4bf5852f81d14ac63ff1ede49 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 30 Apr 2023 21:30:41 -0700 Subject: [PATCH 014/116] push --- dGame/LeaderboardManager.cpp | 336 +++++++++++++++----------- dGame/LeaderboardManager.h | 20 +- tests/dGameTests/LeaderboardTests.cpp | 41 ++-- 3 files changed, 221 insertions(+), 176 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index e6aef981..8c32d383 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -16,36 +16,6 @@ #include "CDActivitiesTable.h" #include "Metrics.hpp" -// DON'T YOU DARE MERGE THIS WITH A GLOBAL I WANT TO TEST FAST - -// The below query creates 2 derived tables -// The first is just a straight ranking of the leaderboard based on a provided ranking parameter. -// The second is a query that finds the ranking of the requested score -// The third and final query takes the score gotten above and gets the rankings as follows:. -// If the requested score is in the top 5, it will return the top 11 scores. -// If the requested score is in the bottom 5, it will return the bottom 11 scores. -// In all other cases, the second query will return the 5 scores above and below the requested score. -std::string myStandingsQueryBase = -"WITH leaderboardsRanked AS (" -" SELECT *," -" RANK() OVER" -" (" -" ORDER BY score desc, streak, hitPercentage DESC" -" ) AS ranking" -" FROM leaderboard WHERE game_id = ?" -")," -"myStanding AS (" -" SELECT ranking as myRank" -" FROM leaderboardsRanked" -" WHERE id = ? LIMIT 1" -")" -"SELECT * FROM leaderboardsRanked, myStanding, (SELECT MAX(leaderboardsRanked.ranking) AS lowestRank FROM leaderboardsRanked) AS lowestRanking" -"WHERE leaderboardsRanked.ranking BETWEEN" -"LEAST(GREATEST(myRank - 5, 1), lowestRanking.lowestRank - 10)" -"AND" -"LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank)" -"ORDER BY ranking ASC;"; - Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type leaderboardType) { this->gameID = gameID; this->weekly = weekly; @@ -68,66 +38,60 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { auto index = 0; for (const auto& entry : entries) { - WriteLeaderboardRow(leaderboard, index, "CharacterID", eLDFType::LDF_TYPE_U64, entry.playerID); - WriteLeaderboardRow(leaderboard, index, "LastPlayed", eLDFType::LDF_TYPE_U64, entry.lastPlayed); - WriteLeaderboardRow(leaderboard, index, "NumPlayed", eLDFType::LDF_TYPE_S32, 1); - WriteLeaderboardRow(leaderboard, index, "name", eLDFType::LDF_TYPE_UTF_16, entry.playerName); - WriteLeaderboardRow(leaderboard, index, "RowNumber", eLDFType::LDF_TYPE_S32, entry.placement); - // Each minigame has its own "points" system switch (leaderboardType) { - case Type::ShootingGallery: - WriteLeaderboardRow(leaderboard, index, "HitPercentage", eLDFType::LDF_TYPE_FLOAT, 0.0f); - // HitPercentage:3 between 0 and 1 - WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); - // Score:1 - WriteLeaderboardRow(leaderboard, index, "Streak", eLDFType::LDF_TYPE_S32, 0); - // Streak:1 - break; - case Type::Racing: - WriteLeaderboardRow(leaderboard, index, "BestLapTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); - // BestLapTime:3 - WriteLeaderboardRow(leaderboard, index, "BestTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); - // BestTime:3 - WriteLeaderboardRow(leaderboard, index, "License", eLDFType::LDF_TYPE_S32, 0); - // License:1 - 1 if player has completed mission 637 and 0 otherwise - WriteLeaderboardRow(leaderboard, index, "NumWins", eLDFType::LDF_TYPE_S32, 0); - // NumWins:1 - break; - case Type::UnusedLeaderboard4: - WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); - // Points:1 - break; - case Type::MonumentRace: - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); - // Time:1(?) - break; - case Type::FootRace: - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); - // Time:1 - break; - case Type::Survival: - WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); - // Points:1 - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); - // Time:1 - break; - case Type::SurvivalNS: - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); - // Time:1 - WriteLeaderboardRow(leaderboard, index, "Wave", eLDFType::LDF_TYPE_S32, entry.score); - // Wave:1 - break; - case Type::Donations: - WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); - // Score:1 - // Something? idk yet. - break; - case Type::None: - // This type is included here simply to resolve a compiler warning on mac about unused enum types - break; - default: - break; + case Type::ShootingGallery: + WriteLeaderboardRow(leaderboard, index, "HitPercentage", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // HitPercentage:3 between 0 and 1 + WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); + // Score:1 + WriteLeaderboardRow(leaderboard, index, "Streak", eLDFType::LDF_TYPE_S32, 0); + // Streak:1 + break; + case Type::Racing: + WriteLeaderboardRow(leaderboard, index, "BestLapTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // BestLapTime:3 + WriteLeaderboardRow(leaderboard, index, "BestTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + // BestTime:3 + WriteLeaderboardRow(leaderboard, index, "License", eLDFType::LDF_TYPE_S32, 0); + // License:1 - 1 if player has completed mission 637 and 0 otherwise + WriteLeaderboardRow(leaderboard, index, "NumWins", eLDFType::LDF_TYPE_S32, 0); + // NumWins:1 + break; + case Type::UnusedLeaderboard4: + WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); + // Points:1 + break; + case Type::MonumentRace: + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1(?) + break; + case Type::FootRace: + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1 + break; + case Type::Survival: + WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); + // Points:1 + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1 + break; + case Type::SurvivalNS: + WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + // Time:1 + WriteLeaderboardRow(leaderboard, index, "Wave", eLDFType::LDF_TYPE_S32, entry.score); + // Wave:1 + break; + case Type::Donations: + WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); + // Score:1 + // Something? idk yet. + break; + case Type::None: + // This type is included here simply to resolve a compiler warning on mac about unused enum types + break; + default: + break; } index++; } @@ -137,9 +101,89 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { } void Leaderboard::SetupLeaderboard() { + std::string queryBase = + "SELECT %s, character_id, UNIX_TIMESTAMP(last_played), charinfo.name as lastPlayed" + "FROM leaderboard JOIN charinfo" + "ON charinfo.id = leaderboard.character_id" + "WHERE game_id = ?" + "ORDER BY %s"; // Setup query based on activity. // Where clause will vary based on what query we are doing + // Get base based on InfoType + // Fill in base with arguments based on leaderboard type + char queryBuffer[1024]; + switch (leaderboardType) { + case Type::ShootingGallery: + snprintf(queryBuffer, 1024, queryBase.c_str(), "hitPercentage, score, streak", "score DESC, streak DESC, hitPercentage DESC"); + break; + case Type::Racing: + snprintf(queryBuffer, 1024, queryBase.c_str(), "bestLapTime, bestTime, numWins", "bestTime ASC, bestLapTime ASC, numWins DESC"); + break; + case Type::UnusedLeaderboard4: + snprintf(queryBuffer, 1024, queryBase.c_str(), "points", "points DESC"); + break; + case Type::MonumentRace: + snprintf(queryBuffer, 1024, queryBase.c_str(), "time", "time ASC"); + break; + case Type::FootRace: + snprintf(queryBuffer, 1024, queryBase.c_str(), "time", "time DESC"); + break; + case Type::Survival: + snprintf(queryBuffer, 1024, queryBase.c_str(), "points, time", "points DESC, time DESC"); + // If the config option default_survival_scoring is 1, reverse the order of the points and time columns + break; + case Type::SurvivalNS: + snprintf(queryBuffer, 1024, queryBase.c_str(), "time, wave", "time DESC, wave DESC"); + break; + case Type::Donations: + snprintf(queryBuffer, 1024, queryBase.c_str(), "score", "score DESC"); + break; + case Type::None: + Game::logger->Log("LeaderboardManager", "Attempting to get leaderboard for type none. Is this intended?"); + // This type is included here simply to resolve a compiler warning on mac about unused enum types + break; + } + Game::logger->Log("LeaderboardManager", "filled in query is %s", queryBuffer); + // create and execute query here + std::unique_ptr query(Database::CreatePreppedStmt(queryBuffer)); + query->setInt(1, this->gameID); + std::unique_ptr result(query->executeQuery()); + if (result->rowsCount() == 0) return; + + uint32_t myRanking = 1; + uint32_t myCharacterId = 0; + // Find my ranking in the leaderboard + while (result->next()) { + if (result->getInt("character_id") != myCharacterId) myRanking++; + else break; + } + // Once you've found my ranking, figure out if we need to adjust the + // row pointer to get the top 11 or the bottom 11. + + int32_t lowestRanking = result->rowsCount() - 5; + if (lowestRanking > 0 && myRanking >= lowestRanking) { // I am in the bottom 10, so set row pointer back to the top of the bottom 6 + for (uint32_t i = myRanking - lowestRanking; i > lowestRanking; i--) { + result->previous(); + } + } + + uint32_t startRanking = 1; // Default to top 11 + if (myRanking >= 6) startRanking = myRanking - 5; // If i am not in the top 5, set row pointer to 5 above my ranking + else if (myRanking > result->rowsCount()) { // If i am in the bottom 10, set the row pointer to the top of the bottom 11 + startRanking = result->rowsCount() - 10; + } + + for (uint32_t i = myRanking - 5; i > 0; i--) { // Adjust first row gotten to be 5 above my ranking. + result->previous(); + } + for (uint32_t i = 11; i > 0; i--) { + this->entries.push_back(LDFData(u"CharacterID", result->getInt("character_id"))); + this->entries.push_back(LDFData(u"LastPlayed", result->getUInt64("lastPlayed"))); + this->entries.push_back(LDFData(u"NumPlayed", 1)); + this->entries.push_back(LDFData(u"name", GeneralUtils::ASCIIToUTF16(result->getString("name").c_str()))); + this->entries.push_back(LDFData(u"RowNumber", startRanking + i)); + } } void Leaderboard::Send(LWOOBJID targetID) const { @@ -166,70 +210,70 @@ std::string FormatInsert(const char* columns, const char* format, va_list args) return finishedQuery; } -void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args){ +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args) { std::string insertStatement; // use replace into to update the score if it already exists instead of needing an update and an insert switch (leaderboardType) { - case Leaderboard::Type::ShootingGallery: { - // Check that the score exists and is better. If the score is better update it. - // If the score is the same but the streak is better, update it. - // If the score is the same and the streak is the same but the hit percentage is better, update it. - // If the score doesn't exist, insert it. - auto lookup = Database::CreatePreppedStmt("SELECT score, streak, hitPercentage FROM leaderboard WHERE playerID = ? AND gameID = ?"); - lookup->setInt64(1, playerID); - lookup->setInt(2, gameID); - auto lookupResult = lookup->executeQuery(); - if (lookupResult->next()) { + case Leaderboard::Type::ShootingGallery: { + // Check that the score exists and is better. If the score is better update it. + // If the score is the same but the streak is better, update it. + // If the score is the same and the streak is the same but the hit percentage is better, update it. + // If the score doesn't exist, insert it. + auto lookup = Database::CreatePreppedStmt("SELECT score, streak, hitPercentage FROM leaderboard WHERE playerID = ? AND gameID = ?"); + lookup->setInt64(1, playerID); + lookup->setInt(2, gameID); + auto lookupResult = lookup->executeQuery(); + if (lookupResult->next()) { - } else { - auto result = FormatInsert("hitPercentage, score, streak", "%f, %i, %i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - } - break; - } - case Leaderboard::Type::Racing: { - auto result = FormatInsert("bestLapTime, bestTime", "%f, %f", args); + } else { + auto result = FormatInsert("hitPercentage, score, streak", "%f, %i, %i", args); Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::UnusedLeaderboard4: { - auto result = FormatInsert("points", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::MonumentRace: { - auto result = FormatInsert("time", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::FootRace: { - auto result = FormatInsert("time", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::Survival: { - auto result = FormatInsert("points, time", "%i, %i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::SurvivalNS: { - auto result = FormatInsert("time, wave", "%i, %i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::Donations: { - auto result = FormatInsert("score", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::None: { - Game::logger->Log("LeaderboardManager", "Warning: Saving leaderboard of type None. Are you sure this is intended?"); - break; - } - default: { - Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); - return; } + break; + } + case Leaderboard::Type::Racing: { + auto result = FormatInsert("bestLapTime, bestTime", "%f, %f", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::UnusedLeaderboard4: { + auto result = FormatInsert("points", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::MonumentRace: { + auto result = FormatInsert("time", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::FootRace: { + auto result = FormatInsert("time", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::Survival: { + auto result = FormatInsert("points, time", "%i, %i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::SurvivalNS: { + auto result = FormatInsert("time, wave", "%i, %i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::Donations: { + auto result = FormatInsert("score", "%i", args); + Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + break; + } + case Leaderboard::Type::None: { + Game::logger->Log("LeaderboardManager", "Warning: Saving leaderboard of type None. Are you sure this is intended?"); + break; + } + default: { + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); + return; + } } } diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index abe679e9..1a44fde4 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -15,15 +15,15 @@ typedef uint32_t GameID; class Leaderboard { public: - struct Entry { - LWOOBJID playerID; - uint32_t time; - uint32_t score; - uint32_t placement; - time_t lastPlayed; - std::string playerName; - }; - typedef std::vector LeaderboardEntries; + // struct Entry { + // LWOOBJID playerID; + // uint32_t time; + // uint32_t score; + // uint32_t placement; + // time_t lastPlayed; + // std::string playerName; + // }; + typedef std::vector LeaderboardEntries; // Enums for leaderboards enum InfoType : uint32_t { @@ -76,7 +76,7 @@ public: * Adds a new entry to the leaderboard * Used for debug only! */ - void AddEntry(Entry entry) { entries.push_back(entry); } + void AddEntry(LDFBaseData& entry) { entries.push_back(entry); } private: template inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, const std::string& key, const eLDFType& ldfType, const TypeToWrite& value) const; diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index e3fa4264..8594b186 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -35,10 +35,11 @@ protected: void RunTests(Leaderboard::Type type) { Game::logger->Log("LeaderboardTests", "Testing leaderboard %i for Serialize speed", type); Leaderboard leaderboard(0, Leaderboard::InfoType::Top, false, type); - TestLeaderboard(leaderboard, 1); - TestLeaderboard(leaderboard, 10); - TestLeaderboard(leaderboard, 100); - TestLeaderboard(leaderboard, 1000); + leaderboard.SetupLeaderboard(); + // TestLeaderboard(leaderboard, 1); + // TestLeaderboard(leaderboard, 10); + // TestLeaderboard(leaderboard, 100); + // TestLeaderboard(leaderboard, 1000); } CBITSTREAM; @@ -77,20 +78,20 @@ protected: */ TEST_F(LeaderboardTests, LeaderboardSpeedTest) { - // RunTests(Leaderboard::Type::ShootingGallery); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::ShootingGallery, 3, 3000, 15.0f, 100); - // RunTests(Leaderboard::Type::Racing); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Racing, 2, 260.0f, 250.0f); - // RunTests(Leaderboard::Type::MonumentRace); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::MonumentRace, 1, 150); - // RunTests(Leaderboard::Type::FootRace); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::FootRace, 1, 150); - // RunTests(Leaderboard::Type::UnusedLeaderboard4); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 100); - // RunTests(Leaderboard::Type::Survival); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Survival, 2, 3000, 15); - // RunTests(Leaderboard::Type::SurvivalNS); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::SurvivalNS, 2, 300, 15); - // RunTests(Leaderboard::Type::Donations); - LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Donations, 1, 300000); + RunTests(Leaderboard::Type::ShootingGallery); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::ShootingGallery, 3, 3000, 15.0f, 100); + RunTests(Leaderboard::Type::Racing); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Racing, 2, 260.0f, 250.0f); + RunTests(Leaderboard::Type::MonumentRace); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::MonumentRace, 1, 150); + RunTests(Leaderboard::Type::FootRace); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::FootRace, 1, 150); + RunTests(Leaderboard::Type::UnusedLeaderboard4); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 100); + RunTests(Leaderboard::Type::Survival); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Survival, 2, 3000, 15); + RunTests(Leaderboard::Type::SurvivalNS); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::SurvivalNS, 2, 300, 15); + RunTests(Leaderboard::Type::Donations); + // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Donations, 1, 300000); } From a3626a3b53dcfefc184954e57c7f9ef35c96db50 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 3 May 2023 00:38:38 -0700 Subject: [PATCH 015/116] The query is supposed to get SMALLER Still better than 9 different queries all with 1 minor change i guess. --- dGame/LeaderboardManager.cpp | 328 +++++++++++++++++--------- dGame/LeaderboardManager.h | 26 +- tests/dGameTests/GameDependencies.h | 2 + tests/dGameTests/LeaderboardTests.cpp | 42 ++-- 4 files changed, 242 insertions(+), 156 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 8c32d383..940e4932 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -16,19 +16,23 @@ #include "CDActivitiesTable.h" #include "Metrics.hpp" -Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type leaderboardType) { +Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type leaderboardType) { this->gameID = gameID; this->weekly = weekly; this->infoType = infoType; this->leaderboardType = leaderboardType; + this->relatedPlayer = relatedPlayer; } -template -void Leaderboard::WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, const std::string& key, const eLDFType& ldfType, const TypeToWrite& value) const { - leaderboard << "Result[0].Row[" << index << "]." << key << '=' << ldfType << ':' << value << '\n'; +Leaderboard::~Leaderboard() { + for (auto& entry : entries) for (auto data : entry) delete data; } -void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { +void Leaderboard::WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { + leaderboard << "Result[0].Row[" << index << "]." << data->GetString() << '\n'; +} + +void Leaderboard::Serialize(RakNet::BitStream* bitStream) { std::ostringstream leaderboard; leaderboard << "ADO.Result=7:1\n"; // Unused in 1.10.64, but is in captures @@ -36,54 +40,235 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { leaderboard << "Result[0].Index=0:RowNumber\n"; // "Primary key" leaderboard << "Result[0].RowCount=1:" << entries.size() << '\n'; // number of rows - auto index = 0; - for (const auto& entry : entries) { - // Each minigame has its own "points" system + int32_t index = 0; + for (auto& entry : entries) { + for (auto data : entry) { + WriteLeaderboardRow(leaderboard, index, data); + } + index++; + } + + // Serialize the thing to a BitStream + bitStream->Write(leaderboard.str().c_str(), leaderboard.tellp()); +} + +#define MAX_QUERY_LENGTH 1526 + +void Leaderboard::SetupLeaderboard() { + bool isTopQuery = this->infoType == InfoType::Top; + bool isMyStandingQuery = this->infoType == InfoType::MyStanding; + bool isFriendsQuery = this->infoType == InfoType::Friends; + std::string baseLookupStr; + + if (!isTopQuery) { + baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ? LIMIT 1"; + } else { + baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY %s LIMIT 1"; + } + + std::string queryBase = + " \ + WITH leaderboardsRanked AS ( \ + SELECT leaderboard.*, charinfo.name, \ + RANK() OVER \ + ( \ + ORDER BY %s \ + ) AS ranking \ + FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id \ + WHERE game_id = ? %s \ + ), \ + myStanding AS ( \ + SELECT \ + ranking as myRank \ + FROM leaderboardsRanked \ + WHERE id = ? \ + ), \ + lowestRanking AS ( \ + SELECT MAX(ranking) AS lowestRank \ + FROM leaderboardsRanked \ + ) \ + SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name FROM leaderboardsRanked, myStanding, lowestRanking \ + WHERE leaderboardsRanked.ranking \ + BETWEEN \ + LEAST(GREATEST(myRank - 5, 1), lowestRanking.lowestRank - 10) \ + AND \ + LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank) \ + ORDER BY ranking ASC;"; + // Setup query based on activity. + // Where clause will vary based on what query we are doing + // Get base based on InfoType + // Fill in base with arguments based on leaderboard type + // If this is a friends query we need to join another table and add even more to the where clause. + + const char* friendsQuery = + " AND (character_id IN (SELECT fr.requested_player FROM (SELECT CASE " + "WHEN player_id = ? THEN friend_id " + "WHEN friend_id = ? THEN player_id " + "END AS requested_player FROM friends) AS fr " + "JOIN charinfo AS ci ON ci.id = fr.requested_player " + "WHERE fr.requested_player IS NOT NULL) OR character_id = ?) "; + + char baseStandingBuffer[1024]; + char lookupBuffer[MAX_QUERY_LENGTH]; + + switch (leaderboardType) { + case Type::ShootingGallery: { + const char* orderBase = "score DESC, streak DESC, hitPercentage DESC"; + const char* selectBase = "hitPercentage, score, streak"; + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase, selectBase); + if (isFriendsQuery) snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase, friendsQuery, selectBase); + else snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase, "", selectBase); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), orderBase); + break; + } + case Type::Racing: + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime ASC, bestLapTime ASC, numWins DESC", "bestLapTime, bestTime, numWins"); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime ASC, bestLapTime ASC, numWins DESC"); + break; + case Type::UnusedLeaderboard4: + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "score DESC", "score"); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "score DESC"); + break; + case Type::MonumentRace: + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime ASC", "bestTime"); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime ASC"); + break; + case Type::FootRace: + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime DESC", "bestTime"); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime DESC"); + break; + case Type::Survival: + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "score DESC, bestTime DESC", "score, bestTime"); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "score DESC, bestTime DESC"); + // If the config option default_survival_scoring is 1, reverse the order of the points and time columns + break; + case Type::SurvivalNS: + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime DESC, score DESC", "bestTime, score"); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime DESC, score DESC"); + break; + case Type::Donations: + snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "score DESC", "score"); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "score DESC"); + break; + case Type::None: + Game::logger->Log("LeaderboardManager", "Attempting to get leaderboard for type none. Is this intended?"); + // This type is included here simply to resolve a compiler warning on mac about unused enum types + break; + } + Game::logger->Log("LeaderboardManager", "lookup query is %s", (!isTopQuery) ? baseLookupStr.c_str() : baseStandingBuffer); + std::unique_ptr baseQuery(Database::CreatePreppedStmt((!isTopQuery) ? baseLookupStr : baseStandingBuffer)); + baseQuery->setInt(1, this->gameID); + if (!isTopQuery) { + baseQuery->setInt(2, this->relatedPlayer); + } + + std::unique_ptr baseResult(baseQuery->executeQuery()); + if (baseResult->rowsCount() == 0) return; + baseResult->next(); + // Get the ID of the row fetched. + uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); + + // create and execute query here + Game::logger->Log("LeaderboardManager", "filled in query is %s %i %i %i", lookupBuffer, this->gameID, this->relatedPlayer, relatedPlayerLeaderboardId); + std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); + query->setInt(1, this->gameID); + if (isFriendsQuery) { + query->setInt(2, this->relatedPlayer); + query->setInt(3, this->relatedPlayer); + query->setInt(4, this->relatedPlayer); + query->setInt(5, relatedPlayerLeaderboardId); + } else { + query->setInt(2, relatedPlayerLeaderboardId); + } + std::unique_ptr result(query->executeQuery()); + + if (result->rowsCount() == 0) return; + + uint32_t myRanking = 1; + uint32_t myCharacterId = 0; + int32_t lowestRanking = result->rowsCount() - 5; + uint32_t startRanking = 1; // Default to top 11 + if (this->infoType == InfoType::MyStanding) { + // Find my ranking in the leaderboard + while (result->next()) { + if (result->getInt("character_id") != myCharacterId) myRanking++; + else break; + } + // Once you've found my ranking, figure out if we need to adjust the + // row pointer to get the top 11 or the bottom 11. + + if (lowestRanking > 0 && myRanking >= lowestRanking) { // I am in the bottom 10, so set row pointer back to the top of the bottom 6 + for (uint32_t i = myRanking - lowestRanking; i > lowestRanking; i--) { + result->previous(); + } + } + + if (myRanking >= 6) startRanking = myRanking - 5; // If i am not in the top 5, set row pointer to 5 above my ranking + else if (myRanking > result->rowsCount()) { // If i am in the bottom 10, set the row pointer to the top of the bottom 11 + startRanking = result->rowsCount() - 10; + } + + for (uint32_t i = myRanking - 5; i > 0; i--) { // Adjust first row gotten to be 5 above my ranking. + result->previous(); + } + } + + this->entries.reserve(11); + for (uint32_t i = 0; i < 11 && result->next(); i++) { + constexpr int32_t MAX_NUM_DATA_PER_ROW = 9; + this->entries.push_back(std::vector()); + auto& entry = this->entries.back(); + entry.reserve(MAX_NUM_DATA_PER_ROW); + entry.push_back(new LDFData(u"CharacterID", result->getInt("character_id"))); + entry.push_back(new LDFData(u"LastPlayed", result->getUInt64("lastPlayed"))); + entry.push_back(new LDFData(u"NumPlayed", 1)); + entry.push_back(new LDFData(u"name", GeneralUtils::ASCIIToUTF16(result->getString("name").c_str()))); + entry.push_back(new LDFData(u"RowNumber", startRanking + i)); switch (leaderboardType) { case Type::ShootingGallery: - WriteLeaderboardRow(leaderboard, index, "HitPercentage", eLDFType::LDF_TYPE_FLOAT, 0.0f); + entry.push_back(new LDFData(u"HitPercentage", result->getDouble("hitPercentage"))); // HitPercentage:3 between 0 and 1 - WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); + entry.push_back(new LDFData(u"Score", result->getInt("score"))); // Score:1 - WriteLeaderboardRow(leaderboard, index, "Streak", eLDFType::LDF_TYPE_S32, 0); + entry.push_back(new LDFData(u"Streak", result->getInt("streak"))); // Streak:1 break; case Type::Racing: - WriteLeaderboardRow(leaderboard, index, "BestLapTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + entry.push_back(new LDFData(u"BestLapTime", result->getDouble("bestLapTime"))); // BestLapTime:3 - WriteLeaderboardRow(leaderboard, index, "BestTime", eLDFType::LDF_TYPE_FLOAT, 0.0f); + entry.push_back(new LDFData(u"BestTime", result->getDouble("bestTime"))); // BestTime:3 - WriteLeaderboardRow(leaderboard, index, "License", eLDFType::LDF_TYPE_S32, 0); + entry.push_back(new LDFData(u"License", 1)); // License:1 - 1 if player has completed mission 637 and 0 otherwise - WriteLeaderboardRow(leaderboard, index, "NumWins", eLDFType::LDF_TYPE_S32, 0); + entry.push_back(new LDFData(u"NumWins", result->getInt("numWins"))); // NumWins:1 break; case Type::UnusedLeaderboard4: - WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); + entry.push_back(new LDFData(u"Score", result->getInt("score"))); // Points:1 break; case Type::MonumentRace: - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); // Time:1(?) break; case Type::FootRace: - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); // Time:1 break; case Type::Survival: - WriteLeaderboardRow(leaderboard, index, "Points", eLDFType::LDF_TYPE_S32, entry.score); + entry.push_back(new LDFData(u"Score", result->getInt("score"))); // Points:1 - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); // Time:1 break; case Type::SurvivalNS: - WriteLeaderboardRow(leaderboard, index, "Time", eLDFType::LDF_TYPE_S32, entry.time); + entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); // Time:1 - WriteLeaderboardRow(leaderboard, index, "Wave", eLDFType::LDF_TYPE_S32, entry.score); + entry.push_back(new LDFData(u"Score", result->getInt("score"))); // Wave:1 break; case Type::Donations: - WriteLeaderboardRow(leaderboard, index, "Score", eLDFType::LDF_TYPE_S32, entry.score); + entry.push_back(new LDFData(u"Score", result->getInt("score"))); // Score:1 // Something? idk yet. break; @@ -93,97 +278,12 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { default: break; } - index++; } - - // Serialize the thing to a BitStream - bitStream->Write(leaderboard.str().c_str(), leaderboard.tellp()); -} - -void Leaderboard::SetupLeaderboard() { - std::string queryBase = - "SELECT %s, character_id, UNIX_TIMESTAMP(last_played), charinfo.name as lastPlayed" - "FROM leaderboard JOIN charinfo" - "ON charinfo.id = leaderboard.character_id" - "WHERE game_id = ?" - "ORDER BY %s"; - // Setup query based on activity. - // Where clause will vary based on what query we are doing - // Get base based on InfoType - // Fill in base with arguments based on leaderboard type - char queryBuffer[1024]; - switch (leaderboardType) { - case Type::ShootingGallery: - snprintf(queryBuffer, 1024, queryBase.c_str(), "hitPercentage, score, streak", "score DESC, streak DESC, hitPercentage DESC"); - break; - case Type::Racing: - snprintf(queryBuffer, 1024, queryBase.c_str(), "bestLapTime, bestTime, numWins", "bestTime ASC, bestLapTime ASC, numWins DESC"); - break; - case Type::UnusedLeaderboard4: - snprintf(queryBuffer, 1024, queryBase.c_str(), "points", "points DESC"); - break; - case Type::MonumentRace: - snprintf(queryBuffer, 1024, queryBase.c_str(), "time", "time ASC"); - break; - case Type::FootRace: - snprintf(queryBuffer, 1024, queryBase.c_str(), "time", "time DESC"); - break; - case Type::Survival: - snprintf(queryBuffer, 1024, queryBase.c_str(), "points, time", "points DESC, time DESC"); - // If the config option default_survival_scoring is 1, reverse the order of the points and time columns - break; - case Type::SurvivalNS: - snprintf(queryBuffer, 1024, queryBase.c_str(), "time, wave", "time DESC, wave DESC"); - break; - case Type::Donations: - snprintf(queryBuffer, 1024, queryBase.c_str(), "score", "score DESC"); - break; - case Type::None: - Game::logger->Log("LeaderboardManager", "Attempting to get leaderboard for type none. Is this intended?"); - // This type is included here simply to resolve a compiler warning on mac about unused enum types - break; - } - Game::logger->Log("LeaderboardManager", "filled in query is %s", queryBuffer); - // create and execute query here - std::unique_ptr query(Database::CreatePreppedStmt(queryBuffer)); - query->setInt(1, this->gameID); - std::unique_ptr result(query->executeQuery()); - if (result->rowsCount() == 0) return; - - uint32_t myRanking = 1; - uint32_t myCharacterId = 0; - // Find my ranking in the leaderboard - while (result->next()) { - if (result->getInt("character_id") != myCharacterId) myRanking++; - else break; - } - // Once you've found my ranking, figure out if we need to adjust the - // row pointer to get the top 11 or the bottom 11. - - int32_t lowestRanking = result->rowsCount() - 5; - if (lowestRanking > 0 && myRanking >= lowestRanking) { // I am in the bottom 10, so set row pointer back to the top of the bottom 6 - for (uint32_t i = myRanking - lowestRanking; i > lowestRanking; i--) { - result->previous(); + for (auto& entry : entries) { + for (auto data : entry) { + Game::logger->Log("LeaderboardManager", "entry is %s", data->GetString().c_str()); } } - - uint32_t startRanking = 1; // Default to top 11 - if (myRanking >= 6) startRanking = myRanking - 5; // If i am not in the top 5, set row pointer to 5 above my ranking - else if (myRanking > result->rowsCount()) { // If i am in the bottom 10, set the row pointer to the top of the bottom 11 - startRanking = result->rowsCount() - 10; - } - - for (uint32_t i = myRanking - 5; i > 0; i--) { // Adjust first row gotten to be 5 above my ranking. - result->previous(); - } - - for (uint32_t i = 11; i > 0; i--) { - this->entries.push_back(LDFData(u"CharacterID", result->getInt("character_id"))); - this->entries.push_back(LDFData(u"LastPlayed", result->getUInt64("lastPlayed"))); - this->entries.push_back(LDFData(u"NumPlayed", 1)); - this->entries.push_back(LDFData(u"name", GeneralUtils::ASCIIToUTF16(result->getString("name").c_str()))); - this->entries.push_back(LDFData(u"RowNumber", startRanking + i)); - } } void Leaderboard::Send(LWOOBJID targetID) const { @@ -271,7 +371,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead break; } default: { - Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); return; } } @@ -279,8 +379,8 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead } void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { - // Create the leaderboard here and then send it right after. On the stack. - Leaderboard leaderboard(gameID, infoType, weekly, GetLeaderboardType(gameID)); + // Create the leaderboard here and then send it right after. On the stack. + Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(); leaderboard.Send(targetID); } diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 1a44fde4..b0d6bf26 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -15,15 +15,8 @@ typedef uint32_t GameID; class Leaderboard { public: - // struct Entry { - // LWOOBJID playerID; - // uint32_t time; - // uint32_t score; - // uint32_t placement; - // time_t lastPlayed; - // std::string playerName; - // }; - typedef std::vector LeaderboardEntries; + using LeaderboardEntry = std::vector; + using LeaderboardEntries = std::vector; // Enums for leaderboards enum InfoType : uint32_t { @@ -44,14 +37,16 @@ public: None = UINT_MAX }; - Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const Leaderboard::Type = None); + Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None); + + ~Leaderboard(); /** * Serialize the Leaderboard to a BitStream * * Expensive! Leaderboards are very string intensive so be wary of performatnce calling this method. */ - void Serialize(RakNet::BitStream* bitStream) const; + void Serialize(RakNet::BitStream* bitStream); /** * Based on the associated gameID, return true if the score provided @@ -71,15 +66,8 @@ public: * Sends the leaderboard to the client specified by targetID. */ void Send(LWOOBJID targetID) const; - - /** - * Adds a new entry to the leaderboard - * Used for debug only! - */ - void AddEntry(LDFBaseData& entry) { entries.push_back(entry); } private: -template - inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, const std::string& key, const eLDFType& ldfType, const TypeToWrite& value) const; + inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data); LeaderboardEntries entries; LWOOBJID relatedPlayer; GameID gameID; diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 353b53b8..c0fb8bce 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -6,6 +6,7 @@ #include "dServer.h" #include "EntityInfo.h" #include "EntityManager.h" +#include "Database.h" #include "dConfig.h" #include @@ -32,6 +33,7 @@ protected: Game::logger = new dLogger("./testing.log", true, true); Game::server = new dServerMock(); Game::config = new dConfig("worldconfig.ini"); + Database::Connect(Game::config->GetValue("mysql_host"), Game::config->GetValue("mysql_database"), Game::config->GetValue("mysql_username"), Game::config->GetValue("mysql_password")); } void TearDownDependencies() { diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index 8594b186..7cec021b 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -15,14 +15,7 @@ protected: } void TestLeaderboard(Leaderboard& leaderboard, int32_t entries) { - Leaderboard::Entry entry; - entry.playerID = UINT64_MAX; - entry.time = 100; - entry.score = 100; - entry.placement = 1; - entry.lastPlayed = 0; - entry.playerName = "TestThreeWords"; - for (int32_t i = 0; i < entries; i++) leaderboard.AddEntry(entry); + bitStream.Reset(); Metrics::StartMeasurement(MetricVariable::Leaderboard); for (int32_t i = 0; i < MAX_MEASURMENT_POINTS; i++) leaderboard.Serialize(&bitStream); Metrics::EndMeasurement(MetricVariable::Leaderboard); @@ -32,14 +25,15 @@ protected: bitStream.Reset(); } - void RunTests(Leaderboard::Type type) { - Game::logger->Log("LeaderboardTests", "Testing leaderboard %i for Serialize speed", type); - Leaderboard leaderboard(0, Leaderboard::InfoType::Top, false, type); + void RunTests(uint32_t gameID, Leaderboard::Type type, Leaderboard::InfoType infoType) { + Game::logger->Log("LeaderboardTests", "Testing leaderboard %i for Serialize speed", infoType); + Leaderboard leaderboard(gameID, infoType, false, 14231, type); leaderboard.SetupLeaderboard(); - // TestLeaderboard(leaderboard, 1); - // TestLeaderboard(leaderboard, 10); - // TestLeaderboard(leaderboard, 100); - // TestLeaderboard(leaderboard, 1000); + leaderboard.Serialize(&bitStream); + TestLeaderboard(leaderboard, 1); + TestLeaderboard(leaderboard, 10); + TestLeaderboard(leaderboard, 100); + TestLeaderboard(leaderboard, 1000); } CBITSTREAM; @@ -78,20 +72,22 @@ protected: */ TEST_F(LeaderboardTests, LeaderboardSpeedTest) { - RunTests(Leaderboard::Type::ShootingGallery); + RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); + RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); + RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::ShootingGallery, 3, 3000, 15.0f, 100); - RunTests(Leaderboard::Type::Racing); + // RunTests(0, Leaderboard::Type::Racing); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Racing, 2, 260.0f, 250.0f); - RunTests(Leaderboard::Type::MonumentRace); + // RunTests(0, Leaderboard::Type::MonumentRace); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::MonumentRace, 1, 150); - RunTests(Leaderboard::Type::FootRace); + // RunTests(0, Leaderboard::Type::FootRace); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::FootRace, 1, 150); - RunTests(Leaderboard::Type::UnusedLeaderboard4); + // RunTests(0, Leaderboard::Type::UnusedLeaderboard4); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 100); - RunTests(Leaderboard::Type::Survival); + // RunTests(0, Leaderboard::Type::Survival); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Survival, 2, 3000, 15); - RunTests(Leaderboard::Type::SurvivalNS); + // RunTests(0, Leaderboard::Type::SurvivalNS); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::SurvivalNS, 2, 300, 15); - RunTests(Leaderboard::Type::Donations); + // RunTests(0, Leaderboard::Type::Donations); // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Donations, 1, 300000); } From 8de528e77caa49ffe72ab4479c6e0ae67b5acb51 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 4 May 2023 13:58:48 -0700 Subject: [PATCH 016/116] Remove old code --- dGame/LeaderboardManager.cpp | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 940e4932..7f294285 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -184,37 +184,8 @@ void Leaderboard::SetupLeaderboard() { if (result->rowsCount() == 0) return; - uint32_t myRanking = 1; - uint32_t myCharacterId = 0; - int32_t lowestRanking = result->rowsCount() - 5; - uint32_t startRanking = 1; // Default to top 11 - if (this->infoType == InfoType::MyStanding) { - // Find my ranking in the leaderboard - while (result->next()) { - if (result->getInt("character_id") != myCharacterId) myRanking++; - else break; - } - // Once you've found my ranking, figure out if we need to adjust the - // row pointer to get the top 11 or the bottom 11. - - if (lowestRanking > 0 && myRanking >= lowestRanking) { // I am in the bottom 10, so set row pointer back to the top of the bottom 6 - for (uint32_t i = myRanking - lowestRanking; i > lowestRanking; i--) { - result->previous(); - } - } - - if (myRanking >= 6) startRanking = myRanking - 5; // If i am not in the top 5, set row pointer to 5 above my ranking - else if (myRanking > result->rowsCount()) { // If i am in the bottom 10, set the row pointer to the top of the bottom 11 - startRanking = result->rowsCount() - 10; - } - - for (uint32_t i = myRanking - 5; i > 0; i--) { // Adjust first row gotten to be 5 above my ranking. - result->previous(); - } - } - this->entries.reserve(11); - for (uint32_t i = 0; i < 11 && result->next(); i++) { + while (result->next()) { constexpr int32_t MAX_NUM_DATA_PER_ROW = 9; this->entries.push_back(std::vector()); auto& entry = this->entries.back(); @@ -223,7 +194,7 @@ void Leaderboard::SetupLeaderboard() { entry.push_back(new LDFData(u"LastPlayed", result->getUInt64("lastPlayed"))); entry.push_back(new LDFData(u"NumPlayed", 1)); entry.push_back(new LDFData(u"name", GeneralUtils::ASCIIToUTF16(result->getString("name").c_str()))); - entry.push_back(new LDFData(u"RowNumber", startRanking + i)); + entry.push_back(new LDFData(u"RowNumber", result->getInt("ranking"))); switch (leaderboardType) { case Type::ShootingGallery: entry.push_back(new LDFData(u"HitPercentage", result->getDouble("hitPercentage"))); From 2ab995b9c3287d88fd52bf9d479c6f8d81913712 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 4 May 2023 14:28:53 -0700 Subject: [PATCH 017/116] Simplify snprintfs so much better to read --- dGame/LeaderboardManager.cpp | 43 +++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 7f294285..88276978 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -111,50 +111,53 @@ void Leaderboard::SetupLeaderboard() { char baseStandingBuffer[1024]; char lookupBuffer[MAX_QUERY_LENGTH]; + std::string orderBase; + std::string selectBase; + switch (leaderboardType) { case Type::ShootingGallery: { - const char* orderBase = "score DESC, streak DESC, hitPercentage DESC"; - const char* selectBase = "hitPercentage, score, streak"; - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase, selectBase); - if (isFriendsQuery) snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase, friendsQuery, selectBase); - else snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase, "", selectBase); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), orderBase); + orderBase = "score DESC, streak DESC, hitPercentage DESC"; + selectBase = "hitPercentage, score, streak"; break; } case Type::Racing: - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime ASC, bestLapTime ASC, numWins DESC", "bestLapTime, bestTime, numWins"); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime ASC, bestLapTime ASC, numWins DESC"); + orderBase = "bestTime ASC, bestLapTime ASC, numWins DESC"; + selectBase = "bestLapTime, bestTime, numWins"; break; case Type::UnusedLeaderboard4: - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "score DESC", "score"); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "score DESC"); + orderBase = "score DESC"; + selectBase = "score"; break; case Type::MonumentRace: - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime ASC", "bestTime"); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime ASC"); + orderBase = "bestTime ASC"; + selectBase = "bestTime"; break; case Type::FootRace: - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime DESC", "bestTime"); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime DESC"); + orderBase = "bestTime DESC"; + selectBase = "bestTime"; break; case Type::Survival: - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "score DESC, bestTime DESC", "score, bestTime"); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "score DESC, bestTime DESC"); + orderBase = "score DESC, bestTime DESC"; + selectBase = "score, bestTime"; // If the config option default_survival_scoring is 1, reverse the order of the points and time columns break; case Type::SurvivalNS: - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "bestTime DESC, score DESC", "bestTime, score"); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "bestTime DESC, score DESC"); + orderBase = "bestTime DESC, score DESC"; + selectBase = "bestTime, score"; break; case Type::Donations: - snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), "score DESC", "score"); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), "score DESC"); + orderBase = "score DESC"; + selectBase = "score"; break; case Type::None: Game::logger->Log("LeaderboardManager", "Attempting to get leaderboard for type none. Is this intended?"); // This type is included here simply to resolve a compiler warning on mac about unused enum types break; } + if (isFriendsQuery) snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase.c_str(), friendsQuery, selectBase.c_str()); + else snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase.c_str(), "", selectBase.c_str()); + if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), orderBase.c_str()); + Game::logger->Log("LeaderboardManager", "lookup query is %s", (!isTopQuery) ? baseLookupStr.c_str() : baseStandingBuffer); std::unique_ptr baseQuery(Database::CreatePreppedStmt((!isTopQuery) ? baseLookupStr : baseStandingBuffer)); baseQuery->setInt(1, this->gameID); From 28a0492201bdd313cb8138dcbeed43e4fc8af717 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 4 May 2023 14:48:26 -0700 Subject: [PATCH 018/116] Fix bugs --- dGame/LeaderboardManager.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 88276978..09f65475 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -87,10 +87,10 @@ void Leaderboard::SetupLeaderboard() { SELECT MAX(ranking) AS lowestRank \ FROM leaderboardsRanked \ ) \ - SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name FROM leaderboardsRanked, myStanding, lowestRanking \ + SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking \ WHERE leaderboardsRanked.ranking \ BETWEEN \ - LEAST(GREATEST(myRank - 5, 1), lowestRanking.lowestRank - 10) \ + LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, 1), lowestRanking.lowestRank - 10) \ AND \ LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank) \ ORDER BY ranking ASC;"; @@ -108,12 +108,8 @@ void Leaderboard::SetupLeaderboard() { "JOIN charinfo AS ci ON ci.id = fr.requested_player " "WHERE fr.requested_player IS NOT NULL) OR character_id = ?) "; - char baseStandingBuffer[1024]; - char lookupBuffer[MAX_QUERY_LENGTH]; - std::string orderBase; std::string selectBase; - switch (leaderboardType) { case Type::ShootingGallery: { orderBase = "score DESC, streak DESC, hitPercentage DESC"; @@ -154,6 +150,9 @@ void Leaderboard::SetupLeaderboard() { // This type is included here simply to resolve a compiler warning on mac about unused enum types break; } + + char baseStandingBuffer[1024]; + char lookupBuffer[MAX_QUERY_LENGTH]; if (isFriendsQuery) snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase.c_str(), friendsQuery, selectBase.c_str()); else snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase.c_str(), "", selectBase.c_str()); if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), orderBase.c_str()); From 0faef7d7918f452a0deb0a8b93f9eff8e02e5034 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 4 May 2023 16:53:36 -0700 Subject: [PATCH 019/116] Finished saving --- dGame/LeaderboardManager.cpp | 71 +++++++++++++++++------------------- dGame/LeaderboardManager.h | 3 ++ 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 09f65475..a814d953 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -52,20 +52,17 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) { bitStream->Write(leaderboard.str().c_str(), leaderboard.tellp()); } -#define MAX_QUERY_LENGTH 1526 +bool Leaderboard::GetRankingQuery(std::string& lookupReturn) const { + if (this->infoType == InfoType::Top) { + lookupReturn = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY %s LIMIT 1"; + return true; + } else { + lookupReturn = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ? LIMIT 1"; + return false; + } +} void Leaderboard::SetupLeaderboard() { - bool isTopQuery = this->infoType == InfoType::Top; - bool isMyStandingQuery = this->infoType == InfoType::MyStanding; - bool isFriendsQuery = this->infoType == InfoType::Friends; - std::string baseLookupStr; - - if (!isTopQuery) { - baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ? LIMIT 1"; - } else { - baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY %s LIMIT 1"; - } - std::string queryBase = " \ WITH leaderboardsRanked AS ( \ @@ -151,22 +148,26 @@ void Leaderboard::SetupLeaderboard() { break; } - char baseStandingBuffer[1024]; - char lookupBuffer[MAX_QUERY_LENGTH]; - if (isFriendsQuery) snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase.c_str(), friendsQuery, selectBase.c_str()); - else snprintf(lookupBuffer, MAX_QUERY_LENGTH, queryBase.c_str(), orderBase.c_str(), "", selectBase.c_str()); - if (isTopQuery) snprintf(baseStandingBuffer, 1024, baseLookupStr.c_str(), orderBase.c_str()); + constexpr uint16_t STRING_LENGTH = 1526; + char lookupBuffer[STRING_LENGTH]; + if (this->infoType == InfoType::Friends) snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), friendsQuery, selectBase.c_str()); + else snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), "", selectBase.c_str()); - Game::logger->Log("LeaderboardManager", "lookup query is %s", (!isTopQuery) ? baseLookupStr.c_str() : baseStandingBuffer); - std::unique_ptr baseQuery(Database::CreatePreppedStmt((!isTopQuery) ? baseLookupStr : baseStandingBuffer)); + std::string baseLookupStr; + char baseRankingBuffer[STRING_LENGTH]; + bool neededFormatting = GetRankingQuery(baseLookupStr); + if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.c_str()); + else std::copy(baseLookupStr.begin(), baseLookupStr.end() + 1, baseRankingBuffer); + + Game::logger->Log("LeaderboardManager", "lookup query is %s", baseRankingBuffer); + std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseRankingBuffer)); baseQuery->setInt(1, this->gameID); - if (!isTopQuery) { + if (!neededFormatting) { baseQuery->setInt(2, this->relatedPlayer); } std::unique_ptr baseResult(baseQuery->executeQuery()); - if (baseResult->rowsCount() == 0) return; - baseResult->next(); + if (!baseResult->next()) return; // Get the ID of the row fetched. uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); @@ -174,7 +175,7 @@ void Leaderboard::SetupLeaderboard() { Game::logger->Log("LeaderboardManager", "filled in query is %s %i %i %i", lookupBuffer, this->gameID, this->relatedPlayer, relatedPlayerLeaderboardId); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); query->setInt(1, this->gameID); - if (isFriendsQuery) { + if (this->infoType == InfoType::Friends) { query->setInt(2, this->relatedPlayer); query->setInt(3, this->relatedPlayer); query->setInt(4, this->relatedPlayer); @@ -186,7 +187,7 @@ void Leaderboard::SetupLeaderboard() { if (result->rowsCount() == 0) return; - this->entries.reserve(11); + this->entries.reserve(result->rowsCount()); while (result->next()) { constexpr int32_t MAX_NUM_DATA_PER_ROW = 9; this->entries.push_back(std::vector()); @@ -235,15 +236,14 @@ void Leaderboard::SetupLeaderboard() { // Time:1 break; case Type::SurvivalNS: - entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); - // Time:1 entry.push_back(new LDFData(u"Score", result->getInt("score"))); // Wave:1 + entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); + // Time:1 break; case Type::Donations: entry.push_back(new LDFData(u"Score", result->getInt("score"))); // Score:1 - // Something? idk yet. break; case Type::None: // This type is included here simply to resolve a compiler warning on mac about unused enum types @@ -278,23 +278,21 @@ std::string FormatInsert(const char* columns, const char* format, va_list args) constexpr uint16_t STRING_LENGTH = 400; char formattedInsert[STRING_LENGTH]; char finishedQuery[STRING_LENGTH]; - snprintf(formattedInsert, 400, queryBase, columns, format); - vsnprintf(finishedQuery, 400, formattedInsert, args); + snprintf(formattedInsert, STRING_LENGTH, queryBase, columns, format); + vsnprintf(finishedQuery, STRING_LENGTH, formattedInsert, args); return finishedQuery; } void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args) { std::string insertStatement; // use replace into to update the score if it already exists instead of needing an update and an insert + std::unique_ptr lookup(Database::CreatePreppedStmt("SELECT * FROM leaderboard WHERE playerID = ? AND gameID = ?")); + lookup->setInt64(1, playerID); + lookup->setInt(2, gameID); + std::unique_ptr lookupResult(lookup->executeQuery()); + switch (leaderboardType) { case Leaderboard::Type::ShootingGallery: { - // Check that the score exists and is better. If the score is better update it. - // If the score is the same but the streak is better, update it. - // If the score is the same and the streak is the same but the hit percentage is better, update it. - // If the score doesn't exist, insert it. - auto lookup = Database::CreatePreppedStmt("SELECT score, streak, hitPercentage FROM leaderboard WHERE playerID = ? AND gameID = ?"); - lookup->setInt64(1, playerID); - lookup->setInt(2, gameID); auto lookupResult = lookup->executeQuery(); if (lookupResult->next()) { @@ -352,7 +350,6 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead } void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { - // Create the leaderboard here and then send it right after. On the stack. Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(); leaderboard.Send(targetID); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index b0d6bf26..898dfbbb 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -68,6 +68,9 @@ public: void Send(LWOOBJID targetID) const; private: inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data); + + // Returns true if the string needs formatting + bool GetRankingQuery(std::string& lookupReturn) const; LeaderboardEntries entries; LWOOBJID relatedPlayer; GameID gameID; From 3b8f18d2be9acb1e54b1f7ef8d20caafd1b3c3d4 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 5 May 2023 21:33:30 -0700 Subject: [PATCH 020/116] Fix new lines --- dGame/LeaderboardManager.cpp | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index a814d953..9dc32061 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -64,33 +64,33 @@ bool Leaderboard::GetRankingQuery(std::string& lookupReturn) const { void Leaderboard::SetupLeaderboard() { std::string queryBase = - " \ - WITH leaderboardsRanked AS ( \ - SELECT leaderboard.*, charinfo.name, \ - RANK() OVER \ - ( \ - ORDER BY %s \ - ) AS ranking \ - FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id \ - WHERE game_id = ? %s \ - ), \ - myStanding AS ( \ - SELECT \ - ranking as myRank \ - FROM leaderboardsRanked \ - WHERE id = ? \ - ), \ - lowestRanking AS ( \ - SELECT MAX(ranking) AS lowestRank \ - FROM leaderboardsRanked \ - ) \ - SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking \ - WHERE leaderboardsRanked.ranking \ - BETWEEN \ - LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, 1), lowestRanking.lowestRank - 10) \ - AND \ - LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank) \ - ORDER BY ranking ASC;"; + R"QUERY( + WITH leaderboardsRanked AS ( + SELECT leaderboard.*, charinfo.name, + RANK() OVER + ( + ORDER BY %s + ) AS ranking + FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id + WHERE game_id = ? %s + ), + myStanding AS ( + SELECT + ranking as myRank + FROM leaderboardsRanked + WHERE id = ? + ), + lowestRanking AS ( + SELECT MAX(ranking) AS lowestRank + FROM leaderboardsRanked + ) + SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking + WHERE leaderboardsRanked.ranking + BETWEEN + LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, 1), lowestRanking.lowestRank - 10) + AND + LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank) + ORDER BY ranking ASC;)QUERY"; // Setup query based on activity. // Where clause will vary based on what query we are doing // Get base based on InfoType From df3265c82e7ea712a892e5e7974e79044c6981ef Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 5 May 2023 23:31:30 -0700 Subject: [PATCH 021/116] Add more null checks and split out code Makes crash logs more apparent for what stage they crashed in for the engine updating. --- dGame/EntityManager.cpp | 69 +++++++++++-------- dGame/EntityManager.h | 4 ++ .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 45 ++++++------ 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 1a77d365..0fc859bd 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -161,9 +161,7 @@ void EntityManager::DestroyEntity(const LWOOBJID& objectID) { } void EntityManager::DestroyEntity(Entity* entity) { - if (entity == nullptr) { - return; - } + if (!entity) return; entity->TriggerEvent(eTriggerEventType::DESTROY, entity); @@ -182,15 +180,11 @@ void EntityManager::DestroyEntity(Entity* entity) { ScheduleForDeletion(id); } -void EntityManager::UpdateEntities(const float deltaTime) { - for (const auto& e : m_Entities) { - e.second->Update(deltaTime); - } - +void EntityManager::SerializeEntities() { for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) { auto* entity = GetEntity(*entry); - if (entity == nullptr) continue; + if (!entity) continue; m_SerializationCounter++; @@ -212,11 +206,16 @@ void EntityManager::UpdateEntities(const float deltaTime) { } } m_EntitiesToSerialize.clear(); +} +void EntityManager::KillEntities() { for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) { auto* entity = GetEntity(*entry); - if (!entity) continue; + if (!entity) { + Game::logger->Log("EntityManager", "Attempting to kill null entity %llu", *entry); + continue; + } if (entity->GetScheduledKiller()) { entity->Smash(entity->GetScheduledKiller()->GetObjectID(), eKillType::SILENT); @@ -225,32 +224,41 @@ void EntityManager::UpdateEntities(const float deltaTime) { } } m_EntitiesToKill.clear(); +} +void EntityManager::DeleteEntities() { for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) { - - // Get all this info first before we delete the player. auto entityToDelete = GetEntity(*entry); - auto networkIdToErase = entityToDelete->GetNetworkId(); - const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); - if (entityToDelete) { - // If we are a player run through the player destructor. - if (entityToDelete->IsPlayer()) { - delete dynamic_cast(entityToDelete); - } else { - delete entityToDelete; - } + // Get all this info first before we delete the player. + auto networkIdToErase = entityToDelete->GetNetworkId(); + const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); + + delete entityToDelete; + entityToDelete = nullptr; + if (networkIdToErase != 0) m_LostNetworkIds.push(networkIdToErase); + + if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete); + } else { + Game::logger->Log("EntityManager", "Attempted to delete non-existent entity %llu", *entry); } - - if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete); - m_Entities.erase(*entry); } m_EntitiesToDelete.clear(); } +void EntityManager::UpdateEntities(const float deltaTime) { + for (const auto& e : m_Entities) { + e.second->Update(deltaTime); + } + + SerializeEntities(); + KillEntities(); + DeleteEntities(); +} + Entity* EntityManager::GetEntity(const LWOOBJID& objectId) const { const auto& index = m_Entities.find(objectId); @@ -316,6 +324,11 @@ const std::unordered_map& EntityManager::GetSpawnPointEnt } void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr, const bool skipChecks) { + if (!entity) { + Game::logger->Log("EntityManager", "Attempted to construct null entity"); + return; + } + if (entity->GetNetworkId() == 0) { uint16_t networkId; @@ -395,9 +408,7 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) { } void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) { - if (entity->GetNetworkId() == 0) { - return; - } + if (!entity || entity->GetNetworkId() == 0) return; RakNet::BitStream stream; @@ -414,9 +425,7 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) } void EntityManager::SerializeEntity(Entity* entity) { - if (entity->GetNetworkId() == 0) { - return; - } + if (!entity || entity->GetNetworkId() == 0) return; if (std::find(m_EntitiesToSerialize.begin(), m_EntitiesToSerialize.end(), entity->GetObjectID()) == m_EntitiesToSerialize.end()) { m_EntitiesToSerialize.push_back(entity->GetObjectID()); diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 0314cc09..b524344c 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -85,6 +85,10 @@ public: const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; }; private: + void SerializeEntities(); + void KillEntities(); + void DeleteEntities(); + static EntityManager* m_Address; //For singleton method static std::vector m_GhostingExcludedZones; static std::vector m_GhostingExcludedLOTs; diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index bdd7a506..50cd229a 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -275,6 +275,11 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { toSpawn.spawnPaths.at(pathIndex) ); + if (!path) { + Game::logger->Log("SGCannon", "Path %s at index %i is null", toSpawn.spawnPaths.at(pathIndex).c_str(), pathIndex); + return; + } + auto info = EntityInfo{}; info.lot = toSpawn.lot; info.spawnerID = self->GetObjectID(); @@ -294,32 +299,30 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { auto* enemy = EntityManager::Instance()->CreateEntity(info, nullptr, self); EntityManager::Instance()->ConstructEntity(enemy); - if (true) { - auto* movementAI = new MovementAIComponent(enemy, {}); + auto* movementAI = new MovementAIComponent(enemy, {}); - enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); + enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); - movementAI->SetSpeed(toSpawn.initialSpeed); - movementAI->SetCurrentSpeed(toSpawn.initialSpeed); - movementAI->SetHaltDistance(0.0f); + movementAI->SetSpeed(toSpawn.initialSpeed); + movementAI->SetCurrentSpeed(toSpawn.initialSpeed); + movementAI->SetHaltDistance(0.0f); - std::vector pathWaypoints; + std::vector pathWaypoints; - for (const auto& waypoint : path->pathWaypoints) { - pathWaypoints.push_back(waypoint.position); - } - - if (GeneralUtils::GenerateRandomNumber(0, 1) < 0.5f) { - std::reverse(pathWaypoints.begin(), pathWaypoints.end()); - } - - movementAI->SetPath(pathWaypoints); - - enemy->AddDieCallback([this, self, enemy, name]() { - RegisterHit(self, enemy, name); - }); + for (const auto& waypoint : path->pathWaypoints) { + pathWaypoints.push_back(waypoint.position); } + if (GeneralUtils::GenerateRandomNumber(0, 1) < 0.5f) { + std::reverse(pathWaypoints.begin(), pathWaypoints.end()); + } + + movementAI->SetPath(pathWaypoints); + + enemy->AddDieCallback([this, self, enemy, name]() { + RegisterHit(self, enemy, name); + }); + // Save the enemy and tell it to start pathing if (enemy != nullptr) { const_cast&>(self->GetVar>(SpawnedObjects)).push_back(enemy->GetObjectID()); @@ -577,7 +580,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { self->SetNetworkVar(u"UI_Rewards", GeneralUtils::to_u16string(self->GetVar(TotalScoreVariable)) + u"_0_0_0_0_0_0" - ); + ); GameMessages::SendRequestActivitySummaryLeaderboardData( player->GetObjectID(), From 5479cf44287a0f8c542252a5ee7f7a54045473ea Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 6 May 2023 13:32:26 -0500 Subject: [PATCH 022/116] Fix typing of some player flag variables (#1067) Mainly on properties Tested that the spider queen mission can now be progressed --- dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp | 4 ++-- dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp | 4 ++-- dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp | 4 ++-- dScripts/BasePropertyServer.cpp | 4 ++-- dScripts/ai/PROPERTY/AgPropguards.cpp | 2 +- dScripts/ai/PROPERTY/AgPropguards.h | 2 +- dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp | 4 ++-- dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp | 4 ++-- dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp index 5996548f..2711b179 100644 --- a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp +++ b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp @@ -9,8 +9,8 @@ void ZoneAgSpiderQueen::SetGameVariables(Entity* self) { ZoneAgProperty::SetGameVariables(self); // Disable property flags - self->SetVar(defeatedProperyFlag, 0); - self->SetVar(placedModelFlag, 0); + self->SetVar(defeatedProperyFlag, 0); + self->SetVar(placedModelFlag, 0); self->SetVar(guardFirstMissionFlag, 0); self->SetVar(guardMissionFlag, 0); self->SetVar(brickLinkMissionIDFlag, 0); diff --git a/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp b/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp index db1c4c4b..46ec7bbd 100644 --- a/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp @@ -31,8 +31,8 @@ void ZoneAgMedProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "BirdFX", "SunBeam" }); self->SetVar>(BehaviorObjsSpawner, {}); - self->SetVar(defeatedProperyFlag, 118); - self->SetVar(placedModelFlag, 119); + self->SetVar(defeatedProperyFlag, 118); + self->SetVar(placedModelFlag, 119); self->SetVar(guardMissionFlag, 1293); self->SetVar(brickLinkMissionIDFlag, 1294); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp index 635eb8b3..6bf91768 100644 --- a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp @@ -39,8 +39,8 @@ void ZoneAgProperty::SetGameVariables(Entity* self) { self->SetVar(LauncherSpawner, "Launcher"); self->SetVar(InstancerSpawner, "Instancer"); - self->SetVar(defeatedProperyFlag, 71); - self->SetVar(placedModelFlag, 73); + self->SetVar(defeatedProperyFlag, 71); + self->SetVar(placedModelFlag, 73); self->SetVar(guardFirstMissionFlag, 891); self->SetVar(guardMissionFlag, 320); self->SetVar(brickLinkMissionIDFlag, 951); diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index 1522ef26..72cce09f 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -38,8 +38,8 @@ void BasePropertyServer::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, {}); self->SetVar>(BehaviorObjsSpawner, {}); - self->SetVar(defeatedProperyFlag, 0); - self->SetVar(placedModelFlag, 0); + self->SetVar(defeatedProperyFlag, 0); + self->SetVar(placedModelFlag, 0); self->SetVar(guardMissionFlag, 0); self->SetVar(brickLinkMissionIDFlag, 0); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dScripts/ai/PROPERTY/AgPropguards.cpp b/dScripts/ai/PROPERTY/AgPropguards.cpp index 9fc6010a..7e8e2fd1 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.cpp +++ b/dScripts/ai/PROPERTY/AgPropguards.cpp @@ -39,7 +39,7 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission } } -uint32_t AgPropguards::GetFlagForMission(uint32_t missionID) { +int32_t AgPropguards::GetFlagForMission(uint32_t missionID) { switch (missionID) { case 872: return 97; diff --git a/dScripts/ai/PROPERTY/AgPropguards.h b/dScripts/ai/PROPERTY/AgPropguards.h index 25701f86..ed2e3cb0 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.h +++ b/dScripts/ai/PROPERTY/AgPropguards.h @@ -4,5 +4,5 @@ class AgPropguards : public CppScripts::Script { void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; private: - static uint32_t GetFlagForMission(uint32_t missionID); + static int32_t GetFlagForMission(uint32_t missionID); }; diff --git a/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp b/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp index 67ada039..8b8072ad 100644 --- a/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp +++ b/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp @@ -29,8 +29,8 @@ void ZoneFvProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "Ash", "FX", "Fog" }); self->SetVar>(BehaviorObjsSpawner, {}); - self->SetVar(defeatedProperyFlag, 99); - self->SetVar(placedModelFlag, 107); + self->SetVar(defeatedProperyFlag, 99); + self->SetVar(placedModelFlag, 107); self->SetVar(guardMissionFlag, 874); self->SetVar(brickLinkMissionIDFlag, 950); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp b/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp index 565d8cd6..87b2345d 100644 --- a/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp +++ b/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp @@ -29,8 +29,8 @@ void ZoneGfProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "Birds", "Falls", "Sunbeam" }); self->SetVar>(BehaviorObjsSpawner, { "TrappedPlatform", "IceBarrier", "FireBeast" }); - self->SetVar(defeatedProperyFlag, 98); - self->SetVar(placedModelFlag, 106); + self->SetVar(defeatedProperyFlag, 98); + self->SetVar(placedModelFlag, 106); self->SetVar(guardMissionFlag, 873); self->SetVar(brickLinkMissionIDFlag, 949); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp b/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp index 49364ee8..52bb02e2 100644 --- a/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp +++ b/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp @@ -30,8 +30,8 @@ void ZoneNsProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "Rockets" }); self->SetVar>(BehaviorObjsSpawner, { "Cage", "Platform", "Door" }); - self->SetVar(defeatedProperyFlag, 97); - self->SetVar(placedModelFlag, 105); + self->SetVar(defeatedProperyFlag, 97); + self->SetVar(placedModelFlag, 105); self->SetVar(guardMissionFlag, 872); self->SetVar(brickLinkMissionIDFlag, 948); self->SetVar(passwordFlag, "s3kratK1ttN"); From cffb1449d86193e408ca0565eccab780907db915 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 6 May 2023 11:32:38 -0700 Subject: [PATCH 023/116] Add better logs to saving (#1068) * Fix overread in projectile behavior * Fix stuns * Correctly read in bitStream * Fix projectile behavior * Address movement type issues * Update shutdown time to be accurate * Fix small issues * Fix missing template * Add note for compile jobs * Add bounds check for speed division * Add better logs --- dGame/Character.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dGame/Character.cpp b/dGame/Character.cpp index e565ed4f..319b9376 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -373,7 +373,7 @@ void Character::SaveXMLToDatabase() { //Call upon the entity to update our xmlDoc: if (!m_OurEntity) { - Game::logger->Log("Character", "We didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!"); + Game::logger->Log("Character", "%i:%s didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!", this->GetID(), this->GetName().c_str()); return; } @@ -384,7 +384,7 @@ void Character::SaveXMLToDatabase() { //For metrics, log the time it took to save: auto end = std::chrono::system_clock::now(); std::chrono::duration elapsed = end - start; - Game::logger->Log("Character", "Saved character to Database in: %fs", elapsed.count()); + Game::logger->Log("Character", "%i:%s Saved character to Database in: %fs", this->GetID(), this->GetName().c_str(), elapsed.count()); } void Character::SetIsNewLogin() { @@ -396,7 +396,7 @@ void Character::SetIsNewLogin() { while (currentChild) { if (currentChild->Attribute("si")) { flags->DeleteChild(currentChild); - Game::logger->Log("Character", "Removed isLoggedIn flag from character %i, saving character to database", GetID()); + Game::logger->Log("Character", "Removed isLoggedIn flag from character %i:%s, saving character to database", GetID(), GetName().c_str()); WriteToDatabase(); } currentChild = currentChild->NextSiblingElement(); From 7949907517411da0aeeb508676c15745280c5a03 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 6 May 2023 11:32:46 -0700 Subject: [PATCH 024/116] Fix bounds check (#1070) --- dPhysics/dpGrid.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index b4fe385e..1631c91a 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -63,13 +63,13 @@ void dpGrid::Move(dpEntity* entity, float x, float z) { if (cellX < 0) cellX = 0; if (cellZ < 0) cellZ = 0; - if (cellX > NUM_CELLS) cellX = NUM_CELLS; - if (cellZ > NUM_CELLS) cellZ = NUM_CELLS; + if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; + if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; if (oldCellX < 0) oldCellX = 0; if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX > NUM_CELLS) oldCellX = NUM_CELLS; - if (oldCellZ > NUM_CELLS) oldCellZ = NUM_CELLS; + if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; + if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; if (oldCellX == cellX && oldCellZ == cellZ) return; From 33c12f3bc5998d7af601571aed01a13df99c34f4 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 6 May 2023 11:32:53 -0700 Subject: [PATCH 025/116] Fix bounds check (#1071) Fix Chat Crash Update CMakeVariables.txt Add checks for all servers --- dAuthServer/AuthServer.cpp | 2 ++ dChatServer/ChatServer.cpp | 2 ++ dMasterServer/MasterServer.cpp | 2 ++ dWorldServer/WorldServer.cpp | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index ddec32db..262886d7 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -171,6 +171,8 @@ dLogger* SetupLogger() { } void HandlePacket(Packet* packet) { + if (packet->length < 4) return; + if (packet->data[0] == ID_USER_PACKET_ENUM) { if (static_cast(packet->data[1]) == eConnectionType::SERVER) { if (static_cast(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) { diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index 3e3ddfd3..b9fb8556 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -203,6 +203,8 @@ void HandlePacket(Packet* packet) { Game::logger->Log("ChatServer", "A server is connecting, awaiting user list."); } + if (packet->length < 4) return; // Nothing left to process. Need 4 bytes to continue. + if (static_cast(packet->data[1]) == eConnectionType::CHAT_INTERNAL) { switch (static_cast(packet->data[3])) { case eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION: diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 4b524d8d..bc0937c2 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -495,6 +495,8 @@ void HandlePacket(Packet* packet) { } } + if (packet->length < 4) return; + if (static_cast(packet->data[1]) == eConnectionType::MASTER) { switch (static_cast(packet->data[3])) { case eMasterMessageType::REQUEST_PERSISTENT_ID: { diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 4eca86f2..26cbe7ba 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -728,7 +728,7 @@ void HandlePacket(Packet* packet) { Game::server->SendToMaster(&bitStream); } - if (packet->data[0] != ID_USER_PACKET_ENUM) return; + if (packet->data[0] != ID_USER_PACKET_ENUM || packet->length < 4) return; if (static_cast(packet->data[1]) == eConnectionType::SERVER) { if (static_cast(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) { AuthPackets::HandleHandshake(Game::server, packet); From 7e616385957ec683b48067e9c5960f17a270c7aa Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 6 May 2023 23:45:07 -0700 Subject: [PATCH 026/116] Reinforce PacketUtils writing (#1073) Ensure the correct size is written to the bitstream. It is always supposed to write 64 bits. --- dNet/PacketUtils.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dNet/PacketUtils.h b/dNet/PacketUtils.h index 7c917f2e..d07759a0 100644 --- a/dNet/PacketUtils.h +++ b/dNet/PacketUtils.h @@ -10,10 +10,10 @@ enum class eConnectionType : uint16_t; namespace PacketUtils { template void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) { - bitStream.Write(MessageID(ID_USER_PACKET_ENUM)); - bitStream.Write(connectionType); - bitStream.Write(internalPacketID); - bitStream.Write(uint8_t(0)); + bitStream.Write(MessageID(ID_USER_PACKET_ENUM)); + bitStream.Write(connectionType); + bitStream.Write(static_cast(internalPacketID)); + bitStream.Write(0); } uint16_t ReadPacketU16(uint32_t startLoc, Packet* packet); From 820b375c509b2af234fbfbbf1315c486748b0a7f Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 7 May 2023 00:31:38 -0700 Subject: [PATCH 027/116] push --- dGame/LeaderboardManager.cpp | 165 ++++++++++++++---- .../dlu/9_Update_Leaderboard_Storage.sql | 1 + tests/dGameTests/LeaderboardTests.cpp | 16 +- 3 files changed, 142 insertions(+), 40 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 9dc32061..1f436d30 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -273,68 +273,61 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead va_end(args); } -std::string FormatInsert(const char* columns, const char* format, va_list args) { - auto queryBase = "INSERT INTO leaderboard (%s) VALUES (%s)"; +std::string FormatInsert(const std::string& columns, const std::string& format, va_list args, bool update) { + const char* insert = "INSERT"; + const char* update = "UPDATE"; + auto queryBase = "%s leaderboard SET %s WHERE id = ?;"; constexpr uint16_t STRING_LENGTH = 400; char formattedInsert[STRING_LENGTH]; char finishedQuery[STRING_LENGTH]; - snprintf(formattedInsert, STRING_LENGTH, queryBase, columns, format); + snprintf(formattedInsert, STRING_LENGTH, queryBase, columns.c_str(), format.c_str()); vsnprintf(finishedQuery, STRING_LENGTH, formattedInsert, args); return finishedQuery; } void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args) { std::string insertStatement; - // use replace into to update the score if it already exists instead of needing an update and an insert - std::unique_ptr lookup(Database::CreatePreppedStmt("SELECT * FROM leaderboard WHERE playerID = ? AND gameID = ?")); - lookup->setInt64(1, playerID); - lookup->setInt(2, gameID); - std::unique_ptr lookupResult(lookup->executeQuery()); + std::string selectedColumns; + std::string insertFormat; + // If ResultSet is empty, just insert our score. + std::va_list argsCopy; + va_copy(argsCopy, args); switch (leaderboardType) { case Leaderboard::Type::ShootingGallery: { - auto lookupResult = lookup->executeQuery(); - if (lookupResult->next()) { - - } else { - auto result = FormatInsert("hitPercentage, score, streak", "%f, %i, %i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - } + selectedColumns = "score, hitPercentage, streak"; + insertFormat = "score=%i, hitPercentage=%f, streak=%i"; break; } case Leaderboard::Type::Racing: { - auto result = FormatInsert("bestLapTime, bestTime", "%f, %f", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + selectedColumns = "bestLapTime, bestTime"; + insertFormat = "bestLapTime=%f, bestTime=%f"; break; } case Leaderboard::Type::UnusedLeaderboard4: { - auto result = FormatInsert("points", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); - break; - } - case Leaderboard::Type::MonumentRace: { - auto result = FormatInsert("time", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + selectedColumns = "score"; + insertFormat = "score=%i"; break; } + case Leaderboard::Type::MonumentRace: case Leaderboard::Type::FootRace: { - auto result = FormatInsert("time", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + selectedColumns = "time"; + insertFormat = "time=%i"; break; } case Leaderboard::Type::Survival: { - auto result = FormatInsert("points, time", "%i, %i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + selectedColumns = "points, time"; + insertFormat = "points=%i, time=%i"; break; } case Leaderboard::Type::SurvivalNS: { - auto result = FormatInsert("time, wave", "%i, %i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + selectedColumns = "time, wave"; + insertFormat = "time=%i, wave=%i"; break; } case Leaderboard::Type::Donations: { - auto result = FormatInsert("score", "%i", args); - Game::logger->Log("LeaderboardManager", "%s", result.c_str()); + selectedColumns = "score"; + insertFormat = "score=%i"; break; } case Leaderboard::Type::None: { @@ -346,7 +339,115 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead return; } } + const char* lookup = "SELECT %s FROM leaderboard WHERE character_id = ? AND game_id = ?;"; + constexpr uint16_t STRING_LENGTH = 400; + char lookupBuffer[STRING_LENGTH]; + snprintf(lookupBuffer, STRING_LENGTH, lookup, selectedColumns.c_str()); + std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); + query->setInt(1, playerID); + query->setInt(2, gameID); + std::unique_ptr myScoreResult(query->executeQuery()); + switch (leaderboardType) { + case Leaderboard::Type::ShootingGallery: { + int32_t oldScore = myScoreResult->getInt("score"); + int32_t score; + score = va_arg(argsCopy, int32_t); + + float oldHitPercentage = myScoreResult->getFloat("hitPercentage"); + float hitPercentage; + hitPercentage = va_arg(argsCopy, double); + + int32_t oldStreak = myScoreResult->getInt("streak"); + int32_t streak; + streak = va_arg(argsCopy, int32_t); + + if ( + score > oldScore || // If score is better + (score == oldScore && hitPercentage > oldHitPercentage) || // or if the score is tied and the hitPercentage is better + (score == oldScore && hitPercentage == oldHitPercentage && streak > oldStreak)) { // or if the score and hitPercentage are tied and the streak is better + // Save + } + break; + } + case Leaderboard::Type::Racing: { + float oldLapTime = myScoreResult->getFloat("bestLapTime"); + float lapTime; + lapTime = va_arg(argsCopy, double); + + float oldTime = myScoreResult->getFloat("bestTime"); + float oldTime; + oldTime = va_arg(argsCopy, double); + + int32_t oldNumWins = myScoreResult->getInt("numWins"); + bool won; + won = va_arg(argsCopy, int32_t); + // Compare bestTime, if LOWER save + // Compare bestLapTime, if LOWER save + // Increment numWins if player won + break; + } + case Leaderboard::Type::UnusedLeaderboard4: { + int32_t oldScore = myScoreResult->getInt("score"); + int32_t points; + points = va_arg(argsCopy, int32_t); + // Compare score, if HIGHER save + break; + } + case Leaderboard::Type::MonumentRace: { + int32_t oldTime = myScoreResult->getInt("time"); + int32_t time; + time = va_arg(argsCopy, int32_t); + // Compare time, if LOWER save + break; + } + case Leaderboard::Type::FootRace: { + int32_t oldTime = myScoreResult->getInt("time"); + int32_t time; + time = va_arg(argsCopy, int32_t); + // Compare time, if HIGHER save + break; + } + case Leaderboard::Type::Survival: { + int32_t oldPoints = myScoreResult->getInt("points"); + int32_t points; + points = va_arg(argsCopy, int32_t); + + int32_t oldTime = myScoreResult->getInt("time"); + int32_t time; + time = va_arg(argsCopy, int32_t); + // Compare points, if HIGHER save, if TIED compare time, if LOWER save + // If classic_survival_scoring is 1, reverse the order of the points and time columns + break; + } + case Leaderboard::Type::SurvivalNS: { + int32_t oldTime = myScoreResult->getInt("time"); + int32_t time; + time = va_arg(argsCopy, int32_t); + + int32_t oldWave = myScoreResult->getInt("wave"); + int32_t wave; + wave = va_arg(argsCopy, int32_t); + // Compare wave, if HIGHER save, if TIED compare time, if LOWER save + break; + } + case Leaderboard::Type::Donations: { + int32_t oldScore = myScoreResult->getInt("score"); + int32_t score; + score = va_arg(argsCopy, int32_t); + // Compare score, if HIGHER save + break; + } + case Leaderboard::Type::None: { + // This type is included here simply to resolve a compiler warning on mac about unused enum types + Game::logger->Log("LeaderboardManager", "Warning: Saving score for leaderboard of type None. Are you sure this is intended?"); + break; + } + default: + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); + break; + } + va_end(argsCopy); } void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index 5e9c5fa2..d6f185dc 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -3,6 +3,7 @@ ALTER TABLE leaderboard ADD COLUMN streak INT NOT NULL DEFAULT 0, ADD COLUMN bestLapTime FLOAT NOT NULL DEFAULT 0, ADD COLUMN numWins INT NOT NULL DEFAULT 0, + ADD COLUMN timesPlayed INT NOT NULL DEFAULT 0, MODIFY time FLOAT NOT NULL DEFAULT 0; ALTER TABLE leaderboard CHANGE time bestTime float; diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index 7cec021b..38e92658 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -75,19 +75,19 @@ TEST_F(LeaderboardTests, LeaderboardSpeedTest) { RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::ShootingGallery, 3, 3000, 15.0f, 100); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::ShootingGallery, 3, 3000, 15.0f, 100); // RunTests(0, Leaderboard::Type::Racing); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Racing, 2, 260.0f, 250.0f); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Racing, 3, 260.0f, 250.0f, true); // RunTests(0, Leaderboard::Type::MonumentRace); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::MonumentRace, 1, 150); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::MonumentRace, 1, 150); // RunTests(0, Leaderboard::Type::FootRace); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::FootRace, 1, 150); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::FootRace, 1, 150); // RunTests(0, Leaderboard::Type::UnusedLeaderboard4); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 100); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 100); // RunTests(0, Leaderboard::Type::Survival); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Survival, 2, 3000, 15); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Survival, 2, 3000, 15); // RunTests(0, Leaderboard::Type::SurvivalNS); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::SurvivalNS, 2, 300, 15); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::SurvivalNS, 2, 300, 15); // RunTests(0, Leaderboard::Type::Donations); - // LeaderboardManager::Instance().SaveScore(0, 0, Leaderboard::Type::Donations, 1, 300000); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Donations, 1, 300000); } From bc518be65459c48dbce4816b14726476c6b3be22 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 7 May 2023 04:09:10 -0700 Subject: [PATCH 028/116] Bug fixes and cleanup Fix co-pilot induced column bugs Fix insert/update statements Added saving functionality Added update clause for column --- dGame/LeaderboardManager.cpp | 227 ++++++++++-------- .../dlu/9_Update_Leaderboard_Storage.sql | 1 + tests/dGameTests/LeaderboardTests.cpp | 14 +- 3 files changed, 134 insertions(+), 108 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 1f436d30..826fcef3 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -273,23 +273,34 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead va_end(args); } -std::string FormatInsert(const std::string& columns, const std::string& format, va_list args, bool update) { +std::string FormatInsert(const std::string& columns, const std::string& format, va_list args, bool useUpdate) { const char* insert = "INSERT"; const char* update = "UPDATE"; - auto queryBase = "%s leaderboard SET %s WHERE id = ?;"; + const char* queryType = useUpdate ? update : insert; + + const char* scoreFilter = "character_id = ? AND game_id = ?"; + const char* usedFilter = useUpdate ? scoreFilter : ""; + constexpr uint16_t STRING_LENGTH = 400; char formattedInsert[STRING_LENGTH]; + auto queryBase = "%s leaderboard SET %s, character_id = ?, game_id = ? %s;"; + snprintf(formattedInsert, STRING_LENGTH, queryBase, queryType, format.c_str(), usedFilter); + char finishedQuery[STRING_LENGTH]; - snprintf(formattedInsert, STRING_LENGTH, queryBase, columns.c_str(), format.c_str()); vsnprintf(finishedQuery, STRING_LENGTH, formattedInsert, args); return finishedQuery; } void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args) { + // Increment the numTimes this player has played this game. + std::unique_ptr incrementStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;")); + incrementStatement->setInt(1, playerID); + incrementStatement->setInt(2, gameID); + incrementStatement->executeUpdate(); + std::string insertStatement; std::string selectedColumns; std::string insertFormat; - // If ResultSet is empty, just insert our score. std::va_list argsCopy; va_copy(argsCopy, args); @@ -300,8 +311,8 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead break; } case Leaderboard::Type::Racing: { - selectedColumns = "bestLapTime, bestTime"; - insertFormat = "bestLapTime=%f, bestTime=%f"; + selectedColumns = "bestLapTime, bestTime, numWins"; + insertFormat = "bestLapTime=%f, bestTime=%f, numWins=%i"; break; } case Leaderboard::Type::UnusedLeaderboard4: { @@ -311,18 +322,18 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead } case Leaderboard::Type::MonumentRace: case Leaderboard::Type::FootRace: { - selectedColumns = "time"; - insertFormat = "time=%i"; + selectedColumns = "bestTime"; + insertFormat = "bestTime=%i"; break; } case Leaderboard::Type::Survival: { - selectedColumns = "points, time"; - insertFormat = "points=%i, time=%i"; + selectedColumns = "score, bestTime"; + insertFormat = "score=%i, bestTime=%i"; break; } case Leaderboard::Type::SurvivalNS: { - selectedColumns = "time, wave"; - insertFormat = "time=%i, wave=%i"; + selectedColumns = "bestTime, score"; + insertFormat = "bestTime=%i, score=%i"; break; } case Leaderboard::Type::Donations: { @@ -340,112 +351,126 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead } } const char* lookup = "SELECT %s FROM leaderboard WHERE character_id = ? AND game_id = ?;"; + constexpr uint16_t STRING_LENGTH = 400; char lookupBuffer[STRING_LENGTH]; snprintf(lookupBuffer, STRING_LENGTH, lookup, selectedColumns.c_str()); + std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); query->setInt(1, playerID); query->setInt(2, gameID); std::unique_ptr myScoreResult(query->executeQuery()); - switch (leaderboardType) { - case Leaderboard::Type::ShootingGallery: { - int32_t oldScore = myScoreResult->getInt("score"); - int32_t score; - score = va_arg(argsCopy, int32_t); + std::string saveQuery; + if (myScoreResult->next()) { + switch (leaderboardType) { + case Leaderboard::Type::ShootingGallery: { + int32_t oldScore = myScoreResult->getInt("score"); + int32_t score; + score = va_arg(argsCopy, int32_t); - float oldHitPercentage = myScoreResult->getFloat("hitPercentage"); - float hitPercentage; - hitPercentage = va_arg(argsCopy, double); + float oldHitPercentage = myScoreResult->getFloat("hitPercentage"); + float hitPercentage; + hitPercentage = va_arg(argsCopy, double); - int32_t oldStreak = myScoreResult->getInt("streak"); - int32_t streak; - streak = va_arg(argsCopy, int32_t); + int32_t oldStreak = myScoreResult->getInt("streak"); + int32_t streak; + streak = va_arg(argsCopy, int32_t); - if ( - score > oldScore || // If score is better - (score == oldScore && hitPercentage > oldHitPercentage) || // or if the score is tied and the hitPercentage is better - (score == oldScore && hitPercentage == oldHitPercentage && streak > oldStreak)) { // or if the score and hitPercentage are tied and the streak is better - // Save + if ( + score > oldScore || // If score is better + (score == oldScore && hitPercentage > oldHitPercentage) || // or if the score is tied and the hitPercentage is better + (score == oldScore && hitPercentage == oldHitPercentage && streak > oldStreak)) { // or if the score and hitPercentage are tied and the streak is better + saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + } + break; } - break; - } - case Leaderboard::Type::Racing: { - float oldLapTime = myScoreResult->getFloat("bestLapTime"); - float lapTime; - lapTime = va_arg(argsCopy, double); + case Leaderboard::Type::Racing: { + float oldLapTime = myScoreResult->getFloat("bestLapTime"); + float lapTime; + lapTime = va_arg(argsCopy, double); - float oldTime = myScoreResult->getFloat("bestTime"); - float oldTime; - oldTime = va_arg(argsCopy, double); + float oldTime = myScoreResult->getFloat("bestTime"); + float newTime; + newTime = va_arg(argsCopy, double); - int32_t oldNumWins = myScoreResult->getInt("numWins"); - bool won; - won = va_arg(argsCopy, int32_t); - // Compare bestTime, if LOWER save - // Compare bestLapTime, if LOWER save - // Increment numWins if player won - break; - } - case Leaderboard::Type::UnusedLeaderboard4: { - int32_t oldScore = myScoreResult->getInt("score"); - int32_t points; - points = va_arg(argsCopy, int32_t); - // Compare score, if HIGHER save - break; - } - case Leaderboard::Type::MonumentRace: { - int32_t oldTime = myScoreResult->getInt("time"); - int32_t time; - time = va_arg(argsCopy, int32_t); - // Compare time, if LOWER save - break; - } - case Leaderboard::Type::FootRace: { - int32_t oldTime = myScoreResult->getInt("time"); - int32_t time; - time = va_arg(argsCopy, int32_t); - // Compare time, if HIGHER save - break; - } - case Leaderboard::Type::Survival: { - int32_t oldPoints = myScoreResult->getInt("points"); - int32_t points; - points = va_arg(argsCopy, int32_t); + int32_t oldNumWins = myScoreResult->getInt("numWins"); + bool won; + won = va_arg(argsCopy, int32_t); + // Compare bestTime, if LOWER save + // Compare bestLapTime, if LOWER save + // Increment numWins if player won + break; + } + case Leaderboard::Type::UnusedLeaderboard4: { + int32_t oldScore = myScoreResult->getInt("score"); + int32_t points; + points = va_arg(argsCopy, int32_t); + // Compare score, if HIGHER save + break; + } + case Leaderboard::Type::MonumentRace: { + int32_t oldTime = myScoreResult->getInt("bestTime"); + int32_t time; + time = va_arg(argsCopy, int32_t); + // Compare time, if LOWER save + break; + } + case Leaderboard::Type::FootRace: { + int32_t oldTime = myScoreResult->getInt("bestTime"); + int32_t time; + time = va_arg(argsCopy, int32_t); + // Compare time, if HIGHER save + break; + } + case Leaderboard::Type::Survival: { + int32_t oldPoints = myScoreResult->getInt("score"); + int32_t points; + points = va_arg(argsCopy, int32_t); - int32_t oldTime = myScoreResult->getInt("time"); - int32_t time; - time = va_arg(argsCopy, int32_t); - // Compare points, if HIGHER save, if TIED compare time, if LOWER save - // If classic_survival_scoring is 1, reverse the order of the points and time columns - break; - } - case Leaderboard::Type::SurvivalNS: { - int32_t oldTime = myScoreResult->getInt("time"); - int32_t time; - time = va_arg(argsCopy, int32_t); + int32_t oldTime = myScoreResult->getInt("bestTime"); + int32_t time; + time = va_arg(argsCopy, int32_t); + // Compare points, if HIGHER save, if TIED compare time, if LOWER save + // If classic_survival_scoring is 1, reverse the order of the points and time columns + break; + } + case Leaderboard::Type::SurvivalNS: { + int32_t oldTime = myScoreResult->getInt("bestTime"); + int32_t time; + time = va_arg(argsCopy, int32_t); - int32_t oldWave = myScoreResult->getInt("wave"); - int32_t wave; - wave = va_arg(argsCopy, int32_t); - // Compare wave, if HIGHER save, if TIED compare time, if LOWER save - break; + int32_t oldWave = myScoreResult->getInt("score"); + int32_t wave; + wave = va_arg(argsCopy, int32_t); + // Compare wave, if HIGHER save, if TIED compare time, if LOWER save + break; + } + case Leaderboard::Type::Donations: { + int32_t oldScore = myScoreResult->getInt("score"); + int32_t score; + score = va_arg(argsCopy, int32_t); + // Compare score, if HIGHER save + break; + } + case Leaderboard::Type::None: { + // This type is included here simply to resolve a compiler warning on mac about unused enum types + Game::logger->Log("LeaderboardManager", "Warning: Saving score for leaderboard of type None. Are you sure this is intended?"); + break; + } + default: + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); + break; + } + } else { + saveQuery = FormatInsert(selectedColumns, insertFormat, argsCopy, false); } - case Leaderboard::Type::Donations: { - int32_t oldScore = myScoreResult->getInt("score"); - int32_t score; - score = va_arg(argsCopy, int32_t); - // Compare score, if HIGHER save - break; - } - case Leaderboard::Type::None: { - // This type is included here simply to resolve a compiler warning on mac about unused enum types - Game::logger->Log("LeaderboardManager", "Warning: Saving score for leaderboard of type None. Are you sure this is intended?"); - break; - } - default: - Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); - break; + Game::logger->Log("LeaderboardManager", "%s", saveQuery.c_str()); + if (!saveQuery.empty()) { + std::unique_ptr insertQuery(Database::CreatePreppedStmt(saveQuery)); + insertQuery->setInt(1, playerID); + insertQuery->setInt(2, gameID); + insertQuery->execute(); } va_end(argsCopy); } diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index d6f185dc..498e833c 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -7,5 +7,6 @@ ALTER TABLE leaderboard MODIFY time FLOAT NOT NULL DEFAULT 0; ALTER TABLE leaderboard CHANGE time bestTime float; +ALTER TABLE leaderboard CHANGE last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); UPDATE leaderboard SET streak = bestTime where game_id = 1864; diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index 38e92658..8e6cb4e6 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -30,10 +30,10 @@ protected: Leaderboard leaderboard(gameID, infoType, false, 14231, type); leaderboard.SetupLeaderboard(); leaderboard.Serialize(&bitStream); - TestLeaderboard(leaderboard, 1); - TestLeaderboard(leaderboard, 10); - TestLeaderboard(leaderboard, 100); - TestLeaderboard(leaderboard, 1000); + // TestLeaderboard(leaderboard, 1); + // TestLeaderboard(leaderboard, 10); + // TestLeaderboard(leaderboard, 100); + // TestLeaderboard(leaderboard, 1000); } CBITSTREAM; @@ -73,9 +73,9 @@ protected: TEST_F(LeaderboardTests, LeaderboardSpeedTest) { RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); - RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); - RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::ShootingGallery, 3, 3000, 15.0f, 100); + // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); + // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); + LeaderboardManager::Instance().SaveScore(14231, 1864, Leaderboard::Type::ShootingGallery, 3, 53001, 15.0f, 100); // RunTests(0, Leaderboard::Type::Racing); LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Racing, 3, 260.0f, 250.0f, true); // RunTests(0, Leaderboard::Type::MonumentRace); From 8ceabadcded407f424c65c7cacc825c761840daf Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Mon, 8 May 2023 04:38:08 -0500 Subject: [PATCH 029/116] Removed some hardcoded logic for racing (#1075) Including return world and what activity ID to use for rewards --- dGame/dComponents/RacingControlComponent.cpp | 36 +++++-------------- .../dComponents/ScriptedActivityComponent.cpp | 6 ++-- dGame/dUtilities/SlashCommandHandler.cpp | 17 ++------- dGame/dUtilities/SlashCommandHandler.h | 2 -- dZoneManager/dZoneManager.cpp | 13 +++++++ dZoneManager/dZoneManager.h | 1 + 6 files changed, 27 insertions(+), 48 deletions(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 703ec7f3..3134d5fe 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -23,6 +23,8 @@ #include "dConfig.h" #include "Loot.h" #include "eMissionTaskType.h" +#include "dZoneManager.h" +#include "CDActivitiesTable.h" #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 @@ -45,36 +47,14 @@ RacingControlComponent::RacingControlComponent(Entity* parent) m_EmptyTimer = 0; m_SoloRacing = Game::config->GetValue("solo_racing") == "1"; - // Select the main world ID as fallback when a player fails to load. - + m_MainWorld = 1200; const auto worldID = Game::server->GetZoneID(); + if (dZoneManager::Instance()->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10; - switch (worldID) { - case 1203: - m_ActivityID = 42; - m_MainWorld = 1200; - break; - - case 1261: - m_ActivityID = 60; - m_MainWorld = 1260; - break; - - case 1303: - m_ActivityID = 39; - m_MainWorld = 1300; - break; - - case 1403: - m_ActivityID = 54; - m_MainWorld = 1400; - break; - - default: - m_ActivityID = 42; - m_MainWorld = 1200; - break; - } + m_ActivityID = 42; + CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); + std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.instanceMapID == worldID); }); + for (CDActivities activity : activities) m_ActivityID = activity.ActivityID; } RacingControlComponent::~RacingControlComponent() {} diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index eb4ab761..555332f4 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -27,6 +27,7 @@ #include "CDCurrencyTableTable.h" #include "CDActivityRewardsTable.h" #include "CDActivitiesTable.h" +#include "LeaderboardManager.h" ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { m_ActivityID = activityID; @@ -35,10 +36,7 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit for (CDActivities activity : activities) { m_ActivityInfo = activity; - - const auto mapID = m_ActivityInfo.instanceMapID; - - if ((mapID == 1203 || mapID == 1261 || mapID == 1303 || mapID == 1403) && Game::config->GetValue("solo_racing") == "1") { + if (static_cast(activity.leaderboardType) == LeaderboardType::Racing && Game::config->GetValue("solo_racing") == "1") { m_ActivityInfo.minTeamSize = 1; m_ActivityInfo.minTeams = 1; } diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 07950d7a..16db62a6 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -279,7 +279,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "leave-zone") { const auto currentZone = dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID(); - auto newZone = 0; + LWOMAPID newZone = 0; if (currentZone % 100 == 0) { ChatPackets::SendSystemMessage(sysAddr, u"You are not in an instanced zone."); return; @@ -287,7 +287,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit newZone = (currentZone / 100) * 100; } // If new zone would be inaccessible, then default to Avant Gardens. - if (!CheckIfAccessibleZone(newZone)) newZone = 1100; + if (!dZoneManager::Instance()->CheckIfAccessibleZone(newZone)) newZone = 1100; ChatPackets::SendSystemMessage(sysAddr, u"Leaving zone..."); @@ -1559,7 +1559,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit const auto objid = entity->GetObjectID(); - if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery + if (force || dZoneManager::Instance()->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) { @@ -2021,17 +2021,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } -bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) { - //We're gonna go ahead and presume we've got the db loaded already: - CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable(); - const CDZoneTable* zone = zoneTable->Query(zoneID); - if (zone != nullptr) { - return Game::assetManager->HasFile(("maps/" + zone->zoneName).c_str()); - } else { - return false; - } -} - void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::string& message) { AMFArrayValue args; auto* titleValue = new AMFStringValue(); diff --git a/dGame/dUtilities/SlashCommandHandler.h b/dGame/dUtilities/SlashCommandHandler.h index 9ef09a2f..85b7c697 100644 --- a/dGame/dUtilities/SlashCommandHandler.h +++ b/dGame/dUtilities/SlashCommandHandler.h @@ -13,8 +13,6 @@ class Entity; namespace SlashCommandHandler { void HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr); - bool CheckIfAccessibleZone(const unsigned int zoneID); - void SendAnnouncement(const std::string& title, const std::string& message); }; diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 1a40748d..a26e912f 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -12,6 +12,8 @@ #include "CDZoneTableTable.h" #include #include "eObjectBits.h" +#include "CDZoneTableTable.h" +#include "AssetManager.h" #include "../dWorldServer/ObjectIDManager.h" @@ -227,6 +229,17 @@ uint32_t dZoneManager::GetUniqueMissionIdStartingValue() { return m_UniqueMissionIdStart; } +bool dZoneManager::CheckIfAccessibleZone(LWOMAPID zoneID) { + //We're gonna go ahead and presume we've got the db loaded already: + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable(); + const CDZoneTable* zone = zoneTable->Query(zoneID); + if (zone != nullptr) { + return Game::assetManager->HasFile(("maps/" + zone->zoneName).c_str()); + } else { + return false; + } +} + void dZoneManager::LoadWorldConfig() { Game::logger->Log("dZoneManager", "Loading WorldConfig into memory"); diff --git a/dZoneManager/dZoneManager.h b/dZoneManager/dZoneManager.h index c1776e79..3086e6d7 100644 --- a/dZoneManager/dZoneManager.h +++ b/dZoneManager/dZoneManager.h @@ -50,6 +50,7 @@ public: Entity* GetZoneControlObject() { return m_ZoneControlObject; } bool GetPlayerLoseCoinOnDeath() { return m_PlayerLoseCoinsOnDeath; } uint32_t GetUniqueMissionIdStartingValue(); + bool CheckIfAccessibleZone(LWOMAPID zoneID); // The world config should not be modified by a caller. const WorldConfig* GetWorldConfig() { From 0f307ac4be582950f306a275c0dd35ad0ef9187c Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 8 May 2023 02:46:55 -0700 Subject: [PATCH 030/116] Fix bugs - Reinforce Query formatting - Guarantee 11 rows are selected at a time by ranking by id, should there be more than an 11 way tie. --- dGame/LeaderboardManager.cpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 826fcef3..83703724 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -69,7 +69,7 @@ void Leaderboard::SetupLeaderboard() { SELECT leaderboard.*, charinfo.name, RANK() OVER ( - ORDER BY %s + ORDER BY %s, UNIX_TIMESTAMP(last_played) ASC, id DESC ) AS ranking FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id WHERE game_id = ? %s @@ -274,16 +274,17 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead } std::string FormatInsert(const std::string& columns, const std::string& format, va_list args, bool useUpdate) { - const char* insert = "INSERT"; - const char* update = "UPDATE"; - const char* queryType = useUpdate ? update : insert; + const char* insertClause = "INSERT"; + const char* updateClause = "UPDATE"; + const char* queryType = useUpdate ? updateClause : insertClause; - const char* scoreFilter = "character_id = ? AND game_id = ?"; - const char* usedFilter = useUpdate ? scoreFilter : ""; + const char* insertFilter = ", character_id = ?, game_id = ?"; + const char* updateFilter = "WHERE character_id = ? AND game_id = ?"; + const char* usedFilter = useUpdate ? updateFilter : insertFilter; constexpr uint16_t STRING_LENGTH = 400; char formattedInsert[STRING_LENGTH]; - auto queryBase = "%s leaderboard SET %s, character_id = ?, game_id = ? %s;"; + auto queryBase = "%s leaderboard SET %s %s;"; snprintf(formattedInsert, STRING_LENGTH, queryBase, queryType, format.c_str(), usedFilter); char finishedQuery[STRING_LENGTH]; @@ -406,6 +407,9 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t oldScore = myScoreResult->getInt("score"); int32_t points; points = va_arg(argsCopy, int32_t); + if (points > oldScore) { + saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + } // Compare score, if HIGHER save break; } @@ -413,6 +417,9 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t oldTime = myScoreResult->getInt("bestTime"); int32_t time; time = va_arg(argsCopy, int32_t); + if (time < oldTime) { + saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + } // Compare time, if LOWER save break; } @@ -420,6 +427,9 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t oldTime = myScoreResult->getInt("bestTime"); int32_t time; time = va_arg(argsCopy, int32_t); + if (time < oldTime) { + saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + } // Compare time, if HIGHER save break; } @@ -431,6 +441,9 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t oldTime = myScoreResult->getInt("bestTime"); int32_t time; time = va_arg(argsCopy, int32_t); + if (points > oldPoints || (points == oldPoints && time < oldTime)) { + saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + } // Compare points, if HIGHER save, if TIED compare time, if LOWER save // If classic_survival_scoring is 1, reverse the order of the points and time columns break; @@ -443,6 +456,9 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t oldWave = myScoreResult->getInt("score"); int32_t wave; wave = va_arg(argsCopy, int32_t); + if (time < oldTime || (time == oldTime && wave > oldWave)) { + saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + } // Compare wave, if HIGHER save, if TIED compare time, if LOWER save break; } @@ -450,6 +466,9 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t oldScore = myScoreResult->getInt("score"); int32_t score; score = va_arg(argsCopy, int32_t); + if (score > oldScore) { + saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + } // Compare score, if HIGHER save break; } @@ -458,6 +477,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead Game::logger->Log("LeaderboardManager", "Warning: Saving score for leaderboard of type None. Are you sure this is intended?"); break; } + default: Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); break; From 1c7ac93d4b75a55c4f58360311568ae51bfeb9af Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 8 May 2023 03:55:10 -0700 Subject: [PATCH 031/116] Fix various bugs and make code cleaner. Still have work to go. --- dGame/LeaderboardManager.cpp | 26 +++++++++---------- .../dlu/9_Update_Leaderboard_Storage.sql | 2 +- tests/dGameTests/LeaderboardTests.cpp | 16 ++++++------ 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 83703724..44ef17cc 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -64,7 +64,7 @@ bool Leaderboard::GetRankingQuery(std::string& lookupReturn) const { void Leaderboard::SetupLeaderboard() { std::string queryBase = - R"QUERY( + R"QUERY( WITH leaderboardsRanked AS ( SELECT leaderboard.*, charinfo.name, RANK() OVER @@ -278,8 +278,8 @@ std::string FormatInsert(const std::string& columns, const std::string& format, const char* updateClause = "UPDATE"; const char* queryType = useUpdate ? updateClause : insertClause; - const char* insertFilter = ", character_id = ?, game_id = ?"; - const char* updateFilter = "WHERE character_id = ? AND game_id = ?"; + const char* insertFilter = ", character_id = ?, game_id = ?, timesPlayed = 1"; + const char* updateFilter = ", timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?"; const char* usedFilter = useUpdate ? updateFilter : insertFilter; constexpr uint16_t STRING_LENGTH = 400; @@ -293,12 +293,6 @@ std::string FormatInsert(const std::string& columns, const std::string& format, } void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args) { - // Increment the numTimes this player has played this game. - std::unique_ptr incrementStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;")); - incrementStatement->setInt(1, playerID); - incrementStatement->setInt(2, gameID); - incrementStatement->executeUpdate(); - std::string insertStatement; std::string selectedColumns; std::string insertFormat; @@ -342,10 +336,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead insertFormat = "score=%i"; break; } - case Leaderboard::Type::None: { - Game::logger->Log("LeaderboardManager", "Warning: Saving leaderboard of type None. Are you sure this is intended?"); - break; - } + case Leaderboard::Type::None: default: { Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); return; @@ -485,12 +476,19 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead } else { saveQuery = FormatInsert(selectedColumns, insertFormat, argsCopy, false); } - Game::logger->Log("LeaderboardManager", "%s", saveQuery.c_str()); if (!saveQuery.empty()) { + Game::logger->Log("LeaderboardManager", "%s", saveQuery.c_str()); std::unique_ptr insertQuery(Database::CreatePreppedStmt(saveQuery)); insertQuery->setInt(1, playerID); insertQuery->setInt(2, gameID); insertQuery->execute(); + } else { + Game::logger->Log("LeaderboardManager", "No new score to save, incrementing numTimesPlayed"); + // Increment the numTimes this player has played this game. + std::unique_ptr incrementStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;")); + incrementStatement->setInt(1, playerID); + incrementStatement->setInt(2, gameID); + incrementStatement->executeUpdate(); } va_end(argsCopy); } diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index 498e833c..c90ba4a2 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -7,6 +7,6 @@ ALTER TABLE leaderboard MODIFY time FLOAT NOT NULL DEFAULT 0; ALTER TABLE leaderboard CHANGE time bestTime float; -ALTER TABLE leaderboard CHANGE last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); +ALTER TABLE leaderboard CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); UPDATE leaderboard SET streak = bestTime where game_id = 1864; diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index 8e6cb4e6..a4b7b9c0 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -75,19 +75,19 @@ TEST_F(LeaderboardTests, LeaderboardSpeedTest) { RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); - LeaderboardManager::Instance().SaveScore(14231, 1864, Leaderboard::Type::ShootingGallery, 3, 53001, 15.0f, 100); + LeaderboardManager::Instance().SaveScore(14231, 1864, Leaderboard::Type::ShootingGallery, 3, 53002, 15.0f, 100); // RunTests(0, Leaderboard::Type::Racing); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Racing, 3, 260.0f, 250.0f, true); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Racing, 3, 259.0f, 250.0f, true); // RunTests(0, Leaderboard::Type::MonumentRace); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::MonumentRace, 1, 150); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::MonumentRace, 1, 149); // RunTests(0, Leaderboard::Type::FootRace); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::FootRace, 1, 150); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::FootRace, 1, 151); // RunTests(0, Leaderboard::Type::UnusedLeaderboard4); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 100); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 101); // RunTests(0, Leaderboard::Type::Survival); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Survival, 2, 3000, 15); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Survival, 2, 3001, 15); // RunTests(0, Leaderboard::Type::SurvivalNS); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::SurvivalNS, 2, 300, 15); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::SurvivalNS, 2, 301, 15); // RunTests(0, Leaderboard::Type::Donations); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Donations, 1, 300000); + LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Donations, 1, 300001); } From 7aad6e4bc2b399b26ca732a25ac9204f4bdbf6d6 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 8 May 2023 04:31:10 -0700 Subject: [PATCH 032/116] Make header skips more obvious (#1074) * Make header skips more obvious seeing inStream.Read(LWOOBJID) is much less clear than a macro which very clearly skips the header. * Formatting pass --- dChatServer/ChatPacketHandler.cpp | 36 +++++++++----------------- dChatServer/PlayerContainer.cpp | 12 +++------ dCommon/dEnums/dCommonVars.h | 2 ++ dNet/ClientPackets.cpp | 8 ++---- dWorldServer/WorldServer.cpp | 18 ++++--------- tests/dCommonTests/CMakeLists.txt | 1 + tests/dCommonTests/HeaderSkipTest.cpp | 37 +++++++++++++++++++++++++++ 7 files changed, 63 insertions(+), 51 deletions(-) create mode 100644 tests/dCommonTests/HeaderSkipTest.cpp diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index 9b5ca761..878cc71c 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -22,10 +22,9 @@ extern PlayerContainer playerContainer; void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { //Get from the packet which player we want to do something with: - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = 0; inStream.Read(playerID); - inStream.Read(playerID); auto player = playerContainer.GetPlayerData(playerID); if (!player) return; @@ -99,10 +98,9 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { auto maxNumberOfBestFriendsAsString = Game::config->GetValue("max_number_of_best_friends"); // If this config option doesn't exist, default to 5 which is what live used. auto maxNumberOfBestFriends = maxNumberOfBestFriendsAsString != "" ? std::stoi(maxNumberOfBestFriendsAsString) : 5U; - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID requestorPlayerID; inStream.Read(requestorPlayerID); - inStream.Read(requestorPlayerID); uint32_t spacing{}; inStream.Read(spacing); std::string playerName = ""; @@ -247,10 +245,9 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { } void ChatPacketHandler::HandleFriendResponse(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); eAddFriendResponseCode clientResponseCode = static_cast(packet->data[0x14]); std::string friendName = PacketUtils::ReadString(0x15, packet, true); @@ -323,10 +320,9 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { } void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); std::string friendName = PacketUtils::ReadString(0x14, packet, true); //we'll have to query the db here to find the user, since you can delete them while they're offline. @@ -381,10 +377,9 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { } void ChatPacketHandler::HandleChatMessage(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); auto* sender = playerContainer.GetPlayerData(playerID); @@ -501,10 +496,9 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { } void ChatPacketHandler::HandleTeamInvite(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); std::string invitedPlayer = PacketUtils::ReadString(0x14, packet, true); auto* player = playerContainer.GetPlayerData(playerID); @@ -542,10 +536,9 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) { } void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); uint32_t size = 0; inStream.Read(size); char declined = 0; @@ -576,10 +569,9 @@ void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) { } void ChatPacketHandler::HandleTeamLeave(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); uint32_t size = 0; inStream.Read(size); @@ -593,10 +585,9 @@ void ChatPacketHandler::HandleTeamLeave(Packet* packet) { } void ChatPacketHandler::HandleTeamKick(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); std::string kickedPlayer = PacketUtils::ReadString(0x14, packet, true); @@ -624,10 +615,9 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) { } void ChatPacketHandler::HandleTeamPromote(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); std::string promotedPlayer = PacketUtils::ReadString(0x14, packet, true); @@ -647,10 +637,9 @@ void ChatPacketHandler::HandleTeamPromote(Packet* packet) { } void ChatPacketHandler::HandleTeamLootOption(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); uint32_t size = 0; inStream.Read(size); @@ -671,10 +660,9 @@ void ChatPacketHandler::HandleTeamLootOption(Packet* packet) { } void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); auto* team = playerContainer.GetTeam(playerID); auto* data = playerContainer.GetPlayerData(playerID); diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index dcc9ebb9..689ffd77 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -19,9 +19,8 @@ PlayerContainer::~PlayerContainer() { } void PlayerContainer::InsertPlayer(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; PlayerData* data = new PlayerData(); - inStream.SetReadOffset(inStream.GetReadOffset() + 64); inStream.Read(data->playerID); uint32_t len; @@ -52,9 +51,8 @@ void PlayerContainer::InsertPlayer(Packet* packet) { } void PlayerContainer::RemovePlayer(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; - inStream.Read(playerID); //skip header inStream.Read(playerID); //Before they get kicked, we need to also send a message to their friends saying that they disconnected. @@ -97,9 +95,8 @@ void PlayerContainer::RemovePlayer(Packet* packet) { } void PlayerContainer::MuteUpdate(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; - inStream.Read(playerID); //skip header inStream.Read(playerID); time_t expire = 0; inStream.Read(expire); @@ -118,9 +115,8 @@ void PlayerContainer::MuteUpdate(Packet* packet) { } void PlayerContainer::CreateTeamServer(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; - inStream.Read(playerID); //skip header inStream.Read(playerID); size_t membersSize = 0; inStream.Read(membersSize); diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index e11866f1..f67145da 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -28,8 +28,10 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate); //========== MACROS =========== +#define HEADER_SIZE 8 #define CBITSTREAM RakNet::BitStream bitStream; #define CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false); +#define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits()); #define CMSGHEADER PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); #define SEND_PACKET Game::server->Send(&bitStream, sysAddr, false); #define SEND_PACKET_BROADCAST Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true); diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 4ccbb609..1c22bdcd 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -46,9 +46,7 @@ void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* pack return; } - CINSTREAM; - uint64_t header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; char chatChannel; uint16_t unknown; @@ -82,9 +80,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac return; } - CINSTREAM; - uint64_t header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; Entity* entity = EntityManager::Instance()->GetEntity(user->GetLastUsedChar()->GetObjectID()); if (!entity) return; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 26cbe7ba..5dabce1c 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -554,10 +554,9 @@ void HandlePacketChat(Packet* packet) { if (static_cast(packet->data[1]) == eConnectionType::CHAT_INTERNAL) { switch (static_cast(packet->data[3])) { case eChatInternalMessageType::ROUTE_TO_PLAYER: { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); auto player = EntityManager::Instance()->GetEntity(playerID); if (!player) return; @@ -576,9 +575,7 @@ void HandlePacketChat(Packet* packet) { } case eChatInternalMessageType::ANNOUNCEMENT: { - CINSTREAM; - LWOOBJID header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; std::string title; std::string msg; @@ -615,11 +612,10 @@ void HandlePacketChat(Packet* packet) { } case eChatInternalMessageType::MUTE_UPDATE: { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerId; time_t expire = 0; inStream.Read(playerId); - inStream.Read(playerId); inStream.Read(expire); auto* entity = EntityManager::Instance()->GetEntity(playerId); @@ -634,9 +630,7 @@ void HandlePacketChat(Packet* packet) { } case eChatInternalMessageType::TEAM_UPDATE: { - CINSTREAM; - LWOOBJID header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; LWOOBJID teamID = 0; char lootOption = 0; @@ -1213,10 +1207,8 @@ void HandlePacket(Packet* packet) { case eWorldMessageType::ROUTE_PACKET: { //Yeet to chat - CINSTREAM; - uint64_t header = 0; + CINSTREAM_SKIP_HEADER; uint32_t size = 0; - inStream.Read(header); inStream.Read(size); if (size > 20000) { diff --git a/tests/dCommonTests/CMakeLists.txt b/tests/dCommonTests/CMakeLists.txt index dd282cb5..444afbdd 100644 --- a/tests/dCommonTests/CMakeLists.txt +++ b/tests/dCommonTests/CMakeLists.txt @@ -1,5 +1,6 @@ set(DCOMMONTEST_SOURCES "AMFDeserializeTests.cpp" + "HeaderSkipTest.cpp" "TestLDFFormat.cpp" "TestNiPoint3.cpp" "TestEncoding.cpp" diff --git a/tests/dCommonTests/HeaderSkipTest.cpp b/tests/dCommonTests/HeaderSkipTest.cpp new file mode 100644 index 00000000..a8f78078 --- /dev/null +++ b/tests/dCommonTests/HeaderSkipTest.cpp @@ -0,0 +1,37 @@ +#include + +#include "dCommonDependencies.h" +#include "dCommonVars.h" +#include "BitStream.h" + +#define PacketUniquePtr std::unique_ptr + +TEST(dCommonTests, HeaderSkipExcessTest) { + PacketUniquePtr packet = std::make_unique(); + unsigned char headerAndData[] = { 0x53, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 }; // positive + packet->data = headerAndData; + packet->length = sizeof(headerAndData); + CINSTREAM_SKIP_HEADER; + ASSERT_EQ(inStream.GetNumberOfUnreadBits(), 64); + ASSERT_EQ(inStream.GetNumberOfBitsAllocated(), 128); +} + +TEST(dCommonTests, HeaderSkipExactDataTest) { + PacketUniquePtr packet = std::make_unique(); + unsigned char header[] = { 0x53, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00 }; // positive + packet->data = header; + packet->length = sizeof(header); + CINSTREAM_SKIP_HEADER; + ASSERT_EQ(inStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(inStream.GetNumberOfBitsAllocated(), 64); +} + +TEST(dCommonTests, HeaderSkipNotEnoughDataTest) { + PacketUniquePtr packet = std::make_unique(); + unsigned char notEnoughData[] = { 0x53, 0x02, 0x00, 0x07, 0x00, 0x00 }; // negative + packet->data = notEnoughData; + packet->length = sizeof(notEnoughData); + CINSTREAM_SKIP_HEADER; + ASSERT_EQ(inStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(inStream.GetNumberOfBitsAllocated(), 48); +} From 5c086909ed3776087d9764c4b915aac4eb2651b3 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 8 May 2023 18:36:28 -0700 Subject: [PATCH 033/116] Ready for implementation --- dGame/LeaderboardManager.cpp | 524 ++++++++++++++------------ dGame/LeaderboardManager.h | 86 ++++- tests/dGameTests/LeaderboardTests.cpp | 26 +- 3 files changed, 352 insertions(+), 284 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 44ef17cc..d6713518 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -40,12 +40,12 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) { leaderboard << "Result[0].Index=0:RowNumber\n"; // "Primary key" leaderboard << "Result[0].RowCount=1:" << entries.size() << '\n'; // number of rows - int32_t index = 0; + int32_t rowNumber = 0; for (auto& entry : entries) { - for (auto data : entry) { - WriteLeaderboardRow(leaderboard, index, data); + for (auto* data : entry) { + WriteLeaderboardRow(leaderboard, rowNumber, data); } - index++; + rowNumber++; } // Serialize the thing to a BitStream @@ -62,187 +62,65 @@ bool Leaderboard::GetRankingQuery(std::string& lookupReturn) const { } } -void Leaderboard::SetupLeaderboard() { - std::string queryBase = - R"QUERY( - WITH leaderboardsRanked AS ( - SELECT leaderboard.*, charinfo.name, - RANK() OVER - ( - ORDER BY %s, UNIX_TIMESTAMP(last_played) ASC, id DESC - ) AS ranking - FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id - WHERE game_id = ? %s - ), - myStanding AS ( - SELECT - ranking as myRank - FROM leaderboardsRanked - WHERE id = ? - ), - lowestRanking AS ( - SELECT MAX(ranking) AS lowestRank - FROM leaderboardsRanked - ) - SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking - WHERE leaderboardsRanked.ranking - BETWEEN - LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, 1), lowestRanking.lowestRank - 10) - AND - LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank) - ORDER BY ranking ASC;)QUERY"; - // Setup query based on activity. - // Where clause will vary based on what query we are doing - // Get base based on InfoType - // Fill in base with arguments based on leaderboard type - // If this is a friends query we need to join another table and add even more to the where clause. +void Leaderboard::QueryToLdf(std::unique_ptr& rows) { + if (rows->rowsCount() == 0) return; - const char* friendsQuery = - " AND (character_id IN (SELECT fr.requested_player FROM (SELECT CASE " - "WHEN player_id = ? THEN friend_id " - "WHEN friend_id = ? THEN player_id " - "END AS requested_player FROM friends) AS fr " - "JOIN charinfo AS ci ON ci.id = fr.requested_player " - "WHERE fr.requested_player IS NOT NULL) OR character_id = ?) "; - - std::string orderBase; - std::string selectBase; - switch (leaderboardType) { - case Type::ShootingGallery: { - orderBase = "score DESC, streak DESC, hitPercentage DESC"; - selectBase = "hitPercentage, score, streak"; - break; - } - case Type::Racing: - orderBase = "bestTime ASC, bestLapTime ASC, numWins DESC"; - selectBase = "bestLapTime, bestTime, numWins"; - break; - case Type::UnusedLeaderboard4: - orderBase = "score DESC"; - selectBase = "score"; - break; - case Type::MonumentRace: - orderBase = "bestTime ASC"; - selectBase = "bestTime"; - break; - case Type::FootRace: - orderBase = "bestTime DESC"; - selectBase = "bestTime"; - break; - case Type::Survival: - orderBase = "score DESC, bestTime DESC"; - selectBase = "score, bestTime"; - // If the config option default_survival_scoring is 1, reverse the order of the points and time columns - break; - case Type::SurvivalNS: - orderBase = "bestTime DESC, score DESC"; - selectBase = "bestTime, score"; - break; - case Type::Donations: - orderBase = "score DESC"; - selectBase = "score"; - break; - case Type::None: - Game::logger->Log("LeaderboardManager", "Attempting to get leaderboard for type none. Is this intended?"); - // This type is included here simply to resolve a compiler warning on mac about unused enum types - break; - } - - constexpr uint16_t STRING_LENGTH = 1526; - char lookupBuffer[STRING_LENGTH]; - if (this->infoType == InfoType::Friends) snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), friendsQuery, selectBase.c_str()); - else snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), "", selectBase.c_str()); - - std::string baseLookupStr; - char baseRankingBuffer[STRING_LENGTH]; - bool neededFormatting = GetRankingQuery(baseLookupStr); - if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.c_str()); - else std::copy(baseLookupStr.begin(), baseLookupStr.end() + 1, baseRankingBuffer); - - Game::logger->Log("LeaderboardManager", "lookup query is %s", baseRankingBuffer); - std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseRankingBuffer)); - baseQuery->setInt(1, this->gameID); - if (!neededFormatting) { - baseQuery->setInt(2, this->relatedPlayer); - } - - std::unique_ptr baseResult(baseQuery->executeQuery()); - if (!baseResult->next()) return; - // Get the ID of the row fetched. - uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); - - // create and execute query here - Game::logger->Log("LeaderboardManager", "filled in query is %s %i %i %i", lookupBuffer, this->gameID, this->relatedPlayer, relatedPlayerLeaderboardId); - std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); - query->setInt(1, this->gameID); - if (this->infoType == InfoType::Friends) { - query->setInt(2, this->relatedPlayer); - query->setInt(3, this->relatedPlayer); - query->setInt(4, this->relatedPlayer); - query->setInt(5, relatedPlayerLeaderboardId); - } else { - query->setInt(2, relatedPlayerLeaderboardId); - } - std::unique_ptr result(query->executeQuery()); - - if (result->rowsCount() == 0) return; - - this->entries.reserve(result->rowsCount()); - while (result->next()) { + this->entries.reserve(rows->rowsCount()); + while (rows->next()) { constexpr int32_t MAX_NUM_DATA_PER_ROW = 9; this->entries.push_back(std::vector()); auto& entry = this->entries.back(); entry.reserve(MAX_NUM_DATA_PER_ROW); - entry.push_back(new LDFData(u"CharacterID", result->getInt("character_id"))); - entry.push_back(new LDFData(u"LastPlayed", result->getUInt64("lastPlayed"))); + entry.push_back(new LDFData(u"CharacterID", rows->getInt("character_id"))); + entry.push_back(new LDFData(u"LastPlayed", rows->getUInt64("lastPlayed"))); entry.push_back(new LDFData(u"NumPlayed", 1)); - entry.push_back(new LDFData(u"name", GeneralUtils::ASCIIToUTF16(result->getString("name").c_str()))); - entry.push_back(new LDFData(u"RowNumber", result->getInt("ranking"))); + entry.push_back(new LDFData(u"name", GeneralUtils::ASCIIToUTF16(rows->getString("name").c_str()))); + entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); switch (leaderboardType) { case Type::ShootingGallery: - entry.push_back(new LDFData(u"HitPercentage", result->getDouble("hitPercentage"))); + entry.push_back(new LDFData(u"HitPercentage", rows->getDouble("hitPercentage"))); // HitPercentage:3 between 0 and 1 - entry.push_back(new LDFData(u"Score", result->getInt("score"))); + entry.push_back(new LDFData(u"Score", rows->getInt("score"))); // Score:1 - entry.push_back(new LDFData(u"Streak", result->getInt("streak"))); + entry.push_back(new LDFData(u"Streak", rows->getInt("streak"))); // Streak:1 break; case Type::Racing: - entry.push_back(new LDFData(u"BestLapTime", result->getDouble("bestLapTime"))); + entry.push_back(new LDFData(u"BestLapTime", rows->getDouble("bestLapTime"))); // BestLapTime:3 - entry.push_back(new LDFData(u"BestTime", result->getDouble("bestTime"))); + entry.push_back(new LDFData(u"BestTime", rows->getDouble("bestTime"))); // BestTime:3 entry.push_back(new LDFData(u"License", 1)); // License:1 - 1 if player has completed mission 637 and 0 otherwise - entry.push_back(new LDFData(u"NumWins", result->getInt("numWins"))); + entry.push_back(new LDFData(u"NumWins", rows->getInt("numWins"))); // NumWins:1 break; case Type::UnusedLeaderboard4: - entry.push_back(new LDFData(u"Score", result->getInt("score"))); + entry.push_back(new LDFData(u"Score", rows->getInt("score"))); // Points:1 break; case Type::MonumentRace: - entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); // Time:1(?) break; case Type::FootRace: - entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); // Time:1 break; case Type::Survival: - entry.push_back(new LDFData(u"Score", result->getInt("score"))); + entry.push_back(new LDFData(u"Score", rows->getInt("score"))); // Points:1 - entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); // Time:1 break; case Type::SurvivalNS: - entry.push_back(new LDFData(u"Score", result->getInt("score"))); + entry.push_back(new LDFData(u"Score", rows->getInt("score"))); // Wave:1 - entry.push_back(new LDFData(u"Time", result->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); // Time:1 break; case Type::Donations: - entry.push_back(new LDFData(u"Score", result->getInt("score"))); + entry.push_back(new LDFData(u"Score", rows->getInt("score"))); // Score:1 break; case Type::None: @@ -252,11 +130,202 @@ void Leaderboard::SetupLeaderboard() { break; } } - for (auto& entry : entries) { - for (auto data : entry) { - Game::logger->Log("LeaderboardManager", "entry is %s", data->GetString().c_str()); - } +} + +std::string Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { + std::string columns; + switch (leaderboardType) { + case Type::ShootingGallery: + columns = "hitPercentage, score, streak"; + break; + case Type::Racing: + columns = "bestLapTime, bestTime, numWins"; + break; + case Type::UnusedLeaderboard4: + columns = "score"; + break; + case Type::MonumentRace: + columns = "bestTime"; + break; + case Type::FootRace: + columns = "bestTime"; + break; + case Type::Survival: + columns = "bestTime, score"; + break; + case Type::SurvivalNS: + columns = "bestTime, score"; + break; + case Type::Donations: + columns = "score"; + break; + case Type::None: + // This type is included here simply to resolve a compiler warning on mac about unused enum types + break; } + return columns; +} + +std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { + std::string columns; + switch (leaderboardType) { + case Type::ShootingGallery: + columns = "hitPercentage=%f, score=%i, streak=%i"; + break; + case Type::Racing: + columns = "bestLapTime=%i, bestTime=%i, numWins=numWins + %i"; + break; + case Type::UnusedLeaderboard4: + columns = "score=%i"; + break; + case Type::MonumentRace: + columns = "bestTime=%i"; + break; + case Type::FootRace: + columns = "bestTime=%i"; + break; + case Type::Survival: + columns = "bestTime=%i, score=%i"; + break; + case Type::SurvivalNS: + columns = "bestTime=%i, score=%i"; + break; + case Type::Donations: + columns = "score=%i"; + break; + case Type::None: + // This type is included here simply to resolve a compiler warning on mac about unused enum types + break; + } + return columns; +} + +std::string Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { + std::string orderBase; + switch (leaderboardType) { + case Type::ShootingGallery: + orderBase = "score DESC, streak DESC, hitPercentage DESC"; + break; + case Type::Racing: + orderBase = "bestTime ASC, bestLapTime ASC, numWins DESC"; + break; + case Type::UnusedLeaderboard4: + orderBase = "score DESC"; + break; + case Type::MonumentRace: + orderBase = "bestTime ASC"; + break; + case Type::FootRace: + orderBase = "bestTime DESC"; + break; + case Type::Survival: + orderBase = "score DESC, bestTime DESC"; + break; + case Type::SurvivalNS: + orderBase = "bestTime DESC, score DESC"; + break; + case Type::Donations: + orderBase = "score DESC"; + break; + case Type::None: + // This type is included here simply to resolve a compiler warning on mac about unused enum types + break; + } + return orderBase; +} + +void Leaderboard::SetupLeaderboard() { + std::string queryBase = + R"QUERY( + WITH leaderboardsRanked AS ( + SELECT leaderboard.*, charinfo.name, + RANK() OVER + ( + ORDER BY %s, UNIX_TIMESTAMP(last_played) ASC, id DESC + ) AS ranking + FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id + WHERE game_id = ? %s + ), + myStanding AS ( + SELECT + ranking as myRank + FROM leaderboardsRanked + WHERE id = ? + ), + lowestRanking AS ( + SELECT MAX(ranking) AS lowestRank + FROM leaderboardsRanked + ) + SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking + WHERE leaderboardsRanked.ranking + BETWEEN + LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, 1), lowestRanking.lowestRank - 10) + AND + LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank) + ORDER BY ranking ASC; + )QUERY"; + + const char* friendsQuery = + R"QUERY( AND ( + character_id IN ( + SELECT fr.requested_player FROM ( + SELECT CASE + WHEN player_id = ? THEN friend_id + WHEN friend_id = ? THEN player_id + END AS requested_player + FROM friends + ) AS fr + JOIN charinfo AS ci + ON ci.id = fr.requested_player + WHERE fr.requested_player IS NOT NULL + ) + OR character_id = ? + ) + )QUERY"; + + std::string orderBase = GetOrdering(this->leaderboardType); + std::string selectBase = GetColumns(this->leaderboardType); + + constexpr uint16_t STRING_LENGTH = 1526; + char lookupBuffer[STRING_LENGTH]; + // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. + if (this->infoType == InfoType::Friends) snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), friendsQuery, selectBase.c_str()); + else snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), "", selectBase.c_str()); + + std::string baseLookupStr; + char baseRankingBuffer[STRING_LENGTH]; + bool neededFormatting = GetRankingQuery(baseLookupStr); + + // If we need to format the base ranking query, do so, otherwise just copy the query since it's already formatted. + if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.c_str()); + else std::copy(baseLookupStr.begin(), baseLookupStr.end() + 1, baseRankingBuffer); + + std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseRankingBuffer)); + baseQuery->setInt(1, this->gameID); + if (!neededFormatting) { + baseQuery->setInt(2, this->relatedPlayer); + } + + std::unique_ptr baseResult(baseQuery->executeQuery()); + if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game. + + uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); + + // Create and execute the actual save here + std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); + + query->setInt(1, this->gameID); + if (this->infoType == InfoType::Friends) { + query->setInt(2, this->relatedPlayer); + query->setInt(3, this->relatedPlayer); + query->setInt(4, this->relatedPlayer); + query->setInt(5, relatedPlayerLeaderboardId); + } else { + query->setInt(2, relatedPlayerLeaderboardId); + } + + std::unique_ptr result(query->executeQuery()); + QueryToLdf(result); } void Leaderboard::Send(LWOOBJID targetID) const { @@ -292,56 +361,9 @@ std::string FormatInsert(const std::string& columns, const std::string& format, return finishedQuery; } -void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args) { - std::string insertStatement; - std::string selectedColumns; - std::string insertFormat; - std::va_list argsCopy; - va_copy(argsCopy, args); - - switch (leaderboardType) { - case Leaderboard::Type::ShootingGallery: { - selectedColumns = "score, hitPercentage, streak"; - insertFormat = "score=%i, hitPercentage=%f, streak=%i"; - break; - } - case Leaderboard::Type::Racing: { - selectedColumns = "bestLapTime, bestTime, numWins"; - insertFormat = "bestLapTime=%f, bestTime=%f, numWins=%i"; - break; - } - case Leaderboard::Type::UnusedLeaderboard4: { - selectedColumns = "score"; - insertFormat = "score=%i"; - break; - } - case Leaderboard::Type::MonumentRace: - case Leaderboard::Type::FootRace: { - selectedColumns = "bestTime"; - insertFormat = "bestTime=%i"; - break; - } - case Leaderboard::Type::Survival: { - selectedColumns = "score, bestTime"; - insertFormat = "score=%i, bestTime=%i"; - break; - } - case Leaderboard::Type::SurvivalNS: { - selectedColumns = "bestTime, score"; - insertFormat = "bestTime=%i, score=%i"; - break; - } - case Leaderboard::Type::Donations: { - selectedColumns = "score"; - insertFormat = "score=%i"; - break; - } - case Leaderboard::Type::None: - default: { - Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); - return; - } - } +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list activityScore) { + std::string selectedColumns = Leaderboard::GetColumns(leaderboardType); + std::string insertFormat = Leaderboard::GetInsertFormat(leaderboardType); const char* lookup = "SELECT %s FROM leaderboard WHERE character_id = ? AND game_id = ?;"; constexpr uint16_t STRING_LENGTH = 400; @@ -353,6 +375,8 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead query->setInt(2, gameID); std::unique_ptr myScoreResult(query->executeQuery()); + std::va_list argsCopy; + va_copy(argsCopy, activityScore); std::string saveQuery; if (myScoreResult->next()) { switch (leaderboardType) { @@ -369,74 +393,78 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t streak; streak = va_arg(argsCopy, int32_t); - if ( - score > oldScore || // If score is better + if (score > oldScore || // If score is better (score == oldScore && hitPercentage > oldHitPercentage) || // or if the score is tied and the hitPercentage is better (score == oldScore && hitPercentage == oldHitPercentage && streak > oldStreak)) { // or if the score and hitPercentage are tied and the streak is better - saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); } break; } case Leaderboard::Type::Racing: { - float oldLapTime = myScoreResult->getFloat("bestLapTime"); - float lapTime; - lapTime = va_arg(argsCopy, double); + uint32_t oldLapTime = myScoreResult->getFloat("bestLapTime"); + uint32_t lapTime; + lapTime = va_arg(argsCopy, uint32_t); - float oldTime = myScoreResult->getFloat("bestTime"); - float newTime; - newTime = va_arg(argsCopy, double); + uint32_t oldTime = myScoreResult->getFloat("bestTime"); + uint32_t newTime; + newTime = va_arg(argsCopy, uint32_t); - int32_t oldNumWins = myScoreResult->getInt("numWins"); bool won; won = va_arg(argsCopy, int32_t); - // Compare bestTime, if LOWER save - // Compare bestLapTime, if LOWER save - // Increment numWins if player won + + if (newTime < oldTime || + (newTime == oldTime && lapTime < oldLapTime)) { + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); + } else if (won) { + std::unique_ptr incrementStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;")); + incrementStatement->setInt(1, playerID); + incrementStatement->setInt(2, gameID); + incrementStatement->executeUpdate(); + } break; } case Leaderboard::Type::UnusedLeaderboard4: { int32_t oldScore = myScoreResult->getInt("score"); int32_t points; points = va_arg(argsCopy, int32_t); + if (points > oldScore) { - saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); } - // Compare score, if HIGHER save break; } case Leaderboard::Type::MonumentRace: { int32_t oldTime = myScoreResult->getInt("bestTime"); int32_t time; time = va_arg(argsCopy, int32_t); + if (time < oldTime) { - saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); } - // Compare time, if LOWER save break; } case Leaderboard::Type::FootRace: { int32_t oldTime = myScoreResult->getInt("bestTime"); int32_t time; time = va_arg(argsCopy, int32_t); + if (time < oldTime) { - saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); } - // Compare time, if HIGHER save break; } case Leaderboard::Type::Survival: { + int32_t oldTime = myScoreResult->getInt("bestTime"); + int32_t time; + time = va_arg(argsCopy, int32_t); + int32_t oldPoints = myScoreResult->getInt("score"); int32_t points; points = va_arg(argsCopy, int32_t); - int32_t oldTime = myScoreResult->getInt("bestTime"); - int32_t time; - time = va_arg(argsCopy, int32_t); if (points > oldPoints || (points == oldPoints && time < oldTime)) { - saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); } - // Compare points, if HIGHER save, if TIED compare time, if LOWER save - // If classic_survival_scoring is 1, reverse the order of the points and time columns break; } case Leaderboard::Type::SurvivalNS: { @@ -447,52 +475,48 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t oldWave = myScoreResult->getInt("score"); int32_t wave; wave = va_arg(argsCopy, int32_t); + if (time < oldTime || (time == oldTime && wave > oldWave)) { - saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); } - // Compare wave, if HIGHER save, if TIED compare time, if LOWER save break; } case Leaderboard::Type::Donations: { int32_t oldScore = myScoreResult->getInt("score"); int32_t score; score = va_arg(argsCopy, int32_t); - if (score > oldScore) { - saveQuery = FormatInsert(selectedColumns, insertFormat, args, true); - } - // Compare score, if HIGHER save - break; - } - case Leaderboard::Type::None: { - // This type is included here simply to resolve a compiler warning on mac about unused enum types - Game::logger->Log("LeaderboardManager", "Warning: Saving score for leaderboard of type None. Are you sure this is intended?"); - break; - } + if (score > oldScore) { + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); + } + break; + } + case Leaderboard::Type::None: default: Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); break; } } else { - saveQuery = FormatInsert(selectedColumns, insertFormat, argsCopy, false); + saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, false); } + std::unique_ptr saveStatement; if (!saveQuery.empty()) { - Game::logger->Log("LeaderboardManager", "%s", saveQuery.c_str()); - std::unique_ptr insertQuery(Database::CreatePreppedStmt(saveQuery)); - insertQuery->setInt(1, playerID); - insertQuery->setInt(2, gameID); - insertQuery->execute(); + Game::logger->Log("LeaderboardManager", "Executing update with query %s", saveQuery.c_str()); + std::unique_ptr updateStatement(Database::CreatePreppedStmt(saveQuery)); + saveStatement = std::move(updateStatement); } else { Game::logger->Log("LeaderboardManager", "No new score to save, incrementing numTimesPlayed"); // Increment the numTimes this player has played this game. - std::unique_ptr incrementStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;")); - incrementStatement->setInt(1, playerID); - incrementStatement->setInt(2, gameID); - incrementStatement->executeUpdate(); + std::unique_ptr updateStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;")); + saveStatement = std::move(updateStatement); } + saveStatement->setInt(1, playerID); + saveStatement->setInt(2, gameID); + saveStatement->execute(); va_end(argsCopy); } +// Done void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 898dfbbb..c6c9b0e1 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -7,7 +7,11 @@ #include "dCommonVars.h" #include "LDFFormat.h" -namespace RakNet{ +namespace sql { + class ResultSet; +}; + +namespace RakNet { class BitStream; }; @@ -43,7 +47,7 @@ public: /** * Serialize the Leaderboard to a BitStream - * + * * Expensive! Leaderboards are very string intensive so be wary of performatnce calling this method. */ void Serialize(RakNet::BitStream* bitStream); @@ -51,9 +55,9 @@ public: /** * Based on the associated gameID, return true if the score provided * is better than the current entries' score - * @param score - * @return true - * @return false + * @param score + * @return true + * @return false */ bool IsScoreBetter(const uint32_t score) const { return false; }; @@ -66,11 +70,21 @@ public: * Sends the leaderboard to the client specified by targetID. */ void Send(LWOOBJID targetID) const; + + // Helper functions to get the columns, ordering and insert format for a leaderboard + static std::string GetColumns(Type leaderboardType); + static std::string GetInsertFormat(Type leaderboardType); + static std::string GetOrdering(Type leaderboardType); private: inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data); // Returns true if the string needs formatting bool GetRankingQuery(std::string& lookupReturn) const; + + // Takes the resulting query from a leaderboard lookup and converts it to the LDF we need + // to send it to a client. + void QueryToLdf(std::unique_ptr& rows); + LeaderboardEntries entries; LWOOBJID relatedPlayer; GameID gameID; @@ -79,23 +93,61 @@ private: bool weekly; }; -class LeaderboardManager: public Singleton { +class LeaderboardManager : public Singleton { typedef std::map LeaderboardCache; public: - void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, - LWOOBJID playerID = LWOOBJID_EMPTY); - /** - * @brief Public facing Score saving method. This method is simply a wrapper to ensure va_end is called properly. - * - * @param playerID The player whos score to save - * @param gameID The ID of the game which was played - * @param argumentCount The number of arguments in the va_list - * @param ... - */ - void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...); + void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID = LWOOBJID_EMPTY); + + // Saves a score to the database for the Racing minigame + inline void SaveRacingScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestLapTime, uint32_t bestTime, bool won) { + SaveScore(playerID, gameID, Leaderboard::Racing, 3, bestLapTime, bestTime, won); + }; + + // Saves a score to the database for the Shooting Gallery minigame + inline void SaveShootingGalleryScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, float hitPercentage, uint32_t streak) { + SaveScore(playerID, gameID, Leaderboard::ShootingGallery, 3, score, hitPercentage, streak); + }; + + // Saves a score to the database for the footrace minigame + inline void SaveFootRaceScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestTime) { + SaveScore(playerID, gameID, Leaderboard::FootRace, 1, bestTime); + }; + + // Saves a score to the database for the Monument footrace minigame + inline void SaveMonumentRaceScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestTime) { + SaveScore(playerID, gameID, Leaderboard::MonumentRace, 1, bestTime); + }; + + // Saves a score to the database for the Survival minigame + inline void SaveSurvivalScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, uint32_t waves) { + SaveScore(playerID, gameID, Leaderboard::Survival, 2, score, waves); + }; + + // Saves a score to the database for the SurvivalNS minigame + // Same as the Survival minigame, but good for explicitness + inline void SaveSurvivalNSScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, uint32_t waves) { + SaveScore(playerID, gameID, Leaderboard::SurvivalNS, 2, score, waves); + }; + + // Saves a score to the database for the Donations minigame + inline void SaveDonationsScore(const LWOOBJID& playerID, GameID gameID, uint32_t score) { + SaveScore(playerID, gameID, Leaderboard::Donations, 1, score); + }; + private: void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args); void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); + + /** + * @brief Public facing Score saving method. This method is simply a wrapper to ensure va_end is called properly. + * + * @param playerID The player whos score to save + * @param gameID The ID of the game which was played + * @param argumentCount The number of arguments in the va_list + * @param ... The score to save + */ + void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...); + Leaderboard::Type GetLeaderboardType(const GameID gameID); LeaderboardCache leaderboardCache; }; diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index a4b7b9c0..fbe76df4 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -73,21 +73,13 @@ protected: TEST_F(LeaderboardTests, LeaderboardSpeedTest) { RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); - // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); - // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); - LeaderboardManager::Instance().SaveScore(14231, 1864, Leaderboard::Type::ShootingGallery, 3, 53002, 15.0f, 100); - // RunTests(0, Leaderboard::Type::Racing); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Racing, 3, 259.0f, 250.0f, true); - // RunTests(0, Leaderboard::Type::MonumentRace); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::MonumentRace, 1, 149); - // RunTests(0, Leaderboard::Type::FootRace); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::FootRace, 1, 151); - // RunTests(0, Leaderboard::Type::UnusedLeaderboard4); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::UnusedLeaderboard4, 1, 101); - // RunTests(0, Leaderboard::Type::Survival); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Survival, 2, 3001, 15); - // RunTests(0, Leaderboard::Type::SurvivalNS); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::SurvivalNS, 2, 301, 15); - // RunTests(0, Leaderboard::Type::Donations); - LeaderboardManager::Instance().SaveScore(14231, 0, Leaderboard::Type::Donations, 1, 300001); + RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); + RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); + LeaderboardManager::Instance().SaveShootingGalleryScore(14231, 1864, 53003, 15.0f, 100); + LeaderboardManager::Instance().SaveRacingScore(14231, 0, 40, 250, true); + LeaderboardManager::Instance().SaveMonumentRaceScore(14231, 0, 148); + LeaderboardManager::Instance().SaveFootRaceScore(14231, 0, 15); + LeaderboardManager::Instance().SaveSurvivalScore(14231, 0, 3002, 15); + LeaderboardManager::Instance().SaveSurvivalNSScore(14231, 0, 302, 15); + LeaderboardManager::Instance().SaveDonationsScore(14231, 0, 300003); } From d98ad4b94f9e2cc23641666c162d5ddca9eae111 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 8 May 2023 19:35:19 -0700 Subject: [PATCH 034/116] Implement leaderboard page offsets --- dCommon/Metrics.cpp | 1 - dGame/LeaderboardManager.cpp | 27 ++++++++++++++++++--------- dGame/LeaderboardManager.h | 4 ++-- dGame/dGameMessages/GameMessages.cpp | 16 ++-------------- dGame/dGameMessages/GameMessages.h | 2 +- 5 files changed, 23 insertions(+), 27 deletions(-) diff --git a/dCommon/Metrics.cpp b/dCommon/Metrics.cpp index 522bcf61..b97b5435 100644 --- a/dCommon/Metrics.cpp +++ b/dCommon/Metrics.cpp @@ -14,7 +14,6 @@ std::vector Metrics::m_Variables = { MetricVariable::CPUTime, MetricVariable::Sleep, MetricVariable::Frame, - MetricVariable::Leaderboard, }; void Metrics::AddMeasurement(MetricVariable variable, int64_t value) { diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d6713518..4b56fb60 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -33,6 +33,9 @@ void Leaderboard::WriteLeaderboardRow(std::ostringstream& leaderboard, const uin } void Leaderboard::Serialize(RakNet::BitStream* bitStream) { + bitStream->Write(gameID); + bitStream->Write(leaderboardType); + std::ostringstream leaderboard; leaderboard << "ADO.Result=7:1\n"; // Unused in 1.10.64, but is in captures @@ -49,7 +52,9 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) { } // Serialize the thing to a BitStream - bitStream->Write(leaderboard.str().c_str(), leaderboard.tellp()); + bitStream->WriteAlignedBytes((const unsigned char*)leaderboard.str().c_str(), leaderboard.tellp()); + bitStream->Write0(); + bitStream->Write0(); } bool Leaderboard::GetRankingQuery(std::string& lookupReturn) const { @@ -234,7 +239,7 @@ std::string Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { return orderBase; } -void Leaderboard::SetupLeaderboard() { +void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { std::string queryBase = R"QUERY( WITH leaderboardsRanked AS ( @@ -259,9 +264,9 @@ void Leaderboard::SetupLeaderboard() { SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking WHERE leaderboardsRanked.ranking BETWEEN - LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, 1), lowestRanking.lowestRank - 10) + LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, %i), lowestRanking.lowestRank - 10) AND - LEAST(GREATEST(myRank + 5, 11), lowestRanking.lowestRank) + LEAST(GREATEST(myRank + 5, %i), lowestRanking.lowestRank) ORDER BY ranking ASC; )QUERY"; @@ -289,8 +294,14 @@ void Leaderboard::SetupLeaderboard() { constexpr uint16_t STRING_LENGTH = 1526; char lookupBuffer[STRING_LENGTH]; // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. - if (this->infoType == InfoType::Friends) snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), friendsQuery, selectBase.c_str()); - else snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), orderBase.c_str(), "", selectBase.c_str()); + if (this->infoType == InfoType::Friends) { + snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), + orderBase.c_str(), friendsQuery, selectBase.c_str(), resultStart + 1, resultEnd + 1); + } + else { + snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), + orderBase.c_str(), "", selectBase.c_str(), resultStart + 1, resultEnd + 1); + } std::string baseLookupStr; char baseRankingBuffer[STRING_LENGTH]; @@ -328,7 +339,7 @@ void Leaderboard::SetupLeaderboard() { QueryToLdf(result); } -void Leaderboard::Send(LWOOBJID targetID) const { +void Leaderboard::Send(LWOOBJID targetID) { auto* player = EntityManager::Instance()->GetEntity(relatedPlayer); if (player != nullptr) { GameMessages::SendActivitySummaryLeaderboardData(targetID, this, player->GetSystemAddress()); @@ -516,14 +527,12 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead va_end(argsCopy); } -// Done void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(); leaderboard.Send(targetID); } -// Done Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { auto lookup = leaderboardCache.find(gameID); if (lookup != leaderboardCache.end()) return lookup->second; diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index c6c9b0e1..3d3e4b70 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -64,12 +64,12 @@ public: /** * Builds the leaderboard from the database based on the associated gameID */ - void SetupLeaderboard(); + void SetupLeaderboard(uint32_t resultStart = 0, uint32_t resultEnd = 10); /** * Sends the leaderboard to the client specified by targetID. */ - void Send(LWOOBJID targetID) const; + void Send(LWOOBJID targetID); // Helper functions to get the columns, ordering and insert format for a leaderboard static std::string GetColumns(Type leaderboardType); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index b999eb61..ec24248b 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1631,26 +1631,14 @@ void GameMessages::HandleActivitySummaryLeaderboardData(RakNet::BitStream* instr Game::logger->Log("AGS", "We got mail!"); } -void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, const Leaderboard* leaderboard, const SystemAddress& sysAddr) { +void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, Leaderboard* leaderboard, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); bitStream.Write(GAME_MSG::GAME_MSG_SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA); - throw ""; - //bitStream.Write(leaderboard->GetGameID()); - //bitStream.Write(leaderboard->GetInfoType()); - // Leaderboard is written back as LDF string - //const auto leaderboardString = leaderboard->ToString(); - //bitStream.Write(leaderboardString.size()); - //for (const auto c : leaderboardString) { - // bitStream.Write(c); - //} - //if (!leaderboardString.empty()) bitStream.Write(uint16_t(0)); - - bitStream.Write0(); - bitStream.Write0(); + leaderboard->Serialize(&bitStream); SEND_PACKET; } diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index ce24a105..7f358f59 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -561,7 +561,7 @@ namespace GameMessages { void SendUpdateReputation(const LWOOBJID objectId, const int64_t reputation, const SystemAddress& sysAddr); // Leaderboards - void SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, const Leaderboard* leaderboard, + void SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, Leaderboard* leaderboard, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS); void HandleActivitySummaryLeaderboardData(RakNet::BitStream* instream, Entity* entity, const SystemAddress& sysAddr); void SendRequestActivitySummaryLeaderboardData(const LWOOBJID& objectID, const LWOOBJID& targetID, From 6c2312fe87c9a514b3b42baccd92be16ea206a08 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 8 May 2023 19:59:10 -0700 Subject: [PATCH 035/116] Implement page fetching --- dGame/LeaderboardManager.cpp | 12 +++++++----- dGame/LeaderboardManager.h | 5 ++++- dGame/dGameMessages/GameMessages.cpp | 8 +++----- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 4b56fb60..c662bd6d 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -240,6 +240,8 @@ std::string Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { } void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { + resultStart++; + resultEnd++; std::string queryBase = R"QUERY( WITH leaderboardsRanked AS ( @@ -296,11 +298,11 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. if (this->infoType == InfoType::Friends) { snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), - orderBase.c_str(), friendsQuery, selectBase.c_str(), resultStart + 1, resultEnd + 1); + orderBase.c_str(), friendsQuery, selectBase.c_str(), resultStart, resultEnd); } else { snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), - orderBase.c_str(), "", selectBase.c_str(), resultStart + 1, resultEnd + 1); + orderBase.c_str(), "", selectBase.c_str(), resultStart, resultEnd); } std::string baseLookupStr; @@ -527,10 +529,10 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead va_end(argsCopy); } -void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID) { +void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, uint32_t resultStart, uint32_t resultEnd) { Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); - leaderboard.SetupLeaderboard(); - leaderboard.Send(targetID); + leaderboard.SetupLeaderboard(resultStart, resultEnd); + leaderboard.Send(playerID); } Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 3d3e4b70..ab70ae88 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -63,6 +63,9 @@ public: /** * Builds the leaderboard from the database based on the associated gameID + * + * @param resultStart The index to start the leaderboard at. Zero indexed. + * @param resultEnd The index to end the leaderboard at. Zero indexed. */ void SetupLeaderboard(uint32_t resultStart = 0, uint32_t resultEnd = 10); @@ -96,7 +99,7 @@ private: class LeaderboardManager : public Singleton { typedef std::map LeaderboardCache; public: - void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID = LWOOBJID_EMPTY); + void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, uint32_t resultStart = 0, uint32_t resultEnd = 10); // Saves a score to the database for the Racing minigame inline void SaveRacingScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestLapTime, uint32_t bestTime, bool won) { diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index ec24248b..55f40037 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1647,8 +1647,8 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream int32_t gameID = 0; if (inStream->ReadBit()) inStream->Read(gameID); - int32_t queryType = 1; - if (inStream->ReadBit()) inStream->Read(queryType); + Leaderboard::InfoType queryType = Leaderboard::InfoType::MyStanding; + if (inStream->ReadBit()) inStream->Read(queryType); int32_t resultsEnd = 10; if (inStream->ReadBit()) inStream->Read(resultsEnd); @@ -1661,9 +1661,7 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream->ReadBit(); - //const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, (InfoType)queryType, weekly, entity->GetObjectID()); - //SendActivitySummaryLeaderboardData(entity->GetObjectID(), leaderboard, sysAddr); - //delete leaderboard; + LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, target, resultsStart, resultsEnd); } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Entity* entity) { From ce931c2cfe2c1e8a6f80953d290b19010bd00a8b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 8 May 2023 22:39:43 -0700 Subject: [PATCH 036/116] Fix erroneous GM message ID (#1076) --- dCommon/dEnums/eGameMessageType.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dCommon/dEnums/eGameMessageType.h b/dCommon/dEnums/eGameMessageType.h index 247ee5e2..051a5ae8 100644 --- a/dCommon/dEnums/eGameMessageType.h +++ b/dCommon/dEnums/eGameMessageType.h @@ -273,7 +273,7 @@ enum class eGameMessageType : uint16_t { TEAM_SET_LEADER = 1557, TEAM_INVITE_CONFIRM = 1558, TEAM_GET_STATUS_RESPONSE = 1559, - TEAM_ADD_PLAYER = 1526, + TEAM_ADD_PLAYER = 1562, TEAM_REMOVE_PLAYER = 1563, START_CELEBRATION_EFFECT = 1618, ADD_BUFF = 1647, From 4ff5afd9f7ea5d4df732256351ca01b45fdaa3c7 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 9 May 2023 00:40:00 -0500 Subject: [PATCH 037/116] Fix race exit dialogue always exiting (#1077) Fixes #1048 Tested that closing the dialog via esc, the x in the top right, or the big red x doesn't exit the race Tested that the green check button does exit the race --- dGame/dComponents/RacingControlComponent.cpp | 5 ++--- dGame/dComponents/RacingControlComponent.h | 7 ++++++- dGame/dGameMessages/GameMessages.cpp | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 3134d5fe..44c9de36 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -362,8 +362,7 @@ void RacingControlComponent::OnRacingPlayerInfoResetFinished(Entity* player) { } } -void RacingControlComponent::HandleMessageBoxResponse(Entity* player, - const std::string& id) { +void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t button, const std::string& id) { auto* data = GetPlayerData(player->GetObjectID()); if (data == nullptr) { @@ -405,7 +404,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world. } } - } else if (id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") { + } else if (id == "ACT_RACE_EXIT_THE_RACE?" && button == m_ActivityExitConfirm) { auto* vehicle = EntityManager::Instance()->GetEntity(data->vehicleID); if (vehicle == nullptr) { diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index 91ab2fd4..a81121e1 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -144,7 +144,7 @@ public: /** * Invoked when the player responds to the GUI. */ - void HandleMessageBoxResponse(Entity* player, const std::string& id); + void HandleMessageBoxResponse(Entity* player, int32_t button, const std::string& id); /** * Get the racing data from a player's LWOOBJID. @@ -246,4 +246,9 @@ private: float m_EmptyTimer; bool m_SoloRacing; + + /** + * Value for message box response to know if we are exiting the race via the activity dialogue + */ + const int32_t m_ActivityExitConfirm = 1; }; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index caab6459..99b1c67f 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3891,7 +3891,7 @@ void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* auto* racingControlComponent = entity->GetComponent(); if (racingControlComponent != nullptr) { - racingControlComponent->HandleMessageBoxResponse(userEntity, GeneralUtils::UTF16ToWTF8(identifier)); + racingControlComponent->HandleMessageBoxResponse(userEntity, iButton, GeneralUtils::UTF16ToWTF8(identifier)); } for (auto* shootingGallery : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { From fcf5c5ea8a722b63256bed616ab2ac86516ee412 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 9 May 2023 00:06:26 -0700 Subject: [PATCH 038/116] Resolve compiler errors --- dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp | 1 + tests/dGameTests/LeaderboardTests.cpp | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp index 4d1ae5f5..1c3fb830 100644 --- a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp +++ b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp @@ -1,6 +1,7 @@ #include "BaseFootRaceManager.h" #include "EntityManager.h" #include "Character.h" +#include "Entity.h" void BaseFootRaceManager::OnStartup(Entity* self) { // TODO: Add to FootRaceStarter group diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index fbe76df4..b3480f51 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -75,11 +75,4 @@ TEST_F(LeaderboardTests, LeaderboardSpeedTest) { RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); - LeaderboardManager::Instance().SaveShootingGalleryScore(14231, 1864, 53003, 15.0f, 100); - LeaderboardManager::Instance().SaveRacingScore(14231, 0, 40, 250, true); - LeaderboardManager::Instance().SaveMonumentRaceScore(14231, 0, 148); - LeaderboardManager::Instance().SaveFootRaceScore(14231, 0, 15); - LeaderboardManager::Instance().SaveSurvivalScore(14231, 0, 3002, 15); - LeaderboardManager::Instance().SaveSurvivalNSScore(14231, 0, 302, 15); - LeaderboardManager::Instance().SaveDonationsScore(14231, 0, 300003); } From 411c9eaf1f4ddbbc3a8c7fde7c629780db439d6d Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 9 May 2023 00:06:43 -0700 Subject: [PATCH 039/116] Remove dead code --- dGame/LeaderboardManager.h | 50 ++++++-------------------------------- 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index ab70ae88..ce614555 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include "Singleton.h" @@ -38,7 +39,7 @@ public: Survival, SurvivalNS, Donations, - None = UINT_MAX + None }; Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None); @@ -101,46 +102,6 @@ class LeaderboardManager : public Singleton { public: void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, uint32_t resultStart = 0, uint32_t resultEnd = 10); - // Saves a score to the database for the Racing minigame - inline void SaveRacingScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestLapTime, uint32_t bestTime, bool won) { - SaveScore(playerID, gameID, Leaderboard::Racing, 3, bestLapTime, bestTime, won); - }; - - // Saves a score to the database for the Shooting Gallery minigame - inline void SaveShootingGalleryScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, float hitPercentage, uint32_t streak) { - SaveScore(playerID, gameID, Leaderboard::ShootingGallery, 3, score, hitPercentage, streak); - }; - - // Saves a score to the database for the footrace minigame - inline void SaveFootRaceScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestTime) { - SaveScore(playerID, gameID, Leaderboard::FootRace, 1, bestTime); - }; - - // Saves a score to the database for the Monument footrace minigame - inline void SaveMonumentRaceScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestTime) { - SaveScore(playerID, gameID, Leaderboard::MonumentRace, 1, bestTime); - }; - - // Saves a score to the database for the Survival minigame - inline void SaveSurvivalScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, uint32_t waves) { - SaveScore(playerID, gameID, Leaderboard::Survival, 2, score, waves); - }; - - // Saves a score to the database for the SurvivalNS minigame - // Same as the Survival minigame, but good for explicitness - inline void SaveSurvivalNSScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, uint32_t waves) { - SaveScore(playerID, gameID, Leaderboard::SurvivalNS, 2, score, waves); - }; - - // Saves a score to the database for the Donations minigame - inline void SaveDonationsScore(const LWOOBJID& playerID, GameID gameID, uint32_t score) { - SaveScore(playerID, gameID, Leaderboard::Donations, 1, score); - }; - -private: - void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args); - void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); - /** * @brief Public facing Score saving method. This method is simply a wrapper to ensure va_end is called properly. * @@ -151,7 +112,10 @@ private: */ void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...); - Leaderboard::Type GetLeaderboardType(const GameID gameID); - LeaderboardCache leaderboardCache; + static Leaderboard::Type GetLeaderboardType(const GameID gameID); + static LeaderboardCache leaderboardCache; +private: + void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args); + void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); }; From 7a067e7b48c63798fd929703996d89239465c470 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 9 May 2023 01:42:11 -0700 Subject: [PATCH 040/116] Working in game! - Add score saving for races - Fix some bugs - Still work to do. --- dGame/LeaderboardManager.cpp | 34 ++++++++++++------- dGame/dComponents/RacingControlComponent.cpp | 7 ++-- dGame/dGameMessages/GameMessages.cpp | 4 +-- .../02_server/Map/AG/NpcAgCourseStarter.cpp | 3 +- dScripts/ActivityManager.cpp | 27 ++++++++------- dScripts/ActivityManager.h | 1 + .../ai/ACT/FootRace/BaseFootRaceManager.cpp | 1 + 7 files changed, 46 insertions(+), 31 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index c662bd6d..c350dda8 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -16,6 +16,8 @@ #include "CDActivitiesTable.h" #include "Metrics.hpp" +LeaderboardManager::LeaderboardCache LeaderboardManager::leaderboardCache = {}; + Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type leaderboardType) { this->gameID = gameID; this->weekly = weekly; @@ -34,10 +36,10 @@ void Leaderboard::WriteLeaderboardRow(std::ostringstream& leaderboard, const uin void Leaderboard::Serialize(RakNet::BitStream* bitStream) { bitStream->Write(gameID); - bitStream->Write(leaderboardType); + bitStream->Write(infoType); std::ostringstream leaderboard; - + Game::logger->Log("LeaderboardManager", "game is %i info type %i ", gameID, infoType); leaderboard << "ADO.Result=7:1\n"; // Unused in 1.10.64, but is in captures leaderboard << "Result.Count=1:1\n"; // number of results, always 1? leaderboard << "Result[0].Index=0:RowNumber\n"; // "Primary key" @@ -46,13 +48,18 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) { int32_t rowNumber = 0; for (auto& entry : entries) { for (auto* data : entry) { + Game::logger->Log("LeaderboardManager", "writing data %s", data->GetString().c_str()); WriteLeaderboardRow(leaderboard, rowNumber, data); } rowNumber++; } - + Game::logger->Log("LeaderboardManager", "leaderboard is %s", leaderboard.str().c_str()); // Serialize the thing to a BitStream - bitStream->WriteAlignedBytes((const unsigned char*)leaderboard.str().c_str(), leaderboard.tellp()); + uint32_t leaderboardSize = leaderboard.tellp(); + bitStream->Write(leaderboardSize); + // Doing this all in 1 call so there is no possbility of a dangling pointer. + bitStream->WriteAlignedBytes(reinterpret_cast(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboard.tellp() * 2); + if (leaderboardSize > 0) bitStream->Write(0); bitStream->Write0(); bitStream->Write0(); } @@ -80,7 +87,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { entry.push_back(new LDFData(u"LastPlayed", rows->getUInt64("lastPlayed"))); entry.push_back(new LDFData(u"NumPlayed", 1)); entry.push_back(new LDFData(u"name", GeneralUtils::ASCIIToUTF16(rows->getString("name").c_str()))); - entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); + entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); switch (leaderboardType) { case Type::ShootingGallery: entry.push_back(new LDFData(u"HitPercentage", rows->getDouble("hitPercentage"))); @@ -101,7 +108,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { // NumWins:1 break; case Type::UnusedLeaderboard4: - entry.push_back(new LDFData(u"Score", rows->getInt("score"))); + entry.push_back(new LDFData(u"Points", rows->getInt("score"))); // Points:1 break; case Type::MonumentRace: @@ -113,19 +120,19 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { // Time:1 break; case Type::Survival: - entry.push_back(new LDFData(u"Score", rows->getInt("score"))); + entry.push_back(new LDFData(u"Points", rows->getInt("score"))); // Points:1 entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); // Time:1 break; case Type::SurvivalNS: - entry.push_back(new LDFData(u"Score", rows->getInt("score"))); + entry.push_back(new LDFData(u"Wave", rows->getInt("score"))); // Wave:1 entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); // Time:1 break; case Type::Donations: - entry.push_back(new LDFData(u"Score", rows->getInt("score"))); + entry.push_back(new LDFData(u"Points", rows->getInt("score"))); // Score:1 break; case Type::None: @@ -320,11 +327,13 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { } std::unique_ptr baseResult(baseQuery->executeQuery()); + Game::logger->Log("LeaderboardManager", "%s", baseRankingBuffer); if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game. uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); // Create and execute the actual save here + Game::logger->Log("LeaderboardManager", "query is %s", lookupBuffer); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); query->setInt(1, this->gameID); @@ -461,7 +470,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t time; time = va_arg(argsCopy, int32_t); - if (time < oldTime) { + if (time > oldTime) { saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); } break; @@ -507,7 +516,8 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead case Leaderboard::Type::None: default: Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); - break; + va_end(argsCopy); + return; } } else { saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, false); @@ -543,7 +553,7 @@ Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { std::vector activities = activitiesTable->Query([=](const CDActivities& entry) { return (entry.ActivityID == gameID); }); - auto type = activities.empty() ? static_cast(activities.at(0).leaderboardType) : Leaderboard::Type::None; + auto type = !activities.empty() ? static_cast(activities.at(0).leaderboardType) : Leaderboard::Type::None; leaderboardCache.insert_or_assign(gameID, type); return type; } diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 703ec7f3..f74c92fa 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -23,6 +23,7 @@ #include "dConfig.h" #include "Loot.h" #include "eMissionTaskType.h" +#include "LeaderboardManager.h" #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 @@ -391,9 +392,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, } if (id == "rewardButton") { - if (data->collectedRewards) { - return; - } + if (data->collectedRewards) return; data->collectedRewards = true; @@ -401,6 +400,8 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, const auto score = m_LoadedPlayers * 10 + data->finished; LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); + auto leaderboardType = LeaderboardManager::Instance().GetLeaderboardType(m_ActivityID); + LeaderboardManager::Instance().SaveScore(player->GetObjectID(), m_ActivityID, leaderboardType, 3, data->bestLapTime, data->raceTime, data->finished == 1); // Giving rewards GameMessages::SendNotifyRacingClient( diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 55f40037..992311cb 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1639,7 +1639,7 @@ void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, bitStream.Write(GAME_MSG::GAME_MSG_SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA); leaderboard->Serialize(&bitStream); - + PacketUtils::SavePacket("leaderboardData.bin", (const char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed()); SEND_PACKET; } @@ -1661,7 +1661,7 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream->ReadBit(); - LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, target, resultsStart, resultsEnd); + LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), resultsStart, resultsEnd); } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index 7da4ccef..03ed9328 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -96,8 +96,7 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std } EntityManager::Instance()->SerializeEntity(self); - //LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), - // 0, (uint32_t)finish); + // LeaderboardManager::Instance().SaveFootRaceScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), finish); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", scriptedActivityComponent->GetActivityID(), 0, sender->GetObjectID(), diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index acfa5a68..3e039024 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -73,24 +73,27 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const LootGenerator::Instance().GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID)); - // Save the new score to the leaderboard and show the leaderboard to the player - //LeaderboardManager::SaveScore(playerID, gameID, score, value1); - //const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, InfoType::Standings, - // false, player->GetObjectID()); - //GameMessages::SendActivitySummaryLeaderboardData(self->GetObjectID(), leaderboard, player->GetSystemAddress()); - //delete leaderboard; - - // Makes the leaderboard show up for the player - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", - gameID, 0, playerID, "", - player->GetSystemAddress()); - if (sac != nullptr) { sac->PlayerRemove(player->GetObjectID()); } } } +void ActivityManager::SaveScore(Entity* self, LWOOBJID playerID, uint32_t val1, uint32_t val2, uint32_t val3) { + auto* player = EntityManager::Instance()->GetEntity(playerID); + if (!player) return; + + auto* sac = self->GetComponent(); + uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); + // Save the new score to the leaderboard and show the leaderboard to the player + auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); + Game::logger->Log("ActivityManager", "leaderboard type %i %i", leaderboardType, gameID); + LeaderboardManager::Instance().SaveScore(playerID, gameID, leaderboardType, 3, val1, val2, val3); + + // Makes the leaderboard show up for the player + GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", gameID, 0, playerID, "", player->GetSystemAddress()); +} + bool ActivityManager::TakeActivityCost(const Entity* self, const LWOOBJID playerID) { auto* sac = self->GetComponent(); if (sac == nullptr) diff --git a/dScripts/ActivityManager.h b/dScripts/ActivityManager.h index 640cf4bf..633fd5d8 100644 --- a/dScripts/ActivityManager.h +++ b/dScripts/ActivityManager.h @@ -18,6 +18,7 @@ public: static bool TakeActivityCost(const Entity* self, LWOOBJID playerID); static uint32_t GetActivityID(const Entity* self); void StopActivity(Entity* self, LWOOBJID playerID, uint32_t score, uint32_t value1 = 0, uint32_t value2 = 0, bool quit = false); + void SaveScore(Entity* self, LWOOBJID playerID, uint32_t val1 = 0, uint32_t val2 = 0, uint32_t val3 = 0); virtual uint32_t CalculateActivityRating(Entity* self, LWOOBJID playerID); static void GetLeaderboardData(Entity* self, LWOOBJID playerID, uint32_t activityID, uint32_t numResults = 0); // void FreezePlayer(Entity *self, const LWOOBJID playerID, const bool state) const; diff --git a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp index 1c3fb830..3efb5ff4 100644 --- a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp +++ b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp @@ -42,6 +42,7 @@ void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, st } StopActivity(self, player->GetObjectID(), 0, param1); + SaveScore(self, player->GetObjectID(), param1, param2, param3); } } } From 3448426cafe75d3d23a7207c901faa9177fcc9be Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 9 May 2023 22:00:13 -0700 Subject: [PATCH 041/116] commit --- dGame/LeaderboardManager.cpp | 10 +++++----- dGame/dGameMessages/GameMessageHandler.cpp | 2 +- dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp | 12 +++++------- dScripts/ActivityManager.cpp | 7 ++++++- dScripts/BaseSurvivalServer.cpp | 1 + dScripts/BaseWavesServer.cpp | 1 + dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 2 +- 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index c350dda8..22e107d0 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -31,7 +31,7 @@ Leaderboard::~Leaderboard() { } void Leaderboard::WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { - leaderboard << "Result[0].Row[" << index << "]." << data->GetString() << '\n'; + leaderboard << "\nResult[0].Row[" << index << "]." << data->GetString(); } void Leaderboard::Serialize(RakNet::BitStream* bitStream) { @@ -40,10 +40,10 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) { std::ostringstream leaderboard; Game::logger->Log("LeaderboardManager", "game is %i info type %i ", gameID, infoType); - leaderboard << "ADO.Result=7:1\n"; // Unused in 1.10.64, but is in captures - leaderboard << "Result.Count=1:1\n"; // number of results, always 1? - leaderboard << "Result[0].Index=0:RowNumber\n"; // "Primary key" - leaderboard << "Result[0].RowCount=1:" << entries.size() << '\n'; // number of rows + leaderboard << "ADO.Result=7:1"; // Unused in 1.10.64, but is in captures + leaderboard << "\nResult.Count=1:1"; // number of results, always 1? + if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key" + leaderboard << "\nResult[0].RowCount=1:" << entries.size(); // number of rows int32_t rowNumber = 0; for (auto& entry : entries) { diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index c0893a09..8a2238c9 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -44,7 +44,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System Entity* entity = EntityManager::Instance()->GetEntity(objectID); User* usr = UserManager::Instance()->GetUser(sysAddr); - + if (messageID != 888) Game::logger->Log("GameMessageHandler", "message %i", messageID); if (!entity) { Game::logger->Log("GameMessageHandler", "Failed to find associated entity (%llu), aborting GM (%X)!", objectID, messageID); diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index 03ed9328..670fd7ee 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -68,15 +68,12 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 } } -void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, - int32_t param3) { +void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { auto* scriptedActivityComponent = self->GetComponent(); - if (scriptedActivityComponent == nullptr) - return; + if (scriptedActivityComponent == nullptr) return; auto* data = scriptedActivityComponent->GetActivityPlayerData(sender->GetObjectID()); - if (data == nullptr) - return; + if (data == nullptr) return; if (args == "course_cancel") { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"cancel_timer", 0, 0, @@ -96,7 +93,8 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std } EntityManager::Instance()->SerializeEntity(self); - // LeaderboardManager::Instance().SaveFootRaceScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), finish); + auto leaderboardType = LeaderboardManager::GetLeaderboardType(scriptedActivityComponent->GetActivityID()); + LeaderboardManager::Instance().SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), leaderboardType, 1, finish); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", scriptedActivityComponent->GetActivityID(), 0, sender->GetObjectID(), diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 3e039024..d9bf56cd 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -120,7 +120,12 @@ uint32_t ActivityManager::GetActivityID(const Entity* self) { } void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID, const uint32_t activityID, uint32_t numResults) { - //LeaderboardManager::SendLeaderboard(activityID, Standings, false, self->GetObjectID(), playerID); + auto* sac = self->GetComponent(); + uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); + // Save the new score to the leaderboard and show the leaderboard to the player + auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); + Game::logger->Log("ActivityManager", "gameID %i", gameID, activityID); + LeaderboardManager::Instance().SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, 0, numResults); } void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval, diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index 3d72628d..ac775787 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -377,6 +377,7 @@ void BaseSurvivalServer::GameOver(Entity* self) { } StopActivity(self, playerID, score, time); + SaveScore(self, playerID, time, score); } state.waveNumber = 1; diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 00340bd0..48144960 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -378,6 +378,7 @@ void BaseWavesServer::GameOver(Entity* self, bool won) { } StopActivity(self, playerID, wave, time, score); + SaveScore(self, playerID, time, wave); } } diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index bdd7a506..ac9d13ee 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -349,7 +349,7 @@ void SGCannon::StartGame(Entity* self) { auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { - GetLeaderboardData(self, player->GetObjectID(), GetActivityID(self)); + GetLeaderboardData(self, player->GetObjectID(), GetActivityID(self), 1); Game::logger->Log("SGCannon", "Sending ActivityStart"); GameMessages::SendActivityStart(self->GetObjectID(), player->GetSystemAddress()); From 4dba8d9225c537c901c0edd5e521d90eadf3fb15 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 9 May 2023 22:21:41 -0700 Subject: [PATCH 042/116] Correct column order --- dGame/LeaderboardManager.cpp | 6 +++--- dGame/LeaderboardManager.h | 2 +- dGame/dGameMessages/GameMessages.cpp | 2 +- dScripts/ActivityManager.cpp | 2 +- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 1 + 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 22e107d0..0c89030e 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -182,7 +182,7 @@ std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { std::string columns; switch (leaderboardType) { case Type::ShootingGallery: - columns = "hitPercentage=%f, score=%i, streak=%i"; + columns = "score=%i, hitPercentage=%f, streak=%i"; break; case Type::Racing: columns = "bestLapTime=%i, bestTime=%i, numWins=numWins + %i"; @@ -539,10 +539,10 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead va_end(argsCopy); } -void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, uint32_t resultStart, uint32_t resultEnd) { +void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart, uint32_t resultEnd) { Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(resultStart, resultEnd); - leaderboard.Send(playerID); + leaderboard.Send(targetID); } Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index ce614555..f84e4228 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -100,7 +100,7 @@ private: class LeaderboardManager : public Singleton { typedef std::map LeaderboardCache; public: - void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, uint32_t resultStart = 0, uint32_t resultEnd = 10); + void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10); /** * @brief Public facing Score saving method. This method is simply a wrapper to ensure va_end is called properly. diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 992311cb..dae0636a 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1661,7 +1661,7 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream->ReadBit(); - LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), resultsStart, resultsEnd); + LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID(), resultsStart, resultsEnd); } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index d9bf56cd..5b361510 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -125,7 +125,7 @@ void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID, // Save the new score to the leaderboard and show the leaderboard to the player auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); Game::logger->Log("ActivityManager", "gameID %i", gameID, activityID); - LeaderboardManager::Instance().SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, 0, numResults); + LeaderboardManager::Instance().SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID(), 0, numResults); } void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval, diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index ac9d13ee..098d9e55 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -565,6 +565,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { LootGenerator::Instance().GiveActivityLoot(player, self, GetGameID(self), self->GetVar(TotalScoreVariable)); StopActivity(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), self->GetVar(MaxStreakVariable), percentage); + SaveScore(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), percentage, self->GetVar(MaxStreakVariable)); self->SetNetworkVar(AudioFinalWaveDoneVariable, true); // Give the player the model rewards they earned From af1abe9e7412d452d1dd3aabb317a6fd9323f2a1 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 10 May 2023 01:32:55 -0700 Subject: [PATCH 043/116] Use only ints --- dGame/LeaderboardManager.cpp | 8 ++++---- dScripts/ActivityManager.cpp | 2 +- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 0c89030e..4b236384 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -182,7 +182,7 @@ std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { std::string columns; switch (leaderboardType) { case Type::ShootingGallery: - columns = "score=%i, hitPercentage=%f, streak=%i"; + columns = "score=%i, hitPercentage=%i, streak=%i"; break; case Type::Racing: columns = "bestLapTime=%i, bestTime=%i, numWins=numWins + %i"; @@ -407,9 +407,9 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead int32_t score; score = va_arg(argsCopy, int32_t); - float oldHitPercentage = myScoreResult->getFloat("hitPercentage"); - float hitPercentage; - hitPercentage = va_arg(argsCopy, double); + int32_t oldHitPercentage = myScoreResult->getFloat("hitPercentage"); + int32_t hitPercentage; + hitPercentage = va_arg(argsCopy, int32_t); int32_t oldStreak = myScoreResult->getInt("streak"); int32_t streak; diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 5b361510..85365e01 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -87,7 +87,7 @@ void ActivityManager::SaveScore(Entity* self, LWOOBJID playerID, uint32_t val1, uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); // Save the new score to the leaderboard and show the leaderboard to the player auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); - Game::logger->Log("ActivityManager", "leaderboard type %i %i", leaderboardType, gameID); + Game::logger->Log("ActivityManager", "leaderboard type %i %i args %i %i %i", leaderboardType, gameID, val1, val2, val3); LeaderboardManager::Instance().SaveScore(playerID, gameID, leaderboardType, 3, val1, val2, val3); // Makes the leaderboard show up for the player diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 098d9e55..3d386775 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -546,13 +546,13 @@ void SGCannon::StopGame(Entity* self, bool cancel) { // The player won, store all the score and send rewards if (!cancel) { - auto percentage = 0; + int32_t percentage = 50; auto misses = self->GetVar(MissesVariable); auto fired = self->GetVar(ShotsFiredVariable); - if (fired > 0) { - percentage = misses / fired; - } + // if (fired > 0) { + // percentage = misses / fired; + // } auto* missionComponent = player->GetComponent(); From b1cd2776fa2528adb4ba8e300ce03798dd6e6fd6 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Wed, 10 May 2023 04:05:56 -0500 Subject: [PATCH 044/116] fix: make exiting the race work (#1082) --- dGame/dComponents/RacingControlComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 44c9de36..4a4ead59 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -404,7 +404,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world. } } - } else if (id == "ACT_RACE_EXIT_THE_RACE?" && button == m_ActivityExitConfirm) { + } else if ((id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") && button == m_ActivityExitConfirm) { auto* vehicle = EntityManager::Instance()->GetEntity(data->vehicleID); if (vehicle == nullptr) { From bf0ae6f181399620cd1e2f266f7092ae29375d9c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Wed, 10 May 2023 07:44:21 -0500 Subject: [PATCH 045/116] fix: add check for arg nums on handlepushobject (#1081) --- dGame/dComponents/TriggerComponent.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index 3f05d805..7adf47a8 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -235,6 +235,8 @@ void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector argArray){ + if (argArray.size() < 3) return; + auto* phantomPhysicsComponent = m_Parent->GetComponent(); if (!phantomPhysicsComponent) { Game::logger->LogDebug("TriggerComponent::HandlePushObject", "Phantom Physics component not found!"); From 5af5b0f1c13942a59d0ec3f93f74345bc3be03f6 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Wed, 10 May 2023 19:26:04 -0500 Subject: [PATCH 046/116] fix: not exiting shooting gallery when clicking activity close button Fixes #436 Fixes crash when replaying as well --- dGame/Entity.cpp | 6 ++ dGame/Entity.h | 1 + dGame/dGameMessages/GameMessageHandler.cpp | 3 + dGame/dGameMessages/GameMessages.cpp | 16 +++++ dGame/dGameMessages/GameMessages.h | 1 + dScripts/CppScripts.h | 9 +++ .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 66 +++++++++---------- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h | 7 +- 8 files changed, 70 insertions(+), 39 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index b9fc79fb..0cc2f070 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1485,6 +1485,12 @@ void Entity::OnChoiceBoxResponse(Entity* sender, int32_t button, const std::u16s } } +void Entity::RequestActivityExit(Entity* sender, LWOOBJID player, bool canceled) { + for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { + script->OnRequestActivityExit(sender, player, canceled); + } +} + void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType) { if (!m_PlayerIsReadyForUpdates) return; diff --git a/dGame/Entity.h b/dGame/Entity.h index b980b179..90f2a34f 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -207,6 +207,7 @@ public: void OnMessageBoxResponse(Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData); void OnChoiceBoxResponse(Entity* sender, int32_t button, const std::u16string& buttonIdentifier, const std::u16string& identifier); + void RequestActivityExit(Entity* sender, LWOOBJID player, bool canceled); void Smash(const LWOOBJID source = LWOOBJID_EMPTY, const eKillType killType = eKillType::VIOLENT, const std::u16string& deathType = u""); void Kill(Entity* murderer = nullptr); diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 50c7876b..be751598 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -677,6 +677,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case eGameMessageType::ZONE_SUMMARY_DISMISSED: GameMessages::HandleZoneSummaryDismissed(inStream, entity); break; + case eGameMessageType::REQUEST_ACTIVITY_EXIT: + GameMessages::HandleRequestActivityExit(inStream, entity); + break; default: // Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID); break; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 99b1c67f..7ebbf761 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -91,6 +91,7 @@ #include "eReplicaComponentType.h" #include "eClientMessageType.h" #include "eGameMessageType.h" +#include "ActivityManager.h" #include "CDComponentsRegistryTable.h" #include "CDObjectsTable.h" @@ -6204,3 +6205,18 @@ void GameMessages::SendShowBillboardInteractIcon(const SystemAddress& sysAddr, L if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST else SEND_PACKET } + +void GameMessages::HandleRequestActivityExit(RakNet::BitStream* inStream, Entity* entity) { + bool canceled = false; + inStream->Read(canceled); + if (!canceled) return; + + LWOOBJID player_id = LWOOBJID_EMPTY; + inStream->Read(player_id); + auto player = EntityManager::Instance()->GetEntity(player_id); + if (!entity || !player) return; + + for (auto* shootingGallery : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { + shootingGallery->RequestActivityExit(entity, player_id, true); + } +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index ce24a105..94b24b65 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -648,6 +648,7 @@ namespace GameMessages { void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); void HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity); + void HandleRequestActivityExit(RakNet::BitStream* inStream, Entity* entity); }; #endif // GAMEMESSAGES_H diff --git a/dScripts/CppScripts.h b/dScripts/CppScripts.h index 4bf3720f..1b9d0591 100644 --- a/dScripts/CppScripts.h +++ b/dScripts/CppScripts.h @@ -349,6 +349,15 @@ namespace CppScripts { * @param itemObjId The items Object ID */ virtual void OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) {}; + + /** + * Handles exiting a scripted activity + * + * @param sender + * @param player the player to remove + * @param canceled if it was done via the cancel button + */ + virtual void OnRequestActivityExit(Entity* sender, LWOOBJID player, bool canceled){}; }; Script* GetScript(Entity* parent, const std::string& scriptName); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 50cd229a..c3274da1 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -135,38 +135,26 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int } } -void SGCannon::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, - const std::u16string& userData) { +void SGCannon::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) { auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); - if (player != nullptr) { - if (button == 1 && identifier == u"Shooting_Gallery_Stop") { + if (!player) return; + + if (identifier == u"Scoreboardinfo") { + GameMessages::SendDisplayMessageBox(player->GetObjectID(), true, + dZoneManager::Instance()->GetZoneControlObject()->GetObjectID(), + u"Shooting_Gallery_Retry", 2, u"Retry?", + u"", player->GetSystemAddress()); + } else { + if ((button == 1 && (identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay")) || identifier == u"SG1" || button == 0) { + if (IsPlayerInActivity(self, player->GetObjectID())) return; + self->SetNetworkVar(ClearVariable, true); + StartGame(self); + } else if (button == 0 && ((identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay"))){ + RemovePlayer(player->GetObjectID()); + UpdatePlayer(self, player->GetObjectID(), true); + } else if (button == 1 && identifier == u"Shooting_Gallery_Exit") { UpdatePlayer(self, player->GetObjectID(), true); RemovePlayer(player->GetObjectID()); - StopGame(self, true); - return; - } - - if (identifier == u"Scoreboardinfo") { - GameMessages::SendDisplayMessageBox(player->GetObjectID(), true, - dZoneManager::Instance()->GetZoneControlObject()->GetObjectID(), - u"Shooting_Gallery_Retry?", 2, u"Retry?", - u"", player->GetSystemAddress()); - } else { - if ((button == 1 && (identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay")) - || identifier == u"SG1" || button == 0) { - - if (identifier == u"RePlay") { - static_cast(player)->SendToZone(1300); - - return; - } - - self->SetNetworkVar(ClearVariable, true); - StartGame(self); - } else if (button == 1 && identifier == u"Shooting_Gallery_Exit") { - UpdatePlayer(self, player->GetObjectID(), true); - RemovePlayer(player->GetObjectID()); - } } } } @@ -267,14 +255,13 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { if (self->GetVar(GameStartedVariable)) { const auto spawnNumber = (uint32_t)std::stoi(name.substr(7)); const auto& activeSpawns = self->GetVar>(ActiveSpawnsVariable); + if (activeSpawns.size() < spawnNumber) { + Game::logger->Log("SGCannon", "Trying to spawn %i when spawns size is only %i", spawnNumber, activeSpawns.size()); + return; + } const auto& toSpawn = activeSpawns.at(spawnNumber); - const auto pathIndex = GeneralUtils::GenerateRandomNumber(0, toSpawn.spawnPaths.size() - 1); - - const auto* path = dZoneManager::Instance()->GetZone()->GetPath( - toSpawn.spawnPaths.at(pathIndex) - ); - + const auto* path = dZoneManager::Instance()->GetZone()->GetPath(toSpawn.spawnPaths.at(pathIndex)); if (!path) { Game::logger->Log("SGCannon", "Path %s at index %i is null", toSpawn.spawnPaths.at(pathIndex).c_str(), pathIndex); return; @@ -341,6 +328,7 @@ SGCannon::OnActivityTimerUpdate(Entity* self, const std::string& name, float_t t } void SGCannon::StartGame(Entity* self) { + if (self->GetVar(GameStartedVariable)) return; self->SetNetworkVar(TimeLimitVariable, self->GetVar(TimeLimitVariable)); self->SetNetworkVar(AudioStartIntroVariable, true); self->SetVar(CurrentRewardVariable, LOT_NULL); @@ -447,6 +435,14 @@ void SGCannon::RemovePlayer(LWOOBJID playerID) { } } +void SGCannon::OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled){ + if (canceled){ + StopGame(self, canceled); + RemovePlayer(player); + } +} + + void SGCannon::StartChargedCannon(Entity* self, uint32_t optionalTime) { optionalTime = optionalTime == 0 ? constants.chargedTime : optionalTime; self->SetVar(SuperChargePausedVariable, false); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h index df9831ad..f4202773 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h @@ -63,12 +63,11 @@ public: void OnStartup(Entity* self) override; void OnPlayerLoaded(Entity* self, Entity* player) override; void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override; - void OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int32_t value1, - int32_t value2, const std::u16string& stringValue) override; - void OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, - const std::u16string& userData) override; + void OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int32_t value1, int32_t value2, const std::u16string& stringValue) override; + void OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) override; void OnActivityTimerDone(Entity* self, const std::string& name) override; void OnActivityTimerUpdate(Entity* self, const std::string& name, float_t timeRemaining, float_t elapsedTime) override; + void OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled); private: static std::vector> GetWaves(); static SGConstants GetConstants(); From 6e6a05fc1d71d2292af6953366850bfd3815c031 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 11 May 2023 06:37:02 -0500 Subject: [PATCH 047/116] fix: prevent negative imagination (#1083) * fix: prevent negative imagination And fail switch if we don't have enough imagination * Make better --- dGame/dBehaviors/SwitchBehavior.cpp | 2 +- dGame/dComponents/RebuildComponent.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dGame/dBehaviors/SwitchBehavior.cpp b/dGame/dBehaviors/SwitchBehavior.cpp index c010f31b..bd261906 100644 --- a/dGame/dBehaviors/SwitchBehavior.cpp +++ b/dGame/dBehaviors/SwitchBehavior.cpp @@ -30,7 +30,7 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre Game::logger->LogDebug("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination()); - if (state || (entity->GetLOT() == 8092 && destroyableComponent->GetImagination() >= m_imagination)) { + if (state) { this->m_actionTrue->Handle(context, bitStream, branch); } else { this->m_actionFalse->Handle(context, bitStream, branch); diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index fcf2738c..acd84a64 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -196,18 +196,18 @@ void RebuildComponent::Update(float deltaTime) { DestroyableComponent* destComp = builder->GetComponent(); if (!destComp) break; - int newImagination = destComp->GetImagination() - 1; + int newImagination = destComp->GetImagination(); + if (newImagination <= 0) { + CancelRebuild(builder, eQuickBuildFailReason::OUT_OF_IMAGINATION, true); + break; + } + ++m_DrainedImagination; + --newImagination; destComp->SetImagination(newImagination); EntityManager::Instance()->SerializeEntity(builder); - ++m_DrainedImagination; - if (newImagination == 0 && m_DrainedImagination < m_TakeImagination) { - CancelRebuild(builder, eQuickBuildFailReason::OUT_OF_IMAGINATION, true); - - break; - } } if (m_Timer >= m_CompleteTime && m_DrainedImagination >= m_TakeImagination) { From 0e01948414071993c7924e9b78ab225050ced2f1 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 11 May 2023 06:54:41 -0500 Subject: [PATCH 048/116] Define comp 103 as Gate Rush Control comp (#1078) Fix typo in 115 --- dCommon/dEnums/eReplicaComponentType.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dCommon/dEnums/eReplicaComponentType.h b/dCommon/dEnums/eReplicaComponentType.h index 3eee16f3..2d24c19e 100644 --- a/dCommon/dEnums/eReplicaComponentType.h +++ b/dCommon/dEnums/eReplicaComponentType.h @@ -107,7 +107,7 @@ enum class eReplicaComponentType : uint32_t { DONATION_VENDOR, COMBAT_MEDIATOR, COMMENDATION_VENDOR, - UNKNOWN_103, + GATE_RUSH_CONTROL, RAIL_ACTIVATOR, ROLLER, PLAYER_FORCED_MOVEMENT, @@ -119,7 +119,7 @@ enum class eReplicaComponentType : uint32_t { UNKNOWN_112, PROPERTY_PLAQUE, BUILD_BORDER, - UNKOWN_115, + UNKNOWN_115, CULLING_PLANE, DESTROYABLE = 1000 // Actually 7 }; From a809f36548526ece966a0a3069b04b2c913c99a6 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Thu, 11 May 2023 09:23:48 -0500 Subject: [PATCH 049/116] Address feedback --- dGame/dGameMessages/GameMessages.cpp | 5 +---- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 7ebbf761..165876ff 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -6215,8 +6215,5 @@ void GameMessages::HandleRequestActivityExit(RakNet::BitStream* inStream, Entity inStream->Read(player_id); auto player = EntityManager::Instance()->GetEntity(player_id); if (!entity || !player) return; - - for (auto* shootingGallery : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { - shootingGallery->RequestActivityExit(entity, player_id, true); - } + entity->RequestActivityExit(entity, player_id, canceled); } diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h index f4202773..b20fae6d 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h @@ -67,7 +67,7 @@ public: void OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) override; void OnActivityTimerDone(Entity* self, const std::string& name) override; void OnActivityTimerUpdate(Entity* self, const std::string& name, float_t timeRemaining, float_t elapsedTime) override; - void OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled); + void OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled) override; private: static std::vector> GetWaves(); static SGConstants GetConstants(); From c5afd7d4a34b09c1e18524d24dfcf229a2609aa6 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 13 May 2023 03:55:12 -0700 Subject: [PATCH 050/116] Fix deserialization errors for MovingPlatforms - Fixes deserialization errors for MovingPlatforms that did not have an attached_path, but had a MovingPlatform component >= id 0. --- dGame/Entity.cpp | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index b9fc79fb..fdd7ce6f 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -690,23 +690,11 @@ void Entity::Initialize() { } std::string pathName = GetVarAsString(u"attached_path"); - const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName); - //Check to see if we have an attached path and add the appropiate component to handle it: - if (path){ - // if we have a moving platform path, then we need a moving platform component - if (path->pathType == PathType::MovingPlatform) { - MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); - m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat)); - // else if we are a movement path - } /*else if (path->pathType == PathType::Movement) { - auto movementAIcomp = GetComponent(); - if (movementAIcomp){ - // TODO: set path in existing movementAIComp - } else { - // TODO: create movementAIcomp and set path - } - }*/ + int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1); + if (movingPlatformComponentId >= 0 || !pathName.empty()) { + MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); + m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat)); } int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR); From 739eae52447811c7eddd26b82dc09a858f571c29 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 13 May 2023 09:30:59 -0500 Subject: [PATCH 051/116] feature: Implement FallSpeedBehavior (#1084) * Hacky FallSpeedBehavior * Fixup * Make it more robust like speedboost add check for default Fix error in GetActiveSpeedboosts * simplify and address feedback --- dGame/dBehaviors/Behavior.cpp | 5 +- dGame/dBehaviors/CMakeLists.txt | 1 + dGame/dBehaviors/FallSpeedBehavior.cpp | 50 +++++++++++++++++++ dGame/dBehaviors/FallSpeedBehavior.h | 18 +++++++ .../ControllablePhysicsComponent.cpp | 2 +- .../ControllablePhysicsComponent.h | 2 +- 6 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 dGame/dBehaviors/FallSpeedBehavior.cpp create mode 100644 dGame/dBehaviors/FallSpeedBehavior.h diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 2a269ddc..8b34507a 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -61,6 +61,7 @@ #include "SpeedBehavior.h" #include "DamageReductionBehavior.h" #include "JetPackBehavior.h" +#include "FallSpeedBehavior.h" #include "ChangeIdleFlagsBehavior.h" #include "DarkInspirationBehavior.h" @@ -164,7 +165,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { case BehaviorTemplates::BEHAVIOR_CAR_BOOST: behavior = new CarBoostBehavior(behaviorId); break; - case BehaviorTemplates::BEHAVIOR_FALL_SPEED: break; + case BehaviorTemplates::BEHAVIOR_FALL_SPEED: + behavior = new FallSpeedBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_SHIELD: break; case BehaviorTemplates::BEHAVIOR_REPAIR_ARMOR: behavior = new RepairBehavior(behaviorId); diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index 7b331fe0..8a9368b9 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -22,6 +22,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "DurationBehavior.cpp" "EmptyBehavior.cpp" "EndBehavior.cpp" + "FallSpeedBehavior.cpp" "ForceMovementBehavior.cpp" "HealBehavior.cpp" "ImaginationBehavior.cpp" diff --git a/dGame/dBehaviors/FallSpeedBehavior.cpp b/dGame/dBehaviors/FallSpeedBehavior.cpp new file mode 100644 index 00000000..158c87f6 --- /dev/null +++ b/dGame/dBehaviors/FallSpeedBehavior.cpp @@ -0,0 +1,50 @@ +#include "FallSpeedBehavior.h" + +#include "ControllablePhysicsComponent.h" +#include "BehaviorContext.h" +#include "BehaviorBranchContext.h" + + +void FallSpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + // make sure required parameter has non-default value + if (m_PercentSlowed == 0.0f) return; + auto* target = EntityManager::Instance()->GetEntity(branch.target); + if (!target) return; + + auto* controllablePhysicsComponent = target->GetComponent(); + if (!controllablePhysicsComponent) return; + controllablePhysicsComponent->SetGravityScale(m_PercentSlowed); + EntityManager::Instance()->SerializeEntity(target); + + if (branch.duration > 0.0f) { + context->RegisterTimerBehavior(this, branch); + } else if (branch.start > 0) { + context->RegisterEndBehavior(this, branch); + } +} + +void FallSpeedBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + Handle(context, bitStream, branch); +} + +void FallSpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + End(context, branch, second); +} + +void FallSpeedBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { + End(context, branch, LWOOBJID_EMPTY); +} + +void FallSpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + auto* target = EntityManager::Instance()->GetEntity(branch.target); + if (!target) return; + + auto* controllablePhysicsComponent = target->GetComponent(); + if (!controllablePhysicsComponent) return; + controllablePhysicsComponent->SetGravityScale(1); + EntityManager::Instance()->SerializeEntity(target); +} + +void FallSpeedBehavior::Load(){ + m_PercentSlowed = GetFloat("percent_slowed"); +} diff --git a/dGame/dBehaviors/FallSpeedBehavior.h b/dGame/dBehaviors/FallSpeedBehavior.h new file mode 100644 index 00000000..01f0143f --- /dev/null +++ b/dGame/dBehaviors/FallSpeedBehavior.h @@ -0,0 +1,18 @@ +#pragma once +#include "Behavior.h" + +class FallSpeedBehavior final : public Behavior +{ +public: + explicit FallSpeedBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {} + + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void UnCast(BehaviorContext* context, BehaviorBranchContext branch) override; + void Load() override; + +private: + float m_PercentSlowed; +}; diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index 1b8627a7..d1b44200 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -320,7 +320,7 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) { // Recalculate speedboost since we removed one m_SpeedBoost = 0.0f; - if (m_ActiveSpeedBoosts.size() == 0) { // no active speed boosts left, so return to base speed + if (m_ActiveSpeedBoosts.empty()) { // no active speed boosts left, so return to base speed auto* levelProgressionComponent = m_Parent->GetComponent(); if (levelProgressionComponent) m_SpeedBoost = levelProgressionComponent->GetSpeedBase(); } else { // Used the last applied speedboost diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index d6088718..470a7af4 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -276,7 +276,7 @@ public: * The speed boosts of this component. * @return All active Speed boosts for this component. */ - std::vector GetActiveSpeedboosts() { return m_ActivePickupRadiusScales; }; + std::vector GetActiveSpeedboosts() { return m_ActiveSpeedBoosts; }; /** * Activates the Bubble Buff From 1af70161eb70ad5b00dba6f586e4447f3e1ac552 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 13 May 2023 09:31:13 -0500 Subject: [PATCH 052/116] fix: orient player correctly when using pirate mast in FV (#1087) * fix: frient player correctly when using pirate mast in FV * only get mast name once --- dScripts/02_server/Map/GF/MastTeleport.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index 97b126b4..1447a6a0 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -43,10 +43,13 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendTeleport(playerId, position, rotation, player->GetSystemAddress(), true); // Hacky fix for odd rotations - if (self->GetVar(u"MastName") != u"Jail") { + auto mastName = self->GetVar(u"MastName"); + if (mastName == u"Elephant") { GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 140.0f, player->GetSystemAddress()); - } else { + } else if (mastName == u"Jail") { GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 100.0f, player->GetSystemAddress()); + } else if (mastName == u""){ + GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 203.0f, player->GetSystemAddress()); } const auto cinematic = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Cinematic")); From 9d105a287d28916a3e5c6f1eac65bebbb9eb901e Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 13 May 2023 15:47:28 -0500 Subject: [PATCH 053/116] fix: not everything attached to a path is a moving platform (#1090) --- dGame/Entity.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 4345d2db..68ab0c7a 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -690,11 +690,30 @@ void Entity::Initialize() { } std::string pathName = GetVarAsString(u"attached_path"); + const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName); - int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1); - if (movingPlatformComponentId >= 0 || !pathName.empty()) { - MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); - m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat)); + //Check to see if we have an attached path and add the appropiate component to handle it: + if (path){ + // if we have a moving platform path, then we need a moving platform component + if (path->pathType == PathType::MovingPlatform) { + MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); + m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat)); + // else if we are a movement path + } /*else if (path->pathType == PathType::Movement) { + auto movementAIcomp = GetComponent(); + if (movementAIcomp){ + // TODO: set path in existing movementAIComp + } else { + // TODO: create movementAIcomp and set path + } + }*/ + } else { + // else we still need to setup moving platform if it has a moving platform comp but no path + int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1); + if (movingPlatformComponentId >= 0) { + MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); + m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat)); + } } int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR); From 4fe335cc66a26ddcddca85a86cfe77d241b70638 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 13 May 2023 15:22:00 -0700 Subject: [PATCH 054/116] Refactor: Amf3 implementation (#998) * Update AMFDeserializeTests.cpp Redo Amf3 functionality Overhaul the whole thing due to it being outdated and clunky to use Sometimes you want to keep the value Update AMFDeserializeTests.cpp * Fix enum and constructors Correct enum to a class and simplify names. Add a proper default constructor * Update MasterServer.cpp * Fix bugs and add more tests * Refactor: AMF with templates in mind - Remove hard coded bodge - Use templates and generics to allow for much looser typing and strengthened implementation - Move code into header only implementation for portability Refactor: Convert AMF implementation to templates - Rip out previous implementation - Remove all extraneous terminology - Add proper overloads for all types of inserts - Fix up tests and codebase * Fix compiler errors * Check for null first * Add specialization for const char* * Update tests for new template specialization * Switch BitStream to use references * Rename files * Check enum bounds on deserialize I did this on a phone --- dCommon/AMFDeserialize.cpp | 99 ++--- dCommon/AMFDeserialize.h | 15 +- dCommon/AMFFormat.cpp | 156 ------- dCommon/AMFFormat.h | 413 ------------------ dCommon/AMFFormat_BitStream.cpp | 259 ----------- dCommon/AMFFormat_BitStream.h | 92 ---- dCommon/Amf3.h | 368 ++++++++++++++++ dCommon/AmfSerialize.cpp | 184 ++++++++ dCommon/AmfSerialize.h | 50 +++ dCommon/CMakeLists.txt | 4 +- dGame/dComponents/CharacterComponent.cpp | 6 +- dGame/dComponents/DestroyableComponent.cpp | 34 +- dGame/dComponents/MissionComponent.cpp | 2 +- .../dComponents/PropertyEntranceComponent.cpp | 9 +- dGame/dComponents/RenderComponent.h | 2 +- dGame/dGameMessages/GameMessages.cpp | 16 +- dGame/dGameMessages/GameMessages.h | 6 +- .../ControlBehaviorMessages/Action.cpp | 14 +- .../ControlBehaviorMessages/ActionContext.cpp | 10 +- .../AddActionMessage.cpp | 2 +- .../ControlBehaviorMessages/AddMessage.cpp | 4 +- .../AddStripMessage.cpp | 9 +- .../BehaviorMessageBase.cpp | 14 +- .../BehaviorMessageBase.h | 2 +- .../MoveToInventoryMessage.cpp | 4 +- .../ControlBehaviorMessages/RenameMessage.cpp | 4 +- .../StripUiPosition.cpp | 12 +- .../UpdateActionMessage.cpp | 2 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 44 +- dGame/dUtilities/SlashCommandHandler.cpp | 47 +- dMasterServer/MasterServer.cpp | 1 - .../Map/AM/AmConsoleTeleportServer.cpp | 2 +- .../Map/General/BankInteractServer.cpp | 14 +- .../02_server/Map/General/MailBoxServer.cpp | 15 +- .../Map/General/StoryBoxInteractServer.cpp | 19 +- dScripts/02_server/Map/NS/NsLegoClubDoor.cpp | 118 ++--- dScripts/02_server/Map/NS/NsLegoClubDoor.h | 2 +- dScripts/02_server/Map/NS/NsLupTeleport.cpp | 68 +-- dScripts/02_server/Map/NS/NsLupTeleport.h | 2 +- .../Map/NT/NtConsoleTeleportServer.cpp | 2 +- .../Map/Property/PropertyBankInteract.cpp | 15 +- dWorldServer/WorldServer.cpp | 12 +- tests/dCommonTests/AMFDeserializeTests.cpp | 225 +++++----- tests/dCommonTests/Amf3Tests.cpp | 116 +++++ tests/dCommonTests/CMakeLists.txt | 1 + .../dGameMessagesTests/GameMessageTests.cpp | 6 +- 46 files changed, 1081 insertions(+), 1420 deletions(-) delete mode 100644 dCommon/AMFFormat.cpp delete mode 100644 dCommon/AMFFormat.h delete mode 100644 dCommon/AMFFormat_BitStream.cpp delete mode 100644 dCommon/AMFFormat_BitStream.h create mode 100644 dCommon/Amf3.h create mode 100644 dCommon/AmfSerialize.cpp create mode 100644 dCommon/AmfSerialize.h create mode 100644 tests/dCommonTests/Amf3Tests.cpp diff --git a/dCommon/AMFDeserialize.cpp b/dCommon/AMFDeserialize.cpp index df4a7cb6..9eee1f12 100644 --- a/dCommon/AMFDeserialize.cpp +++ b/dCommon/AMFDeserialize.cpp @@ -1,77 +1,81 @@ #include "AMFDeserialize.h" -#include "AMFFormat.h" +#include + +#include "Amf3.h" /** * AMF3 Reference document https://rtmp.veriskope.com/pdf/amf3-file-format-spec.pdf * AMF3 Deserializer written by EmosewaMC */ -AMFValue* AMFDeserialize::Read(RakNet::BitStream* inStream) { +AMFBaseValue* AMFDeserialize::Read(RakNet::BitStream* inStream) { if (!inStream) return nullptr; - AMFValue* returnValue = nullptr; + AMFBaseValue* returnValue = nullptr; // Read in the value type from the bitStream - int8_t marker; - inStream->Read(marker); + uint8_t i; + inStream->Read(i); + if (i > static_cast(eAmf::Dictionary)) return nullptr; + eAmf marker = static_cast(i); // Based on the typing, create the value associated with that and return the base value class switch (marker) { - case AMFValueType::AMFUndefined: { - returnValue = new AMFUndefinedValue(); + case eAmf::Undefined: { + returnValue = new AMFBaseValue(); break; } - case AMFValueType::AMFNull: { + case eAmf::Null: { returnValue = new AMFNullValue(); break; } - case AMFValueType::AMFFalse: { - returnValue = new AMFFalseValue(); + case eAmf::False: { + returnValue = new AMFBoolValue(false); break; } - case AMFValueType::AMFTrue: { - returnValue = new AMFTrueValue(); + case eAmf::True: { + returnValue = new AMFBoolValue(true); break; } - case AMFValueType::AMFInteger: { + case eAmf::Integer: { returnValue = ReadAmfInteger(inStream); break; } - case AMFValueType::AMFDouble: { + case eAmf::Double: { returnValue = ReadAmfDouble(inStream); break; } - case AMFValueType::AMFString: { + case eAmf::String: { returnValue = ReadAmfString(inStream); break; } - case AMFValueType::AMFArray: { + case eAmf::Array: { returnValue = ReadAmfArray(inStream); break; } - // TODO We do not need these values, but if someone wants to implement them - // then please do so and add the corresponding unit tests. - case AMFValueType::AMFXMLDoc: - case AMFValueType::AMFDate: - case AMFValueType::AMFObject: - case AMFValueType::AMFXML: - case AMFValueType::AMFByteArray: - case AMFValueType::AMFVectorInt: - case AMFValueType::AMFVectorUInt: - case AMFValueType::AMFVectorDouble: - case AMFValueType::AMFVectorObject: - case AMFValueType::AMFDictionary: { - throw static_cast(marker); + // These values are unimplemented in the live client and will remain unimplemented + // unless someone modifies the client to allow serializing of these values. + case eAmf::XMLDoc: + case eAmf::Date: + case eAmf::Object: + case eAmf::XML: + case eAmf::ByteArray: + case eAmf::VectorInt: + case eAmf::VectorUInt: + case eAmf::VectorDouble: + case eAmf::VectorObject: + case eAmf::Dictionary: { + throw marker; break; } default: - throw static_cast(marker); + throw std::invalid_argument("Invalid AMF3 marker" + std::to_string(static_cast(marker))); break; } return returnValue; @@ -99,7 +103,7 @@ uint32_t AMFDeserialize::ReadU29(RakNet::BitStream* inStream) { return actualNumber; } -std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) { +const std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) { auto length = ReadU29(inStream); // Check if this is a reference bool isReference = length % 2 == 1; @@ -113,48 +117,39 @@ std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) { return value; } else { // Length is a reference to a previous index - use that as the read in value - return accessedElements[length]; + return accessedElements.at(length); } } -AMFValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) { - auto doubleValue = new AMFDoubleValue(); +AMFBaseValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) { double value; inStream->Read(value); - doubleValue->SetDoubleValue(value); - return doubleValue; + return new AMFDoubleValue(value); } -AMFValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) { +AMFBaseValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) { auto arrayValue = new AMFArrayValue(); // Read size of dense array auto sizeOfDenseArray = (ReadU29(inStream) >> 1); - - // Then read Key'd portion + // Then read associative portion while (true) { auto key = ReadString(inStream); - // No more values when we encounter an empty string + // No more associative values when we encounter an empty string key if (key.size() == 0) break; - arrayValue->InsertValue(key, Read(inStream)); + arrayValue->Insert(key, Read(inStream)); } - // Finally read dense portion for (uint32_t i = 0; i < sizeOfDenseArray; i++) { - arrayValue->PushBackValue(Read(inStream)); + arrayValue->Insert(i, Read(inStream)); } - return arrayValue; } -AMFValue* AMFDeserialize::ReadAmfString(RakNet::BitStream* inStream) { - auto stringValue = new AMFStringValue(); - stringValue->SetStringValue(ReadString(inStream)); - return stringValue; +AMFBaseValue* AMFDeserialize::ReadAmfString(RakNet::BitStream* inStream) { + return new AMFStringValue(ReadString(inStream)); } -AMFValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream* inStream) { - auto integerValue = new AMFIntegerValue(); - integerValue->SetIntegerValue(ReadU29(inStream)); - return integerValue; +AMFBaseValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream* inStream) { + return new AMFIntValue(ReadU29(inStream)); } diff --git a/dCommon/AMFDeserialize.h b/dCommon/AMFDeserialize.h index a49cdcd2..5e2729eb 100644 --- a/dCommon/AMFDeserialize.h +++ b/dCommon/AMFDeserialize.h @@ -5,7 +5,8 @@ #include #include -class AMFValue; +class AMFBaseValue; + class AMFDeserialize { public: /** @@ -14,7 +15,7 @@ public: * @param inStream inStream to read value from. * @return Returns an AMFValue with all the information from the bitStream in it. */ - AMFValue* Read(RakNet::BitStream* inStream); + AMFBaseValue* Read(RakNet::BitStream* inStream); private: /** * @brief Private method to read a U29 integer from a bitstream @@ -30,7 +31,7 @@ private: * @param inStream bitStream to read data from * @return The read string */ - std::string ReadString(RakNet::BitStream* inStream); + const std::string ReadString(RakNet::BitStream* inStream); /** * @brief Read an AMFDouble value from a bitStream @@ -38,7 +39,7 @@ private: * @param inStream bitStream to read data from * @return Double value represented as an AMFValue */ - AMFValue* ReadAmfDouble(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfDouble(RakNet::BitStream* inStream); /** * @brief Read an AMFArray from a bitStream @@ -46,7 +47,7 @@ private: * @param inStream bitStream to read data from * @return Array value represented as an AMFValue */ - AMFValue* ReadAmfArray(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfArray(RakNet::BitStream* inStream); /** * @brief Read an AMFString from a bitStream @@ -54,7 +55,7 @@ private: * @param inStream bitStream to read data from * @return String value represented as an AMFValue */ - AMFValue* ReadAmfString(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfString(RakNet::BitStream* inStream); /** * @brief Read an AMFInteger from a bitStream @@ -62,7 +63,7 @@ private: * @param inStream bitStream to read data from * @return Integer value represented as an AMFValue */ - AMFValue* ReadAmfInteger(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfInteger(RakNet::BitStream* inStream); /** * List of strings read so far saved to be read by reference. diff --git a/dCommon/AMFFormat.cpp b/dCommon/AMFFormat.cpp deleted file mode 100644 index 4407b29c..00000000 --- a/dCommon/AMFFormat.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "AMFFormat.h" - -// AMFInteger -void AMFIntegerValue::SetIntegerValue(uint32_t value) { - this->value = value; -} - -uint32_t AMFIntegerValue::GetIntegerValue() { - return this->value; -} - -// AMFDouble -void AMFDoubleValue::SetDoubleValue(double value) { - this->value = value; -} - -double AMFDoubleValue::GetDoubleValue() { - return this->value; -} - -// AMFString -void AMFStringValue::SetStringValue(const std::string& value) { - this->value = value; -} - -std::string AMFStringValue::GetStringValue() { - return this->value; -} - -// AMFXMLDoc -void AMFXMLDocValue::SetXMLDocValue(const std::string& value) { - this->xmlData = value; -} - -std::string AMFXMLDocValue::GetXMLDocValue() { - return this->xmlData; -} - -// AMFDate -void AMFDateValue::SetDateValue(uint64_t value) { - this->millisecondTimestamp = value; -} - -uint64_t AMFDateValue::GetDateValue() { - return this->millisecondTimestamp; -} - -// AMFArray Insert Value -void AMFArrayValue::InsertValue(const std::string& key, AMFValue* value) { - this->associative.insert(std::make_pair(key, value)); -} - -// AMFArray Remove Value -void AMFArrayValue::RemoveValue(const std::string& key) { - _AMFArrayMap_::iterator it = this->associative.find(key); - if (it != this->associative.end()) { - this->associative.erase(it); - } -} - -// AMFArray Get Associative Iterator Begin -_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueBegin() { - return this->associative.begin(); -} - -// AMFArray Get Associative Iterator End -_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueEnd() { - return this->associative.end(); -} - -// AMFArray Push Back Value -void AMFArrayValue::PushBackValue(AMFValue* value) { - this->dense.push_back(value); -} - -// AMFArray Pop Back Value -void AMFArrayValue::PopBackValue() { - this->dense.pop_back(); -} - -// AMFArray Get Dense List Size -uint32_t AMFArrayValue::GetDenseValueSize() { - return (uint32_t)this->dense.size(); -} - -// AMFArray Get Dense Iterator Begin -_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorBegin() { - return this->dense.begin(); -} - -// AMFArray Get Dense Iterator End -_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorEnd() { - return this->dense.end(); -} - -AMFArrayValue::~AMFArrayValue() { - for (auto valueToDelete : GetDenseArray()) { - if (valueToDelete) delete valueToDelete; - } - for (auto valueToDelete : GetAssociativeMap()) { - if (valueToDelete.second) delete valueToDelete.second; - } -} - -// AMFObject Constructor -AMFObjectValue::AMFObjectValue(std::vector> traits) { - this->traits.reserve(traits.size()); - std::vector>::iterator it = traits.begin(); - while (it != traits.end()) { - this->traits.insert(std::make_pair(it->first, std::make_pair(it->second, new AMFNullValue()))); - it++; - } -} - -// AMFObject Set Value -void AMFObjectValue::SetTraitValue(const std::string& trait, AMFValue* value) { - if (value) { - _AMFObjectTraits_::iterator it = this->traits.find(trait); - if (it != this->traits.end()) { - if (it->second.first == value->GetValueType()) { - it->second.second = value; - } - } - } -} - -// AMFObject Get Value -AMFValue* AMFObjectValue::GetTraitValue(const std::string& trait) { - _AMFObjectTraits_::iterator it = this->traits.find(trait); - if (it != this->traits.end()) { - return it->second.second; - } - - return nullptr; -} - -// AMFObject Get Trait Iterator Begin -_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorBegin() { - return this->traits.begin(); -} - -// AMFObject Get Trait Iterator End -_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorEnd() { - return this->traits.end(); -} - -// AMFObject Get Trait Size -uint32_t AMFObjectValue::GetTraitArrayCount() { - return (uint32_t)this->traits.size(); -} - -AMFObjectValue::~AMFObjectValue() { - for (auto valueToDelete = GetTraitsIteratorBegin(); valueToDelete != GetTraitsIteratorEnd(); valueToDelete++) { - if (valueToDelete->second.second) delete valueToDelete->second.second; - } -} diff --git a/dCommon/AMFFormat.h b/dCommon/AMFFormat.h deleted file mode 100644 index 6e479ef6..00000000 --- a/dCommon/AMFFormat.h +++ /dev/null @@ -1,413 +0,0 @@ -#pragma once - -// Custom Classes -#include "dCommonVars.h" - -// C++ -#include -#include - -/*! - \file AMFFormat.hpp - \brief A class for managing AMF values - */ - -class AMFValue; // Forward declaration - -// Definitions -#define _AMFArrayMap_ std::unordered_map -#define _AMFArrayList_ std::vector - -#define _AMFObjectTraits_ std::unordered_map> -#define _AMFObjectDynamicTraits_ std::unordered_map - -//! An enum for each AMF value type -enum AMFValueType : unsigned char { - AMFUndefined = 0x00, //!< An undefined AMF Value - AMFNull = 0x01, //!< A null AMF value - AMFFalse = 0x02, //!< A false AMF value - AMFTrue = 0x03, //!< A true AMF value - AMFInteger = 0x04, //!< An integer AMF value - AMFDouble = 0x05, //!< A double AMF value - AMFString = 0x06, //!< A string AMF value - AMFXMLDoc = 0x07, //!< An XML Doc AMF value - AMFDate = 0x08, //!< A date AMF value - AMFArray = 0x09, //!< An array AMF value - AMFObject = 0x0A, //!< An object AMF value - AMFXML = 0x0B, //!< An XML AMF value - AMFByteArray = 0x0C, //!< A byte array AMF value - AMFVectorInt = 0x0D, //!< An integer vector AMF value - AMFVectorUInt = 0x0E, //!< An unsigned integer AMF value - AMFVectorDouble = 0x0F, //!< A double vector AMF value - AMFVectorObject = 0x10, //!< An object vector AMF value - AMFDictionary = 0x11 //!< A dictionary AMF value -}; - -//! An enum for the object value types -enum AMFObjectValueType : unsigned char { - AMFObjectAnonymous = 0x01, - AMFObjectTyped = 0x02, - AMFObjectDynamic = 0x03, - AMFObjectExternalizable = 0x04 -}; - -//! The base AMF value class -class AMFValue { -public: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - virtual AMFValueType GetValueType() = 0; - virtual ~AMFValue() {}; -}; - -//! A typedef for a pointer to an AMF value -typedef AMFValue* NDGFxValue; - - -// The various AMF value types - -//! The undefined value AMF type -class AMFUndefinedValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFUndefined; -}; - -//! The null value AMF type -class AMFNullValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFNull; -}; - -//! The false value AMF type -class AMFFalseValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFFalse; -}; - -//! The true value AMF type -class AMFTrueValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFTrue; -}; - -//! The integer value AMF type -class AMFIntegerValue : public AMFValue { -private: - uint32_t value; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFInteger; - //! Sets the integer value - /*! - \param value The value to set - */ - void SetIntegerValue(uint32_t value); - - //! Gets the integer value - /*! - \return The integer value - */ - uint32_t GetIntegerValue(); -}; - -//! The double value AMF type -class AMFDoubleValue : public AMFValue { -private: - double value; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFDouble; - //! Sets the double value - /*! - \param value The value to set to - */ - void SetDoubleValue(double value); - - //! Gets the double value - /*! - \return The double value - */ - double GetDoubleValue(); -}; - -//! The string value AMF type -class AMFStringValue : public AMFValue { -private: - std::string value; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFString; - //! Sets the string value - /*! - \param value The string value to set to - */ - void SetStringValue(const std::string& value); - - //! Gets the string value - /*! - \return The string value - */ - std::string GetStringValue(); -}; - -//! The XML doc value AMF type -class AMFXMLDocValue : public AMFValue { -private: - std::string xmlData; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFXMLDoc; - //! Sets the XML Doc value - /*! - \param value The value to set to - */ - void SetXMLDocValue(const std::string& value); - - //! Gets the XML Doc value - /*! - \return The XML Doc value - */ - std::string GetXMLDocValue(); -}; - -//! The date value AMF type -class AMFDateValue : public AMFValue { -private: - uint64_t millisecondTimestamp; //!< The time in milliseconds since the ephoch - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFDate; - //! Sets the date time - /*! - \param value The value to set to - */ - void SetDateValue(uint64_t value); - - //! Gets the date value - /*! - \return The date value in milliseconds since the epoch - */ - uint64_t GetDateValue(); -}; - -//! The array value AMF type -// This object will manage it's own memory map and list. Do not delete its values. -class AMFArrayValue : public AMFValue { -private: - _AMFArrayMap_ associative; //!< The array map (associative part) - _AMFArrayList_ dense; //!< The array list (dense part) - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() override { return ValueType; } - -public: - static const AMFValueType ValueType = AMFArray; - - ~AMFArrayValue() override; - //! Inserts an item into the array map for a specific key - /*! - \param key The key to set - \param value The value to add - */ - void InsertValue(const std::string& key, AMFValue* value); - - //! Removes an item for a specific key - /*! - \param key The key to remove - */ - void RemoveValue(const std::string& key); - - //! Finds an AMF value - /*! - \return The AMF value if found, nullptr otherwise - */ - template - T* FindValue(const std::string& key) const { - _AMFArrayMap_::const_iterator it = this->associative.find(key); - if (it != this->associative.end() && T::ValueType == it->second->GetValueType()) { - return dynamic_cast(it->second); - } - - return nullptr; - }; - - //! Returns where the associative iterator begins - /*! - \return Where the array map iterator begins - */ - _AMFArrayMap_::iterator GetAssociativeIteratorValueBegin(); - - //! Returns where the associative iterator ends - /*! - \return Where the array map iterator ends - */ - _AMFArrayMap_::iterator GetAssociativeIteratorValueEnd(); - - //! Pushes back a value into the array list - /*! - \param value The value to push back - */ - void PushBackValue(AMFValue* value); - - //! Pops back the last value in the array list - void PopBackValue(); - - //! Gets the count of the dense list - /*! - \return The dense list size - */ - uint32_t GetDenseValueSize(); - - //! Gets a specific value from the list for the specified index - /*! - \param index The index to get - */ - template - T* GetValueAt(uint32_t index) { - if (index >= this->dense.size()) return nullptr; - AMFValue* foundValue = this->dense.at(index); - return T::ValueType == foundValue->GetValueType() ? dynamic_cast(foundValue) : nullptr; - }; - - //! Returns where the dense iterator begins - /*! - \return Where the iterator begins - */ - _AMFArrayList_::iterator GetDenseIteratorBegin(); - - //! Returns where the dense iterator ends - /*! - \return Where the iterator ends - */ - _AMFArrayList_::iterator GetDenseIteratorEnd(); - - //! Returns the associative map - /*! - \return The associative map - */ - _AMFArrayMap_ GetAssociativeMap() { return this->associative; }; - - //! Returns the dense array - /*! - \return The dense array - */ - _AMFArrayList_ GetDenseArray() { return this->dense; }; -}; - -//! The anonymous object value AMF type -class AMFObjectValue : public AMFValue { -private: - _AMFObjectTraits_ traits; //!< The object traits - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() override { return ValueType; } - ~AMFObjectValue() override; - -public: - static const AMFValueType ValueType = AMFObject; - //! Constructor - /*! - \param traits The traits to set - */ - AMFObjectValue(std::vector> traits); - - //! Gets the object value type - /*! - \return The object value type - */ - virtual AMFObjectValueType GetObjectValueType() { return AMFObjectAnonymous; } - - //! Sets the value of a trait - /*! - \param trait The trait to set the value for - \param value The AMF value to set - */ - void SetTraitValue(const std::string& trait, AMFValue* value); - - //! Gets a trait value - /*! - \param trait The trait to get the value for - \return The trait value - */ - AMFValue* GetTraitValue(const std::string& trait); - - //! Gets the beginning of the object traits iterator - /*! - \return The AMF trait array iterator begin - */ - _AMFObjectTraits_::iterator GetTraitsIteratorBegin(); - - //! Gets the end of the object traits iterator - /*! - \return The AMF trait array iterator begin - */ - _AMFObjectTraits_::iterator GetTraitsIteratorEnd(); - - //! Gets the amount of traits - /*! - \return The amount of traits - */ - uint32_t GetTraitArrayCount(); -}; diff --git a/dCommon/AMFFormat_BitStream.cpp b/dCommon/AMFFormat_BitStream.cpp deleted file mode 100644 index dcb9197d..00000000 --- a/dCommon/AMFFormat_BitStream.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include "AMFFormat_BitStream.h" - -// Writes an AMFValue pointer to a RakNet::BitStream -template<> -void RakNet::BitStream::Write(AMFValue* value) { - if (value != nullptr) { - AMFValueType type = value->GetValueType(); - - switch (type) { - case AMFUndefined: { - AMFUndefinedValue* v = (AMFUndefinedValue*)value; - this->Write(*v); - break; - } - - case AMFNull: { - AMFNullValue* v = (AMFNullValue*)value; - this->Write(*v); - break; - } - - case AMFFalse: { - AMFFalseValue* v = (AMFFalseValue*)value; - this->Write(*v); - break; - } - - case AMFTrue: { - AMFTrueValue* v = (AMFTrueValue*)value; - this->Write(*v); - break; - } - - case AMFInteger: { - AMFIntegerValue* v = (AMFIntegerValue*)value; - this->Write(*v); - break; - } - - case AMFDouble: { - AMFDoubleValue* v = (AMFDoubleValue*)value; - this->Write(*v); - break; - } - - case AMFString: { - AMFStringValue* v = (AMFStringValue*)value; - this->Write(*v); - break; - } - - case AMFXMLDoc: { - AMFXMLDocValue* v = (AMFXMLDocValue*)value; - this->Write(*v); - break; - } - - case AMFDate: { - AMFDateValue* v = (AMFDateValue*)value; - this->Write(*v); - break; - } - - case AMFArray: { - this->Write((AMFArrayValue*)value); - break; - } - case AMFObject: - case AMFXML: - case AMFByteArray: - case AMFVectorInt: - case AMFVectorUInt: - case AMFVectorDouble: - case AMFVectorObject: - case AMFDictionary: - break; - } - } -} - -/** - * A private function to write an value to a RakNet::BitStream - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteUInt29(RakNet::BitStream* bs, uint32_t v) { - unsigned char b4 = (unsigned char)v; - if (v < 0x00200000) { - b4 = b4 & 0x7F; - if (v > 0x7F) { - unsigned char b3; - v = v >> 7; - b3 = ((unsigned char)(v)) | 0x80; - if (v > 0x7F) { - unsigned char b2; - v = v >> 7; - b2 = ((unsigned char)(v)) | 0x80; - bs->Write(b2); - } - - bs->Write(b3); - } - } else { - unsigned char b1; - unsigned char b2; - unsigned char b3; - - v = v >> 8; - b3 = ((unsigned char)(v)) | 0x80; - v = v >> 7; - b2 = ((unsigned char)(v)) | 0x80; - v = v >> 7; - b1 = ((unsigned char)(v)) | 0x80; - - bs->Write(b1); - bs->Write(b2); - bs->Write(b3); - } - - bs->Write(b4); -} - -/** - * Writes a flag number to a RakNet::BitStream - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) { - v = (v << 1) | 0x01; - WriteUInt29(bs, v); -} - -/** - * Writes an AMFString to a RakNet::BitStream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFString(RakNet::BitStream* bs, const std::string& str) { - WriteFlagNumber(bs, (uint32_t)str.size()); - bs->Write(str.c_str(), (uint32_t)str.size()); -} - -/** - * Writes an U16 to a bitstream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) { - bs->Write(value); -} - -/** - * Writes an U32 to a bitstream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) { - bs->Write(value); -} - -/** - * Writes an U64 to a bitstream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) { - bs->Write(value); -} - - -// Writes an AMFUndefinedValue to BitStream -template<> -void RakNet::BitStream::Write(AMFUndefinedValue value) { - this->Write(AMFUndefined); -} - -// Writes an AMFNullValue to BitStream -template<> -void RakNet::BitStream::Write(AMFNullValue value) { - this->Write(AMFNull); -} - -// Writes an AMFFalseValue to BitStream -template<> -void RakNet::BitStream::Write(AMFFalseValue value) { - this->Write(AMFFalse); -} - -// Writes an AMFTrueValue to BitStream -template<> -void RakNet::BitStream::Write(AMFTrueValue value) { - this->Write(AMFTrue); -} - -// Writes an AMFIntegerValue to BitStream -template<> -void RakNet::BitStream::Write(AMFIntegerValue value) { - this->Write(AMFInteger); - WriteUInt29(this, value.GetIntegerValue()); -} - -// Writes an AMFDoubleValue to BitStream -template<> -void RakNet::BitStream::Write(AMFDoubleValue value) { - this->Write(AMFDouble); - double d = value.GetDoubleValue(); - WriteAMFU64(this, *((unsigned long long*) & d)); -} - -// Writes an AMFStringValue to BitStream -template<> -void RakNet::BitStream::Write(AMFStringValue value) { - this->Write(AMFString); - std::string v = value.GetStringValue(); - WriteAMFString(this, v); -} - -// Writes an AMFXMLDocValue to BitStream -template<> -void RakNet::BitStream::Write(AMFXMLDocValue value) { - this->Write(AMFXMLDoc); - std::string v = value.GetXMLDocValue(); - WriteAMFString(this, v); -} - -// Writes an AMFDateValue to BitStream -template<> -void RakNet::BitStream::Write(AMFDateValue value) { - this->Write(AMFDate); - uint64_t date = value.GetDateValue(); - WriteAMFU64(this, date); -} - -// Writes an AMFArrayValue to BitStream -template<> -void RakNet::BitStream::Write(AMFArrayValue* value) { - this->Write(AMFArray); - uint32_t denseSize = value->GetDenseValueSize(); - WriteFlagNumber(this, denseSize); - - _AMFArrayMap_::iterator it = value->GetAssociativeIteratorValueBegin(); - _AMFArrayMap_::iterator end = value->GetAssociativeIteratorValueEnd(); - - while (it != end) { - WriteAMFString(this, it->first); - this->Write(it->second); - it++; - } - - this->Write(AMFNull); - - if (denseSize > 0) { - _AMFArrayList_::iterator it2 = value->GetDenseIteratorBegin(); - _AMFArrayList_::iterator end2 = value->GetDenseIteratorEnd(); - - while (it2 != end2) { - this->Write(*it2); - it2++; - } - } -} diff --git a/dCommon/AMFFormat_BitStream.h b/dCommon/AMFFormat_BitStream.h deleted file mode 100644 index caa49337..00000000 --- a/dCommon/AMFFormat_BitStream.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -// Custom Classes -#include "AMFFormat.h" - -// RakNet -#include - -/*! - \file AMFFormat_BitStream.h - \brief A class that implements native writing of AMF values to RakNet::BitStream - */ - - // We are using the RakNet namespace -namespace RakNet { - //! Writes an AMFValue pointer to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFValue* value); - - //! Writes an AMFUndefinedValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFUndefinedValue value); - - //! Writes an AMFNullValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFNullValue value); - - //! Writes an AMFFalseValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFFalseValue value); - - //! Writes an AMFTrueValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFTrueValue value); - - //! Writes an AMFIntegerValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFIntegerValue value); - - //! Writes an AMFDoubleValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFDoubleValue value); - - //! Writes an AMFStringValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFStringValue value); - - //! Writes an AMFXMLDocValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFXMLDocValue value); - - //! Writes an AMFDateValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFDateValue value); - - //! Writes an AMFArrayValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFArrayValue* value); -} // namespace RakNet diff --git a/dCommon/Amf3.h b/dCommon/Amf3.h new file mode 100644 index 00000000..4dba039f --- /dev/null +++ b/dCommon/Amf3.h @@ -0,0 +1,368 @@ +#ifndef __AMF3__H__ +#define __AMF3__H__ + +#include "dCommonVars.h" +#include "dLogger.h" +#include "Game.h" + +#include +#include + +enum class eAmf : uint8_t { + Undefined = 0x00, // An undefined AMF Value + Null = 0x01, // A null AMF value + False = 0x02, // A false AMF value + True = 0x03, // A true AMF value + Integer = 0x04, // An integer AMF value + Double = 0x05, // A double AMF value + String = 0x06, // A string AMF value + XMLDoc = 0x07, // Unused in the live client and cannot be serialized without modification. An XML Doc AMF value + Date = 0x08, // Unused in the live client and cannot be serialized without modification. A date AMF value + Array = 0x09, // An array AMF value + Object = 0x0A, // Unused in the live client and cannot be serialized without modification. An object AMF value + XML = 0x0B, // Unused in the live client and cannot be serialized without modification. An XML AMF value + ByteArray = 0x0C, // Unused in the live client and cannot be serialized without modification. A byte array AMF value + VectorInt = 0x0D, // Unused in the live client and cannot be serialized without modification. An integer vector AMF value + VectorUInt = 0x0E, // Unused in the live client and cannot be serialized without modification. An unsigned integer AMF value + VectorDouble = 0x0F, // Unused in the live client and cannot be serialized without modification. A double vector AMF value + VectorObject = 0x10, // Unused in the live client and cannot be serialized without modification. An object vector AMF value + Dictionary = 0x11 // Unused in the live client and cannot be serialized without modification. A dictionary AMF value +}; + +class AMFBaseValue { +public: + virtual eAmf GetValueType() { return eAmf::Undefined; }; + AMFBaseValue() {}; + virtual ~AMFBaseValue() {}; +}; + +template +class AMFValue : public AMFBaseValue { +public: + AMFValue() {}; + AMFValue(ValueType value) { SetValue(value); }; + virtual ~AMFValue() override {}; + + eAmf GetValueType() override { return eAmf::Undefined; }; + + const ValueType& GetValue() { return data; }; + void SetValue(ValueType value) { data = value; }; +protected: + ValueType data; +}; + +// As a string this is much easier to write and read from a BitStream. +template<> +class AMFValue : public AMFBaseValue { +public: + AMFValue() {}; + AMFValue(const char* value) { SetValue(std::string(value)); }; + virtual ~AMFValue() override {}; + + eAmf GetValueType() override { return eAmf::String; }; + + const std::string& GetValue() { return data; }; + void SetValue(std::string value) { data = value; }; +protected: + std::string data; +}; + +typedef AMFValue AMFNullValue; +typedef AMFValue AMFBoolValue; +typedef AMFValue AMFIntValue; +typedef AMFValue AMFStringValue; +typedef AMFValue AMFDoubleValue; + +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Null; }; +template<> inline eAmf AMFValue::GetValueType() { return this->data ? eAmf::True : eAmf::False; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Integer; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Integer; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::String; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Double; }; + +/** + * The AMFArrayValue object holds 2 types of lists: + * An associative list where a key maps to a value + * A Dense list where elements are stored back to back + * + * Objects that are Registered are owned by this object + * and are not to be deleted by a caller. + */ +class AMFArrayValue : public AMFBaseValue { + + typedef std::unordered_map AMFAssociative; + typedef std::vector AMFDense; + +public: + eAmf GetValueType() override { return eAmf::Array; }; + + ~AMFArrayValue() override { + for (auto valueToDelete : GetDense()) { + if (valueToDelete) { + delete valueToDelete; + valueToDelete = nullptr; + } + } + for (auto valueToDelete : GetAssociative()) { + if (valueToDelete.second) { + delete valueToDelete.second; + valueToDelete.second = nullptr; + } + } + }; + + /** + * Returns the Associative portion of the object + */ + inline AMFAssociative& GetAssociative() { return this->associative; }; + + /** + * Returns the dense portion of the object + */ + inline AMFDense& GetDense() { return this->dense; }; + + /** + * Inserts an AMFValue into the associative portion with the given key. + * If a duplicate is attempted to be inserted, it is ignored and the + * first value with that key is kept in the map. + * + * These objects are not to be deleted by the caller as they are owned by + * the AMFArray object which manages its own memory. + * + * @param key The key to associate with the value + * @param value The value to insert + * + * @return The inserted element if the type matched, + * or nullptr if a key existed and was not the same type + */ + template + std::pair*, bool> Insert(const std::string& key, ValueType value) { + auto element = associative.find(key); + AMFValue* val = nullptr; + bool found = true; + if (element == associative.end()) { + val = new AMFValue(value); + associative.insert(std::make_pair(key, val)); + } else { + val = dynamic_cast*>(element->second); + found = false; + } + return std::make_pair(val, found); + }; + + // Associates an array with a string key + std::pair Insert(const std::string& key) { + auto element = associative.find(key); + AMFArrayValue* val = nullptr; + bool found = true; + if (element == associative.end()) { + val = new AMFArrayValue(); + associative.insert(std::make_pair(key, val)); + } else { + val = dynamic_cast(element->second); + found = false; + } + return std::make_pair(val, found); + }; + + // Associates an array with an integer key + std::pair Insert(const uint32_t& index) { + AMFArrayValue* val = nullptr; + bool inserted = false; + if (index >= dense.size()) { + dense.resize(index + 1); + val = new AMFArrayValue(); + dense.at(index) = val; + inserted = true; + } + return std::make_pair(dynamic_cast(dense.at(index)), inserted); + }; + + /** + * @brief Inserts an AMFValue into the AMFArray key'd by index. + * Attempting to insert the same key to the same value twice overwrites + * the previous value with the new one. + * + * @param index The index to associate with the value + * @param value The value to insert + * @return The inserted element, or nullptr if the type did not match + * what was at the index. + */ + template + std::pair*, bool> Insert(const uint32_t& index, ValueType value) { + AMFValue* val = nullptr; + bool inserted = false; + if (index >= this->dense.size()) { + this->dense.resize(index + 1); + val = new AMFValue(value); + this->dense.at(index) = val; + inserted = true; + } + return std::make_pair(dynamic_cast*>(this->dense.at(index)), inserted); + }; + + /** + * Inserts an AMFValue into the associative portion with the given key. + * If a duplicate is attempted to be inserted, it replaces the original + * + * The inserted element is now owned by this object and is not to be deleted + * + * @param key The key to associate with the value + * @param value The value to insert + */ + void Insert(const std::string& key, AMFBaseValue* value) { + auto element = associative.find(key); + if (element != associative.end() && element->second) { + delete element->second; + element->second = value; + } else { + associative.insert(std::make_pair(key, value)); + } + }; + + /** + * Inserts an AMFValue into the associative portion with the given index. + * If a duplicate is attempted to be inserted, it replaces the original + * + * The inserted element is now owned by this object and is not to be deleted + * + * @param key The key to associate with the value + * @param value The value to insert + */ + void Insert(const uint32_t index, AMFBaseValue* value) { + if (index < dense.size()) { + AMFDense::iterator itr = dense.begin() + index; + if (*itr) delete dense.at(index); + } else { + dense.resize(index + 1); + } + dense.at(index) = value; + }; + + /** + * Pushes an AMFValue into the back of the dense portion. + * + * These objects are not to be deleted by the caller as they are owned by + * the AMFArray object which manages its own memory. + * + * @param value The value to insert + * + * @return The inserted pointer, or nullptr should the key already be in use. + */ + template + inline AMFValue* Push(ValueType value) { + return Insert(this->dense.size(), value).first; + }; + + /** + * Removes the key from the associative portion + * + * The pointer removed is now no longer managed by this container + * + * @param key The key to remove from the associative portion + */ + void Remove(const std::string& key, bool deleteValue = true) { + AMFAssociative::iterator it = this->associative.find(key); + if (it != this->associative.end()) { + if (deleteValue) delete it->second; + this->associative.erase(it); + } + } + + /** + * Pops the last element in the dense portion, deleting it in the process. + */ + void Remove(const uint32_t index) { + if (!this->dense.empty() && index < this->dense.size()) { + auto itr = this->dense.begin() + index; + if (*itr) delete (*itr); + this->dense.erase(itr); + } + } + + void Pop() { + if (!this->dense.empty()) Remove(this->dense.size() - 1); + } + + AMFArrayValue* GetArray(const std::string& key) { + AMFAssociative::const_iterator it = this->associative.find(key); + if (it != this->associative.end()) { + return dynamic_cast(it->second); + } + return nullptr; + }; + + AMFArrayValue* GetArray(const uint32_t index) { + return index >= this->dense.size() ? nullptr : dynamic_cast(this->dense.at(index)); + }; + + inline AMFArrayValue* InsertArray(const std::string& key) { + return static_cast(Insert(key).first); + }; + + inline AMFArrayValue* InsertArray(const uint32_t index) { + return static_cast(Insert(index).first); + }; + + inline AMFArrayValue* PushArray() { + return static_cast(Insert(this->dense.size()).first); + }; + + /** + * Gets an AMFValue by the key from the associative portion and converts it + * to the AmfValue template type. If the key did not exist, it is inserted. + * + * @tparam The target object type + * @param key The key to lookup + * + * @return The AMFValue + */ + template + AMFValue* Get(const std::string& key) const { + AMFAssociative::const_iterator it = this->associative.find(key); + return it != this->associative.end() ? + dynamic_cast*>(it->second) : + nullptr; + }; + + // Get from the array but dont cast it + AMFBaseValue* Get(const std::string& key) const { + AMFAssociative::const_iterator it = this->associative.find(key); + return it != this->associative.end() ? it->second : nullptr; + }; + + /** + * @brief Get an AMFValue object at a position in the dense portion. + * Gets an AMFValue by the index from the dense portion and converts it + * to the AmfValue template type. If the index did not exist, it is inserted. + * + * @tparam The target object type + * @param index The index to get + * @return The casted object, or nullptr. + */ + template + AMFValue* Get(uint32_t index) const { + std::cout << (index < this->dense.size()) << std::endl; + return index < this->dense.size() ? + dynamic_cast*>(this->dense.at(index)) : + nullptr; + }; + + // Get from the dense but dont cast it + AMFBaseValue* Get(const uint32_t index) const { + return index < this->dense.size() ? this->dense.at(index) : nullptr; + }; +private: + /** + * The associative portion. These values are key'd with strings to an AMFValue. + */ + AMFAssociative associative; + + /** + * The dense portion. These AMFValue's are stored one after + * another with the most recent addition being at the back. + */ + AMFDense dense; +}; + +#endif //!__AMF3__H__ diff --git a/dCommon/AmfSerialize.cpp b/dCommon/AmfSerialize.cpp new file mode 100644 index 00000000..79ba5e2d --- /dev/null +++ b/dCommon/AmfSerialize.cpp @@ -0,0 +1,184 @@ +#include "AmfSerialize.h" + +#include "Game.h" +#include "dLogger.h" + +// Writes an AMFValue pointer to a RakNet::BitStream +template<> +void RakNet::BitStream::Write(AMFBaseValue& value) { + eAmf type = value.GetValueType(); + this->Write(type); + switch (type) { + case eAmf::Integer: { + this->Write(*static_cast(&value)); + break; + } + + case eAmf::Double: { + this->Write(*static_cast(&value)); + break; + } + + case eAmf::String: { + this->Write(*static_cast(&value)); + break; + } + + case eAmf::Array: { + this->Write(*static_cast(&value)); + break; + } + default: { + Game::logger->Log("AmfSerialize", "Encountered unwritable AMFType %i!", type); + } + case eAmf::Undefined: + case eAmf::Null: + case eAmf::False: + case eAmf::True: + case eAmf::Date: + case eAmf::Object: + case eAmf::XML: + case eAmf::XMLDoc: + case eAmf::ByteArray: + case eAmf::VectorInt: + case eAmf::VectorUInt: + case eAmf::VectorDouble: + case eAmf::VectorObject: + case eAmf::Dictionary: + break; + } +} + +/** + * A private function to write an value to a RakNet::BitStream + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteUInt29(RakNet::BitStream* bs, uint32_t v) { + unsigned char b4 = (unsigned char)v; + if (v < 0x00200000) { + b4 = b4 & 0x7F; + if (v > 0x7F) { + unsigned char b3; + v = v >> 7; + b3 = ((unsigned char)(v)) | 0x80; + if (v > 0x7F) { + unsigned char b2; + v = v >> 7; + b2 = ((unsigned char)(v)) | 0x80; + bs->Write(b2); + } + + bs->Write(b3); + } + } else { + unsigned char b1; + unsigned char b2; + unsigned char b3; + + v = v >> 8; + b3 = ((unsigned char)(v)) | 0x80; + v = v >> 7; + b2 = ((unsigned char)(v)) | 0x80; + v = v >> 7; + b1 = ((unsigned char)(v)) | 0x80; + + bs->Write(b1); + bs->Write(b2); + bs->Write(b3); + } + + bs->Write(b4); +} + +/** + * Writes a flag number to a RakNet::BitStream + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) { + v = (v << 1) | 0x01; + WriteUInt29(bs, v); +} + +/** + * Writes an AMFString to a RakNet::BitStream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFString(RakNet::BitStream* bs, const std::string& str) { + WriteFlagNumber(bs, (uint32_t)str.size()); + bs->Write(str.c_str(), (uint32_t)str.size()); +} + +/** + * Writes an U16 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) { + bs->Write(value); +} + +/** + * Writes an U32 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) { + bs->Write(value); +} + +/** + * Writes an U64 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) { + bs->Write(value); +} + +// Writes an AMFIntegerValue to BitStream +template<> +void RakNet::BitStream::Write(AMFIntValue& value) { + WriteUInt29(this, value.GetValue()); +} + +// Writes an AMFDoubleValue to BitStream +template<> +void RakNet::BitStream::Write(AMFDoubleValue& value) { + double d = value.GetValue(); + WriteAMFU64(this, *reinterpret_cast(&d)); +} + +// Writes an AMFStringValue to BitStream +template<> +void RakNet::BitStream::Write(AMFStringValue& value) { + WriteAMFString(this, value.GetValue()); +} + +// Writes an AMFArrayValue to BitStream +template<> +void RakNet::BitStream::Write(AMFArrayValue& value) { + uint32_t denseSize = value.GetDense().size(); + WriteFlagNumber(this, denseSize); + + auto it = value.GetAssociative().begin(); + auto end = value.GetAssociative().end(); + + while (it != end) { + WriteAMFString(this, it->first); + this->Write(*it->second); + it++; + } + + this->Write(eAmf::Null); + + if (denseSize > 0) { + auto it2 = value.GetDense().begin(); + auto end2 = value.GetDense().end(); + + while (it2 != end2) { + this->Write(**it2); + it2++; + } + } +} diff --git a/dCommon/AmfSerialize.h b/dCommon/AmfSerialize.h new file mode 100644 index 00000000..9a6f56f2 --- /dev/null +++ b/dCommon/AmfSerialize.h @@ -0,0 +1,50 @@ +#pragma once + +// Custom Classes +#include "Amf3.h" + +// RakNet +#include + +/*! + \file AmfSerialize.h + \brief A class that implements native writing of AMF values to RakNet::BitStream + */ + + // We are using the RakNet namespace +namespace RakNet { + //! Writes an AMFValue pointer to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFBaseValue& value); + + //! Writes an AMFIntegerValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFIntValue& value); + + //! Writes an AMFDoubleValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFDoubleValue& value); + + //! Writes an AMFStringValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFStringValue& value); + + //! Writes an AMFArrayValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFArrayValue& value); +} // namespace RakNet diff --git a/dCommon/CMakeLists.txt b/dCommon/CMakeLists.txt index 549acfb2..2517c048 100644 --- a/dCommon/CMakeLists.txt +++ b/dCommon/CMakeLists.txt @@ -1,6 +1,6 @@ -set(DCOMMON_SOURCES "AMFFormat.cpp" +set(DCOMMON_SOURCES "AMFDeserialize.cpp" - "AMFFormat_BitStream.cpp" + "AmfSerialize.cpp" "BinaryIO.cpp" "dConfig.cpp" "Diagnostics.cpp" diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 82ad5507..32fe564c 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -13,7 +13,7 @@ #include "VehiclePhysicsComponent.h" #include "GameMessages.h" #include "Item.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "eGameMasterLevel.h" #include "eGameActivity.h" @@ -734,6 +734,6 @@ void CharacterComponent::RemoveVentureVisionEffect(std::string ventureVisionType void CharacterComponent::UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const { if (!m_Parent) return; AMFArrayValue arrayToSend; - arrayToSend.InsertValue(ventureVisionType, showFaction ? static_cast(new AMFTrueValue()) : static_cast(new AMFFalseValue())); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent ? m_Parent->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS, "SetFactionVisibility", &arrayToSend); + arrayToSend.Insert(ventureVisionType, showFaction); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent ? m_Parent->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS, "SetFactionVisibility", arrayToSend); } diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 7e7d44aa..01ebf5c1 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -4,8 +4,8 @@ #include "Game.h" #include "dConfig.h" -#include "AMFFormat.h" -#include "AMFFormat_BitStream.h" +#include "Amf3.h" +#include "AmfSerialize.h" #include "GameMessages.h" #include "User.h" #include "CDClientManager.h" @@ -245,16 +245,12 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { if (playAnim) { // Now update the player bar if (!m_Parent->GetParentUser()) return; - AMFStringValue* amount = new AMFStringValue(); - amount->SetStringValue(std::to_string(difference)); - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("health"); AMFArrayValue args; - args.InsertValue("amount", amount); - args.InsertValue("type", type); + args.Insert("amount", std::to_string(difference)); + args.Insert("type", "health"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } EntityManager::Instance()->SerializeEntity(m_Parent); @@ -290,16 +286,12 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { if (playAnim) { // Now update the player bar if (!m_Parent->GetParentUser()) return; - AMFStringValue* amount = new AMFStringValue(); - amount->SetStringValue(std::to_string(value)); - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("armor"); AMFArrayValue args; - args.InsertValue("amount", amount); - args.InsertValue("type", type); + args.Insert("amount", std::to_string(value)); + args.Insert("type", "armor"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } EntityManager::Instance()->SerializeEntity(m_Parent); @@ -334,16 +326,12 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { if (playAnim) { // Now update the player bar if (!m_Parent->GetParentUser()) return; - AMFStringValue* amount = new AMFStringValue(); - amount->SetStringValue(std::to_string(difference)); - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("imagination"); AMFArrayValue args; - args.InsertValue("amount", amount); - args.InsertValue("type", type); + args.Insert("amount", std::to_string(difference)); + args.Insert("type", "imagination"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } EntityManager::Instance()->SerializeEntity(m_Parent); } diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index 0ae0f07e..8f61c1aa 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -13,7 +13,7 @@ #include "InventoryComponent.h" #include "GameMessages.h" #include "Game.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "dZoneManager.h" #include "Mail.h" #include "MissionPrerequisites.h" diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index 5da9a3c4..bff917d8 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -11,7 +11,7 @@ #include "CharacterComponent.h" #include "UserManager.h" #include "dLogger.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "eObjectBits.h" #include "eGameMasterLevel.h" @@ -36,12 +36,9 @@ void PropertyEntranceComponent::OnUse(Entity* entity) { AMFArrayValue args; - auto* state = new AMFStringValue(); - state->SetStringValue("property_menu"); + args.Insert("state", "property_menu"); - args.InsertValue("state", state); - - GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", &args); + GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args); } void PropertyEntranceComponent::OnEnterProperty(Entity* entity, uint32_t index, bool returnToZone, const SystemAddress& sysAddr) { diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index de8b2907..e09ec22d 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -6,7 +6,7 @@ #include #include -#include "AMFFormat.h" +#include "Amf3.h" #include "Component.h" #include "eReplicaComponentType.h" diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 165876ff..be57bce3 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -28,7 +28,7 @@ #include "eUnequippableActiveType.h" #include "eMovementPlatformState.h" #include "LeaderboardManager.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "Loot.h" #include "eRacingTaskParam.h" #include "eMissionTaskType.h" @@ -87,7 +87,7 @@ #include "AMFDeserialize.h" #include "eBlueprintSaveResponseType.h" #include "eAninmationFlags.h" -#include "AMFFormat_BitStream.h" +#include "AmfSerialize.h" #include "eReplicaComponentType.h" #include "eClientMessageType.h" #include "eGameMessageType.h" @@ -596,14 +596,14 @@ void GameMessages::SendModifyLEGOScore(Entity* entity, const SystemAddress& sysA SEND_PACKET; } -void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFValue* args) { +void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFBaseValue& args) { CBITSTREAM; CMSGHEADER; bitStream.Write(entity->GetObjectID()); bitStream.Write((uint16_t)eGameMessageType::UI_MESSAGE_SERVER_TO_SINGLE_CLIENT); - bitStream.Write(args); + bitStream.Write(args); uint32_t strMessageNameLength = message.size(); bitStream.Write(strMessageNameLength); @@ -614,7 +614,7 @@ void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const Syste SEND_PACKET; } -void GameMessages::SendUIMessageServerToAllClients(const std::string& message, AMFValue* args) { +void GameMessages::SendUIMessageServerToAllClients(const std::string& message, AMFBaseValue& args) { CBITSTREAM; CMSGHEADER; @@ -622,7 +622,7 @@ void GameMessages::SendUIMessageServerToAllClients(const std::string& message, A bitStream.Write(empty); bitStream.Write((uint16_t)eGameMessageType::UI_MESSAGE_SERVER_TO_ALL_CLIENTS); - bitStream.Write(args); + bitStream.Write(args); uint32_t strMessageNameLength = message.size(); bitStream.Write(strMessageNameLength); @@ -2486,8 +2486,8 @@ void GameMessages::SendUnSmash(Entity* entity, LWOOBJID builderID, float duratio void GameMessages::HandleControlBehaviors(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { AMFDeserialize reader; - std::unique_ptr amfArguments(reader.Read(inStream)); - if (amfArguments->GetValueType() != AMFValueType::AMFArray) return; + std::unique_ptr amfArguments(reader.Read(inStream)); + if (amfArguments->GetValueType() != eAmf::Array) return; uint32_t commandLength{}; inStream->Read(commandLength); diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 94b24b65..7e7a8f70 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -12,7 +12,7 @@ #include "eLootSourceType.h" #include "Brick.h" -class AMFValue; +class AMFBaseValue; class Entity; class Item; class NiQuaternion; @@ -88,8 +88,8 @@ namespace GameMessages { void NotifyLevelRewards(LWOOBJID objectID, const SystemAddress& sysAddr, int level, bool sending_rewards); void SendModifyLEGOScore(Entity* entity, const SystemAddress& sysAddr, int64_t score, eLootSourceType sourceType); - void SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFValue* args); - void SendUIMessageServerToAllClients(const std::string& message, AMFValue* args); + void SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFBaseValue& args); + void SendUIMessageServerToAllClients(const std::string& message, AMFBaseValue& args); void SendPlayEmbeddedEffectOnAllClientsNearObject(Entity* entity, std::u16string effectName, const LWOOBJID& fromObjectID, float radius); void SendPlayFXEffect(Entity* entity, int32_t effectID, const std::u16string& effectType, const std::string& name, LWOOBJID secondary, float priority = 1, float scale = 1, bool serialize = true); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp index 7da286b0..eabe76b7 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp @@ -12,19 +12,19 @@ Action::Action(AMFArrayValue* arguments) { valueParameterName = ""; valueParameterString = ""; valueParameterDouble = 0.0; - for (auto& typeValueMap : arguments->GetAssociativeMap()) { + for (auto& typeValueMap : arguments->GetAssociative()) { if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - type = static_cast(typeValueMap.second)->GetStringValue(); + if (typeValueMap.second->GetValueType() != eAmf::String) continue; + type = static_cast(typeValueMap.second)->GetValue(); } else { valueParameterName = typeValueMap.first; // Message is the only known string parameter if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast(typeValueMap.second)->GetStringValue(); + if (typeValueMap.second->GetValueType() != eAmf::String) continue; + valueParameterString = static_cast(typeValueMap.second)->GetValue(); } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast(typeValueMap.second)->GetDoubleValue(); + if (typeValueMap.second->GetValueType() != eAmf::Double) continue; + valueParameterDouble = static_cast(typeValueMap.second)->GetValue(); } } } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp index 480eef45..c2ba2eeb 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp @@ -2,7 +2,7 @@ #include -#include "AMFFormat.h" +#include "Amf3.h" ActionContext::ActionContext() { stripId = 0; @@ -17,15 +17,15 @@ ActionContext::ActionContext(AMFArrayValue* arguments, std::string customStateKe } BehaviorState ActionContext::GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key) { - auto* stateIDValue = arguments->FindValue(key); + auto* stateIDValue = arguments->Get(key); if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); - return static_cast(stateIDValue->GetDoubleValue()); + return static_cast(stateIDValue->GetValue()); } StripId ActionContext::GetStripIdFromArgument(AMFArrayValue* arguments, const std::string& key) { - auto* stripIdValue = arguments->FindValue(key); + auto* stripIdValue = arguments->Get(key); if (!stripIdValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); - return static_cast(stripIdValue->GetDoubleValue()); + return static_cast(stripIdValue->GetValue()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp index 4fc7f82b..98672909 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp @@ -4,7 +4,7 @@ AddActionMessage::AddActionMessage(AMFArrayValue* arguments) : BehaviorMessageBa actionContext = ActionContext(arguments); actionIndex = GetActionIndexFromArgument(arguments); - auto* actionValue = arguments->FindValue("action"); + auto* actionValue = arguments->GetArray("action"); if (!actionValue) return; action = Action(actionValue); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp index 4f2123b4..badee2c2 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp @@ -2,10 +2,10 @@ AddMessage::AddMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { behaviorIndex = 0; - auto* behaviorIndexValue = arguments->FindValue("BehaviorIndex"); + auto* behaviorIndexValue = arguments->Get("BehaviorIndex"); if (!behaviorIndexValue) return; - behaviorIndex = static_cast(behaviorIndexValue->GetDoubleValue()); + behaviorIndex = static_cast(behaviorIndexValue->GetValue()); Game::logger->LogDebug("AddMessage", "behaviorId %i index %i", behaviorId, behaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp index c4729c57..261b3462 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp @@ -4,17 +4,16 @@ AddStripMessage::AddStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { actionContext = ActionContext(arguments); - position = StripUiPosition(arguments); - auto* strip = arguments->FindValue("strip"); + auto* strip = arguments->GetArray("strip"); if (!strip) return; - auto* actions = strip->FindValue("actions"); + auto* actions = strip->GetArray("actions"); if (!actions) return; - for (uint32_t actionNumber = 0; actionNumber < actions->GetDenseValueSize(); actionNumber++) { - auto* actionValue = actions->GetValueAt(actionNumber); + for (uint32_t actionNumber = 0; actionNumber < actions->GetDense().size(); actionNumber++) { + auto* actionValue = actions->GetArray(actionNumber); if (!actionValue) continue; actionsToAdd.push_back(Action(actionValue)); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp index b3d98d51..3286504a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp @@ -1,6 +1,6 @@ #include "BehaviorMessageBase.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "BehaviorStates.h" #include "dCommonVars.h" @@ -11,12 +11,12 @@ BehaviorMessageBase::BehaviorMessageBase(AMFArrayValue* arguments) { int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) { const auto* key = "BehaviorID"; - auto* behaviorIDValue = arguments->FindValue(key); + auto* behaviorIDValue = arguments->Get(key); int32_t behaviorID = -1; - if (behaviorIDValue) { - behaviorID = std::stoul(behaviorIDValue->GetStringValue()); - } else if (!arguments->FindValue(key)) { + if (behaviorIDValue && behaviorIDValue->GetValueType() == eAmf::String) { + behaviorID = std::stoul(behaviorIDValue->GetValue()); + } else if (arguments->Get(key)->GetValueType() != eAmf::Undefined) { throw std::invalid_argument("Unable to find behavior ID"); } @@ -24,10 +24,10 @@ int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) } uint32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName) { - auto* actionIndexAmf = arguments->FindValue(keyName); + auto* actionIndexAmf = arguments->Get(keyName); if (!actionIndexAmf) { throw std::invalid_argument("Unable to find actionIndex"); } - return static_cast(actionIndexAmf->GetDoubleValue()); + return static_cast(actionIndexAmf->GetValue()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h index 13b00a35..8771286c 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -4,7 +4,7 @@ #include #include -#include "AMFFormat.h" +#include "Amf3.h" #include "dCommonVars.h" #include "Game.h" diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp index 92700076..5b61ee32 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp @@ -1,9 +1,9 @@ #include "MoveToInventoryMessage.h" MoveToInventoryMessage::MoveToInventoryMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - auto* behaviorIndexValue = arguments->FindValue("BehaviorIndex"); + auto* behaviorIndexValue = arguments->Get("BehaviorIndex"); if (!behaviorIndexValue) return; - behaviorIndex = static_cast(behaviorIndexValue->GetDoubleValue()); + behaviorIndex = static_cast(behaviorIndexValue->GetValue()); Game::logger->LogDebug("MoveToInventoryMessage", "behaviorId %i behaviorIndex %i", behaviorId, behaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp index 0ea3b6d6..a1c2abbc 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp @@ -1,9 +1,9 @@ #include "RenameMessage.h" RenameMessage::RenameMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - auto* nameAmf = arguments->FindValue("Name"); + auto* nameAmf = arguments->Get("Name"); if (!nameAmf) return; - name = nameAmf->GetStringValue(); + name = nameAmf->GetValue(); Game::logger->LogDebug("RenameMessage", "behaviorId %i n %s", behaviorId, name.c_str()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp index 4ddccc55..de612b45 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp @@ -1,6 +1,6 @@ #include "StripUiPosition.h" -#include "AMFFormat.h" +#include "Amf3.h" StripUiPosition::StripUiPosition() { xPosition = 0.0; @@ -10,13 +10,13 @@ StripUiPosition::StripUiPosition() { StripUiPosition::StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName) { xPosition = 0.0; yPosition = 0.0; - auto* uiArray = arguments->FindValue(uiKeyName); + auto* uiArray = arguments->GetArray(uiKeyName); if (!uiArray) return; - auto* xPositionValue = uiArray->FindValue("x"); - auto* yPositionValue = uiArray->FindValue("y"); + auto* xPositionValue = uiArray->Get("x"); + auto* yPositionValue = uiArray->Get("y"); if (!xPositionValue || !yPositionValue) return; - yPosition = yPositionValue->GetDoubleValue(); - xPosition = xPositionValue->GetDoubleValue(); + yPosition = yPositionValue->GetValue(); + xPosition = xPositionValue->GetValue(); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp index 53e2d570..23a0050d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp @@ -5,7 +5,7 @@ UpdateActionMessage::UpdateActionMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { actionContext = ActionContext(arguments); - auto* actionValue = arguments->FindValue("action"); + auto* actionValue = arguments->GetArray("action"); if (!actionValue) return; action = Action(actionValue); diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index dfb22b59..d8a062ca 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -1,6 +1,6 @@ #include "ControlBehaviors.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "Entity.h" #include "Game.h" #include "GameMessages.h" @@ -43,11 +43,11 @@ void ControlBehaviors::RequestUpdatedID(int32_t behaviorID, ModelComponent* mode // AMFArrayValue args; // AMFStringValue* behaviorIDString = new AMFStringValue(); - // behaviorIDString->SetStringValue(std::to_string(persistentId)); + // behaviorIDString->SetValue(std::to_string(persistentId)); // args.InsertValue("behaviorID", behaviorIDString); // AMFStringValue* objectIDAsString = new AMFStringValue(); - // objectIDAsString->SetStringValue(std::to_string(modelComponent->GetParent()->GetObjectID())); + // objectIDAsString->SetValue(std::to_string(modelComponent->GetParent()->GetObjectID())); // args.InsertValue("objectID", objectIDAsString); // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorID", &args); @@ -63,8 +63,6 @@ void ControlBehaviors::SendBehaviorListToClient(Entity* modelEntity, const Syste AMFArrayValue behaviorsToSerialize; - AMFArrayValue* behaviors = new AMFArrayValue(); // Empty for now - /** * The behaviors AMFArray will have up to 5 elements in the dense portion. * Each element in the dense portion will be made up of another AMFArray @@ -75,20 +73,17 @@ void ControlBehaviors::SendBehaviorListToClient(Entity* modelEntity, const Syste * "name": The name of the behavior formatted as an AMFString */ - behaviorsToSerialize.InsertValue("behaviors", behaviors); + behaviorsToSerialize.Insert("behaviors"); + behaviorsToSerialize.Insert("objectID", std::to_string(modelComponent->GetParent()->GetObjectID())); - AMFStringValue* amfStringValueForObjectID = new AMFStringValue(); - amfStringValueForObjectID->SetStringValue(std::to_string(modelComponent->GetParent()->GetObjectID())); - - behaviorsToSerialize.InsertValue("objectID", amfStringValueForObjectID); - GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", &behaviorsToSerialize); + GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", behaviorsToSerialize); } void ControlBehaviors::ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) { - auto* modelTypeAmf = arguments->FindValue("ModelType"); + auto* modelTypeAmf = arguments->Get("ModelType"); if (!modelTypeAmf) return; - uint32_t modelType = static_cast(modelTypeAmf->GetDoubleValue()); + uint32_t modelType = static_cast(modelTypeAmf->GetValue()); //TODO Update the model type here } @@ -179,7 +174,7 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // AMFArrayValue* state = new AMFArrayValue(); // AMFDoubleValue* stateAsDouble = new AMFDoubleValue(); - // stateAsDouble->SetDoubleValue(it->first); + // stateAsDouble->SetValue(it->first); // state->InsertValue("id", stateAsDouble); // AMFArrayValue* strips = new AMFArrayValue(); @@ -189,16 +184,16 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // AMFArrayValue* thisStrip = new AMFArrayValue(); // AMFDoubleValue* stripID = new AMFDoubleValue(); - // stripID->SetDoubleValue(strip->first); + // stripID->SetValue(strip->first); // thisStrip->InsertValue("id", stripID); // AMFArrayValue* uiArray = new AMFArrayValue(); // AMFDoubleValue* yPosition = new AMFDoubleValue(); - // yPosition->SetDoubleValue(strip->second->GetYPosition()); + // yPosition->SetValue(strip->second->GetYPosition()); // uiArray->InsertValue("y", yPosition); // AMFDoubleValue* xPosition = new AMFDoubleValue(); - // xPosition->SetDoubleValue(strip->second->GetXPosition()); + // xPosition->SetValue(strip->second->GetXPosition()); // uiArray->InsertValue("x", xPosition); // thisStrip->InsertValue("ui", uiArray); @@ -211,19 +206,19 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // AMFArrayValue* thisAction = new AMFArrayValue(); // AMFStringValue* actionName = new AMFStringValue(); - // actionName->SetStringValue(behaviorAction->actionName); + // actionName->SetValue(behaviorAction->actionName); // thisAction->InsertValue("Type", actionName); // if (behaviorAction->parameterValueString != "") // { // AMFStringValue* valueAsString = new AMFStringValue(); - // valueAsString->SetStringValue(behaviorAction->parameterValueString); + // valueAsString->SetValue(behaviorAction->parameterValueString); // thisAction->InsertValue(behaviorAction->parameterName, valueAsString); // } // else if (behaviorAction->parameterValueDouble != 0.0) // { // AMFDoubleValue* valueAsDouble = new AMFDoubleValue(); - // valueAsDouble->SetDoubleValue(behaviorAction->parameterValueDouble); + // valueAsDouble->SetValue(behaviorAction->parameterValueDouble); // thisAction->InsertValue(behaviorAction->parameterName, valueAsDouble); // } // stripSerialize->PushBackValue(thisAction); @@ -237,11 +232,11 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // behaviorInfo.InsertValue("states", stateSerialize); // AMFStringValue* objectidAsString = new AMFStringValue(); - // objectidAsString->SetStringValue(std::to_string(targetObjectID)); + // objectidAsString->SetValue(std::to_string(targetObjectID)); // behaviorInfo.InsertValue("objectID", objectidAsString); // AMFStringValue* behaviorIDAsString = new AMFStringValue(); - // behaviorIDAsString->SetStringValue(std::to_string(behaviorID)); + // behaviorIDAsString->SetValue(std::to_string(behaviorID)); // behaviorInfo.InsertValue("BehaviorID", behaviorIDAsString); // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorBlocks", &behaviorInfo); @@ -275,10 +270,9 @@ void ControlBehaviors::MoveToInventory(ModelComponent* modelComponent, const Sys // This closes the UI menu should it be open while the player is removing behaviors AMFArrayValue args; - AMFFalseValue* stateToPop = new AMFFalseValue(); - args.InsertValue("visible", stateToPop); + args.Insert("visible", false); - GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "ToggleBehaviorEditor", &args); + GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "ToggleBehaviorEditor", args); MoveToInventoryMessage moveToInventoryMessage(arguments); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 16db62a6..e8915d27 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -69,7 +69,7 @@ #include "BinaryPathFinder.h" #include "dConfig.h" #include "eBubbleType.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "MovingPlatformComponent.h" #include "eMissionState.h" #include "TriggerComponent.h" @@ -251,26 +251,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit { AMFArrayValue args; - auto* state = new AMFStringValue(); - state->SetStringValue("Story"); + args.Insert("state", "Story"); - args.InsertValue("state", state); - - GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", &args); + GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args); } entity->AddCallbackTimer(0.5f, [customText, entity]() { AMFArrayValue args; - auto* text = new AMFStringValue(); - text->SetStringValue(customText); - - args.InsertValue("visible", new AMFTrueValue()); - args.InsertValue("text", text); + args.Insert("visible", true); + args.Insert("text", customText); Game::logger->Log("SlashCommandHandler", "Sending %s", customText.c_str()); - GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "ToggleStoryBox", &args); + GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "ToggleStoryBox", args); }); return; @@ -530,12 +524,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - AMFStringValue* value = new AMFStringValue(); - value->SetStringValue(args[0]); + AMFArrayValue uiState; - AMFArrayValue args; - args.InsertValue("state", value); - GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "pushGameState", &args); + uiState.Insert("state", args.at(0)); + + GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "pushGameState", uiState); ChatPackets::SendSystemMessage(sysAddr, u"Switched UI state."); @@ -543,11 +536,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - AMFTrueValue* value = new AMFTrueValue(); - AMFArrayValue amfArgs; - amfArgs.InsertValue("visible", value); - GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, args[0], &amfArgs); + + amfArgs.Insert("visible", true); + + GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, args[0], amfArgs); ChatPackets::SendSystemMessage(sysAddr, u"Toggled UI state."); @@ -1617,7 +1610,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if ((chatCommand == "debugui") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Opening UIDebugger..."); AMFArrayValue args; - GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", nullptr); + GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", args); } if ((chatCommand == "boost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { @@ -2023,15 +2016,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::string& message) { AMFArrayValue args; - auto* titleValue = new AMFStringValue(); - titleValue->SetStringValue(title); - auto* messageValue = new AMFStringValue(); - messageValue->SetStringValue(message); - args.InsertValue("title", titleValue); - args.InsertValue("message", messageValue); + args.Insert("title", title); + args.Insert("message", message); - GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", &args); + GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", args); //Notify chat about it CBITSTREAM; diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index bc0937c2..7af235a4 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -335,7 +335,6 @@ int main(int argc, char** argv) { Game::im->GetInstance(0, false, 0); Game::im->GetInstance(1000, false, 0); - StartAuthServer(); } diff --git a/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp b/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp index f3931e0d..0627b27a 100644 --- a/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp +++ b/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp @@ -1,6 +1,6 @@ #include "AmConsoleTeleportServer.h" #include "ChooseYourDestinationNsToNt.h" -#include "AMFFormat.h" +#include "Amf3.h" void AmConsoleTeleportServer::OnStartup(Entity* self) { self->SetVar(u"teleportAnim", m_TeleportAnim); diff --git a/dScripts/02_server/Map/General/BankInteractServer.cpp b/dScripts/02_server/Map/General/BankInteractServer.cpp index b96187cf..9b563491 100644 --- a/dScripts/02_server/Map/General/BankInteractServer.cpp +++ b/dScripts/02_server/Map/General/BankInteractServer.cpp @@ -1,24 +1,24 @@ #include "BankInteractServer.h" #include "GameMessages.h" #include "Entity.h" -#include "AMFFormat.h" +#include "Amf3.h" void BankInteractServer::OnUse(Entity* self, Entity* user) { AMFArrayValue args; - AMFStringValue* bank = new AMFStringValue(); - bank->SetStringValue("bank"); - args.InsertValue("state", bank); - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + args.Insert("state", "bank"); + + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } void BankInteractServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { if (args == "ToggleBank") { AMFArrayValue args; - args.InsertValue("visible", new AMFFalseValue()); - GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", &args); + args.Insert("visible", false); + + GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", args); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"CloseBank", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); } diff --git a/dScripts/02_server/Map/General/MailBoxServer.cpp b/dScripts/02_server/Map/General/MailBoxServer.cpp index c2534f3e..53f3b3a2 100644 --- a/dScripts/02_server/Map/General/MailBoxServer.cpp +++ b/dScripts/02_server/Map/General/MailBoxServer.cpp @@ -1,19 +1,20 @@ #include "MailBoxServer.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "GameMessages.h" +#include "Entity.h" void MailBoxServer::OnUse(Entity* self, Entity* user) { - AMFStringValue* value = new AMFStringValue(); - value->SetStringValue("Mail"); AMFArrayValue args; - args.InsertValue("state", value); - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + + args.Insert("state", "Mail"); + + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } void MailBoxServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { if (args == "toggleMail") { AMFArrayValue args; - args.InsertValue("visible", new AMFFalseValue()); - GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleMail", &args); + args.Insert("visible", false); + GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleMail", args); } } diff --git a/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp b/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp index 2683ddd4..9a1a4908 100644 --- a/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp +++ b/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp @@ -2,7 +2,8 @@ #include "Character.h" #include "GameMessages.h" #include "dServer.h" -#include "AMFFormat.h" +#include "Amf3.h" +#include "Entity.h" void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { if (self->GetVar(u"hasCustomText")) { @@ -11,24 +12,18 @@ void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { { AMFArrayValue args; - auto* state = new AMFStringValue(); - state->SetStringValue("Story"); + args.Insert("state", "Story"); - args.InsertValue("state", state); - - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } user->AddCallbackTimer(0.1f, [user, customText]() { AMFArrayValue args; - auto* text = new AMFStringValue(); - text->SetStringValue(customText); + args.Insert("visible", true); + args.Insert("text", customText); - args.InsertValue("visible", new AMFTrueValue()); - args.InsertValue("text", text); - - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "ToggleStoryBox", &args); + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "ToggleStoryBox", args); }); return; diff --git a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp index 56a213b8..d7ee5fed 100644 --- a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp +++ b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp @@ -1,7 +1,7 @@ #include "NsLegoClubDoor.h" #include "dZoneManager.h" #include "GameMessages.h" -#include "AMFFormat.h" +#include "Amf3.h" void NsLegoClubDoor::OnStartup(Entity* self) { self->SetVar(u"currentZone", (int32_t)dZoneManager::Instance()->GetZoneID().GetMapID()); @@ -12,116 +12,56 @@ void NsLegoClubDoor::OnStartup(Entity* self) { args = {}; - AMFStringValue* callbackClient = new AMFStringValue(); - callbackClient->SetStringValue(std::to_string(self->GetObjectID())); - args.InsertValue("callbackClient", callbackClient); + args.Insert("callbackClient", std::to_string(self->GetObjectID())); + args.Insert("strIdentifier", "choiceDoor"); + args.Insert("title", "%[UI_CHOICE_DESTINATION]"); - AMFStringValue* strIdentifier = new AMFStringValue(); - strIdentifier->SetStringValue("choiceDoor"); - args.InsertValue("strIdentifier", strIdentifier); - - AMFStringValue* title = new AMFStringValue(); - title->SetStringValue("%[UI_CHOICE_DESTINATION]"); - args.InsertValue("title", title); - - AMFArrayValue* choiceOptions = new AMFArrayValue(); + AMFArrayValue* choiceOptions = args.InsertArray("options"); { - AMFArrayValue* nsArgs = new AMFArrayValue(); + AMFArrayValue* nsArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nimbus_Station.dds"); - nsArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NS]"); - nsArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1200"); - nsArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NS_HOVER]"); - nsArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(nsArgs); + nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); + nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); + nsArgs->Insert("identifier", "zoneID_1200"); + nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); } { - AMFArrayValue* ntArgs = new AMFArrayValue(); + AMFArrayValue* ntArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nexus_Tower.dds"); - ntArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NT]"); - ntArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1900"); - ntArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NT_HOVER]"); - ntArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(ntArgs); + ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); + ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); + ntArgs->Insert("identifier", "zoneID_1900"); + ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); } options = choiceOptions; - - args.InsertValue("options", choiceOptions); } void NsLegoClubDoor::OnUse(Entity* self, Entity* user) { auto* player = user; if (CheckChoice(self, player)) { - AMFArrayValue* multiArgs = new AMFArrayValue(); + AMFArrayValue multiArgs; - AMFStringValue* callbackClient = new AMFStringValue(); - callbackClient->SetStringValue(std::to_string(self->GetObjectID())); - multiArgs->InsertValue("callbackClient", callbackClient); - - AMFStringValue* strIdentifier = new AMFStringValue(); - strIdentifier->SetStringValue("choiceDoor"); - multiArgs->InsertValue("strIdentifier", strIdentifier); - - AMFStringValue* title = new AMFStringValue(); - title->SetStringValue("%[UI_CHOICE_DESTINATION]"); - multiArgs->InsertValue("title", title); - - multiArgs->InsertValue("options", options); + multiArgs.Insert("callbackClient", std::to_string(self->GetObjectID())); + multiArgs.Insert("strIdentifier", "choiceDoor"); + multiArgs.Insert("title", "%[UI_CHOICE_DESTINATION]"); + multiArgs.Insert("options", static_cast(options)); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", multiArgs); + + multiArgs.Remove("options", false); // We do not want the local amf to delete the options! } else if (self->GetVar(u"currentZone") != m_ChoiceZoneID) { - AMFArrayValue* multiArgs = new AMFArrayValue(); + AMFArrayValue multiArgs; + multiArgs.Insert("state", "Lobby"); - AMFStringValue* state = new AMFStringValue(); - state->SetStringValue("Lobby"); - multiArgs->InsertValue("state", state); - - AMFArrayValue* context = new AMFArrayValue(); - - AMFStringValue* user = new AMFStringValue(); - user->SetStringValue(std::to_string(player->GetObjectID())); - context->InsertValue("user", user); - - AMFStringValue* callbackObj = new AMFStringValue(); - callbackObj->SetStringValue(std::to_string(self->GetObjectID())); - context->InsertValue("callbackObj", callbackObj); - - AMFStringValue* helpVisible = new AMFStringValue(); - helpVisible->SetStringValue("show"); - context->InsertValue("HelpVisible", helpVisible); - - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("Lego_Club_Valid"); - context->InsertValue("type", type); - - multiArgs->InsertValue("context", context); + AMFArrayValue* context = multiArgs.InsertArray("context"); + context->Insert("user", std::to_string(player->GetObjectID())); + context->Insert("callbackObj", std::to_string(self->GetObjectID())); + context->Insert("HelpVisible", "show"); + context->Insert("type", "Lego_Club_Valid"); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "pushGameState", multiArgs); } else { diff --git a/dScripts/02_server/Map/NS/NsLegoClubDoor.h b/dScripts/02_server/Map/NS/NsLegoClubDoor.h index db1dcae4..5b25ba6d 100644 --- a/dScripts/02_server/Map/NS/NsLegoClubDoor.h +++ b/dScripts/02_server/Map/NS/NsLegoClubDoor.h @@ -2,7 +2,7 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" +#include "Amf3.h" class NsLegoClubDoor : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/02_server/Map/NS/NsLupTeleport.cpp b/dScripts/02_server/Map/NS/NsLupTeleport.cpp index 9cd4359b..74f8ace1 100644 --- a/dScripts/02_server/Map/NS/NsLupTeleport.cpp +++ b/dScripts/02_server/Map/NS/NsLupTeleport.cpp @@ -1,7 +1,7 @@ #include "NsLupTeleport.h" #include "dZoneManager.h" #include "GameMessages.h" -#include "AMFFormat.h" +#include "Amf3.h" void NsLupTeleport::OnStartup(Entity* self) { self->SetVar(u"currentZone", (int32_t)dZoneManager::Instance()->GetZoneID().GetMapID()); @@ -12,72 +12,36 @@ void NsLupTeleport::OnStartup(Entity* self) { args = {}; - AMFStringValue* callbackClient = new AMFStringValue(); - callbackClient->SetStringValue(std::to_string(self->GetObjectID())); - args.InsertValue("callbackClient", callbackClient); + args.Insert("callbackClient", std::to_string(self->GetObjectID())); + args.Insert("strIdentifier", "choiceDoor"); + args.Insert("title", "%[UI_CHOICE_DESTINATION]"); - AMFStringValue* strIdentifier = new AMFStringValue(); - strIdentifier->SetStringValue("choiceDoor"); - args.InsertValue("strIdentifier", strIdentifier); - - AMFStringValue* title = new AMFStringValue(); - title->SetStringValue("%[UI_CHOICE_DESTINATION]"); - args.InsertValue("title", title); - - AMFArrayValue* choiceOptions = new AMFArrayValue(); + AMFArrayValue* choiceOptions = args.InsertArray("options"); { - AMFArrayValue* nsArgs = new AMFArrayValue(); + AMFArrayValue* nsArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nimbus_Station.dds"); - nsArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NS]"); - nsArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1200"); - nsArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NS_HOVER]"); - nsArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(nsArgs); + nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); + nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); + nsArgs->Insert("identifier", "zoneID_1200"); + nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); } { - AMFArrayValue* ntArgs = new AMFArrayValue(); + AMFArrayValue* ntArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nexus_Tower.dds"); - ntArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NT]"); - ntArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1900"); - ntArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NT_HOVER]"); - ntArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(ntArgs); + ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); + ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); + ntArgs->Insert("identifier", "zoneID_1900"); + ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); } - - args.InsertValue("options", choiceOptions); } void NsLupTeleport::OnUse(Entity* self, Entity* user) { auto* player = user; if (CheckChoice(self, player)) { - GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", &args); + GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", args); } else { BaseOnUse(self, player); } diff --git a/dScripts/02_server/Map/NS/NsLupTeleport.h b/dScripts/02_server/Map/NS/NsLupTeleport.h index 28bab016..385e92c7 100644 --- a/dScripts/02_server/Map/NS/NsLupTeleport.h +++ b/dScripts/02_server/Map/NS/NsLupTeleport.h @@ -2,7 +2,7 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" +#include "Amf3.h" class NsLupTeleport : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp b/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp index 324a2fc0..8ba697ce 100644 --- a/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp +++ b/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp @@ -1,6 +1,6 @@ #include "NtConsoleTeleportServer.h" #include "Entity.h" -#include "AMFFormat.h" +#include "Amf3.h" void NtConsoleTeleportServer::OnStartup(Entity* self) { self->SetVar(u"teleportAnim", m_TeleportAnim); diff --git a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp index 9e727f39..282dce6c 100644 --- a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp +++ b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp @@ -1,7 +1,8 @@ #include "PropertyBankInteract.h" #include "EntityManager.h" #include "GameMessages.h" -#include "AMFFormat.h" +#include "Amf3.h" +#include "Entity.h" void PropertyBankInteract::OnStartup(Entity* self) { auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); @@ -20,11 +21,10 @@ void PropertyBankInteract::OnPlayerLoaded(Entity* self, Entity* player) { void PropertyBankInteract::OnUse(Entity* self, Entity* user) { AMFArrayValue args; - auto* value = new AMFStringValue(); - value->SetStringValue("bank"); - args.InsertValue("state", value); - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + args.Insert("state", "bank"); + + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"OpenBank", 0, 0, LWOOBJID_EMPTY, "", user->GetSystemAddress()); @@ -34,9 +34,10 @@ void PropertyBankInteract::OnFireEventServerSide(Entity* self, Entity* sender, s int32_t param2, int32_t param3) { if (args == "ToggleBank") { AMFArrayValue amfArgs; - amfArgs.InsertValue("visible", new AMFFalseValue()); - GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", &amfArgs); + amfArgs.Insert("visible", false); + + GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", amfArgs); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"CloseBank", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 5dabce1c..18625960 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -60,7 +60,7 @@ #include "AssetManager.h" #include "LevelProgressionComponent.h" #include "eBlueprintSaveResponseType.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "NiPoint3.h" #include "eServerDisconnectIdentifiers.h" #include "eObjectBits.h" @@ -598,15 +598,11 @@ void HandlePacketChat(Packet* packet) { //Send to our clients: AMFArrayValue args; - auto* titleValue = new AMFStringValue(); - titleValue->SetStringValue(title.c_str()); - auto* messageValue = new AMFStringValue(); - messageValue->SetStringValue(msg.c_str()); - args.InsertValue("title", titleValue); - args.InsertValue("message", messageValue); + args.Insert("title", title); + args.Insert("message", msg); - GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", &args); + GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", args); break; } diff --git a/tests/dCommonTests/AMFDeserializeTests.cpp b/tests/dCommonTests/AMFDeserializeTests.cpp index b679ea78..5a9d91e6 100644 --- a/tests/dCommonTests/AMFDeserializeTests.cpp +++ b/tests/dCommonTests/AMFDeserializeTests.cpp @@ -3,14 +3,17 @@ #include #include "AMFDeserialize.h" -#include "AMFFormat.h" +#include "Amf3.h" + +#include "Game.h" +#include "dLogger.h" /** * Helper method that all tests use to get their respective AMF. */ -std::unique_ptr ReadFromBitStream(RakNet::BitStream* bitStream) { +AMFBaseValue* ReadFromBitStream(RakNet::BitStream* bitStream) { AMFDeserialize deserializer; - std::unique_ptr returnValue(deserializer.Read(bitStream)); + AMFBaseValue* returnValue(deserializer.Read(bitStream)); return returnValue; } @@ -18,10 +21,10 @@ std::unique_ptr ReadFromBitStream(RakNet::BitStream* bitStream) { * @brief Test reading an AMFUndefined value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFUndefinedTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x00); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFUndefined); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Undefined); } /** @@ -29,54 +32,54 @@ TEST(dCommonTests, AMFDeserializeAMFUndefinedTest) { * */ TEST(dCommonTests, AMFDeserializeAMFNullTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x01); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFNull); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Null); } /** * @brief Test reading an AMFFalse value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFFalseTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x02); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFFalse); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::False); } /** * @brief Test reading an AMFTrue value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFTrueTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x03); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFTrue); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::True); } /** * @brief Test reading an AMFInteger value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { - CBITSTREAM + CBITSTREAM; { bitStream.Write(0x04); // 127 == 01111111 bitStream.Write(127); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that the max value of a byte can be read correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), 127); + ASSERT_EQ(static_cast(res.get())->GetValue(), 127); } bitStream.Reset(); { bitStream.Write(0x04); bitStream.Write(UINT32_MAX); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that we can read the maximum value correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), 536870911); + ASSERT_EQ(static_cast(res.get())->GetValue(), 536870911); } bitStream.Reset(); { @@ -87,10 +90,10 @@ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { bitStream.Write(255); // 127 == 01111111 bitStream.Write(127); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that short max can be read correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), UINT16_MAX); + ASSERT_EQ(static_cast(res.get())->GetValue(), UINT16_MAX); } bitStream.Reset(); { @@ -99,10 +102,10 @@ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { bitStream.Write(255); // 127 == 01111111 bitStream.Write(127); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that 2 byte max can be read correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), 16383); + ASSERT_EQ(static_cast(res.get())->GetValue(), 16383); } } @@ -110,42 +113,42 @@ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { * @brief Test reading an AMFDouble value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFDoubleTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x05); bitStream.Write(25346.4f); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFDouble); - ASSERT_EQ(static_cast(res.get())->GetDoubleValue(), 25346.4f); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Double); + ASSERT_EQ(static_cast(res.get())->GetValue(), 25346.4f); } /** * @brief Test reading an AMFString value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFStringTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x06); bitStream.Write(0x0F); std::string toWrite = "stateID"; for (auto e : toWrite) bitStream.Write(e); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFString); - ASSERT_EQ(static_cast(res.get())->GetStringValue(), "stateID"); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::String); + ASSERT_EQ(static_cast(res.get())->GetValue(), "stateID"); } /** * @brief Test reading an AMFArray value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFArrayTest) { - CBITSTREAM + CBITSTREAM; // Test empty AMFArray bitStream.Write(0x09); bitStream.Write(0x01); bitStream.Write(0x01); { - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFArray); - ASSERT_EQ(static_cast(res.get())->GetAssociativeMap().size(), 0); - ASSERT_EQ(static_cast(res.get())->GetDenseArray().size(), 0); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Array); + ASSERT_EQ(static_cast(res.get())->GetAssociative().size(), 0); + ASSERT_EQ(static_cast(res.get())->GetDense().size(), 0); } bitStream.Reset(); // Test a key'd value and dense value @@ -161,32 +164,32 @@ TEST(dCommonTests, AMFDeserializeAMFArrayTest) { bitStream.Write(0x0B); for (auto e : "10447") if (e != '\0') bitStream.Write(e); { - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFArray); - ASSERT_EQ(static_cast(res.get())->GetAssociativeMap().size(), 1); - ASSERT_EQ(static_cast(res.get())->GetDenseArray().size(), 1); - ASSERT_EQ(static_cast(res.get())->FindValue("BehaviorID")->GetStringValue(), "10447"); - ASSERT_EQ(static_cast(res.get())->GetValueAt(0)->GetStringValue(), "10447"); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Array); + ASSERT_EQ(static_cast(res.get())->GetAssociative().size(), 1); + ASSERT_EQ(static_cast(res.get())->GetDense().size(), 1); + ASSERT_EQ(static_cast(res.get())->Get("BehaviorID")->GetValue(), "10447"); + ASSERT_EQ(static_cast(res.get())->Get(0)->GetValue(), "10447"); } } /** - * @brief This test checks that if we recieve an unimplemented AMFValueType + * @brief This test checks that if we recieve an unimplemented eAmf * we correctly throw an error and can actch it. * Yes this leaks memory. */ TEST(dCommonTests, AMFDeserializeUnimplementedValuesTest) { - std::vector unimplementedValues = { - AMFValueType::AMFXMLDoc, - AMFValueType::AMFDate, - AMFValueType::AMFObject, - AMFValueType::AMFXML, - AMFValueType::AMFByteArray, - AMFValueType::AMFVectorInt, - AMFValueType::AMFVectorUInt, - AMFValueType::AMFVectorDouble, - AMFValueType::AMFVectorObject, - AMFValueType::AMFDictionary + std::vector unimplementedValues = { + eAmf::XMLDoc, + eAmf::Date, + eAmf::Object, + eAmf::XML, + eAmf::ByteArray, + eAmf::VectorInt, + eAmf::VectorUInt, + eAmf::VectorDouble, + eAmf::VectorObject, + eAmf::Dictionary }; // Run unimplemented tests to check that errors are thrown if // unimplemented AMF values are attempted to be parsed. @@ -202,16 +205,16 @@ TEST(dCommonTests, AMFDeserializeUnimplementedValuesTest) { fileStream.close(); - for (auto amfValueType : unimplementedValues) { + for (auto value : unimplementedValues) { RakNet::BitStream testBitStream; for (auto element : baseBitStream) { testBitStream.Write(element); } - testBitStream.Write(amfValueType); + testBitStream.Write(value); bool caughtException = false; try { ReadFromBitStream(&testBitStream); - } catch (AMFValueType unimplementedValueType) { + } catch (eAmf unimplementedValueType) { caughtException = true; } @@ -235,116 +238,116 @@ TEST(dCommonTests, AMFDeserializeLivePacketTest) { testFileStream.close(); - auto resultFromFn = ReadFromBitStream(&testBitStream); + std::unique_ptr resultFromFn(ReadFromBitStream(&testBitStream)); auto result = static_cast(resultFromFn.get()); // Test the outermost array - ASSERT_EQ(result->FindValue("BehaviorID")->GetStringValue(), "10447"); - ASSERT_EQ(result->FindValue("objectID")->GetStringValue(), "288300744895913279"); + ASSERT_EQ(result->Get("BehaviorID")->GetValue(), "10447"); + ASSERT_EQ(result->Get("objectID")->GetValue(), "288300744895913279"); // Test the execution state array - auto executionState = result->FindValue("executionState"); + auto executionState = result->GetArray("executionState"); ASSERT_NE(executionState, nullptr); - auto strips = executionState->FindValue("strips")->GetDenseArray(); + auto strips = executionState->GetArray("strips")->GetDense(); ASSERT_EQ(strips.size(), 1); auto stripsPosition0 = dynamic_cast(strips[0]); - auto actionIndex = stripsPosition0->FindValue("actionIndex"); + auto actionIndex = stripsPosition0->Get("actionIndex"); - ASSERT_EQ(actionIndex->GetDoubleValue(), 0.0f); + ASSERT_EQ(actionIndex->GetValue(), 0.0f); - auto stripIdExecution = stripsPosition0->FindValue("id"); + auto stripIdExecution = stripsPosition0->Get("id"); - ASSERT_EQ(stripIdExecution->GetDoubleValue(), 0.0f); + ASSERT_EQ(stripIdExecution->GetValue(), 0.0f); - auto stateIDExecution = executionState->FindValue("stateID"); + auto stateIdExecution = executionState->Get("stateID"); - ASSERT_EQ(stateIDExecution->GetDoubleValue(), 0.0f); + ASSERT_EQ(stateIdExecution->GetValue(), 0.0f); - auto states = result->FindValue("states")->GetDenseArray(); + auto states = result->GetArray("states")->GetDense(); ASSERT_EQ(states.size(), 1); auto firstState = dynamic_cast(states[0]); - auto stateID = firstState->FindValue("id"); + auto stateID = firstState->Get("id"); - ASSERT_EQ(stateID->GetDoubleValue(), 0.0f); + ASSERT_EQ(stateID->GetValue(), 0.0f); - auto stripsInState = firstState->FindValue("strips")->GetDenseArray(); + auto stripsInState = firstState->GetArray("strips")->GetDense(); ASSERT_EQ(stripsInState.size(), 1); auto firstStrip = dynamic_cast(stripsInState[0]); - auto actionsInFirstStrip = firstStrip->FindValue("actions")->GetDenseArray(); + auto actionsInFirstStrip = firstStrip->GetArray("actions")->GetDense(); ASSERT_EQ(actionsInFirstStrip.size(), 3); - auto actionID = firstStrip->FindValue("id"); + auto actionID = firstStrip->Get("id"); - ASSERT_EQ(actionID->GetDoubleValue(), 0.0f); + ASSERT_EQ(actionID->GetValue(), 0.0f); - auto uiArray = firstStrip->FindValue("ui"); + auto uiArray = firstStrip->GetArray("ui"); - auto xPos = uiArray->FindValue("x"); - auto yPos = uiArray->FindValue("y"); + auto xPos = uiArray->Get("x"); + auto yPos = uiArray->Get("y"); - ASSERT_EQ(xPos->GetDoubleValue(), 103.0f); - ASSERT_EQ(yPos->GetDoubleValue(), 82.0f); + ASSERT_EQ(xPos->GetValue(), 103.0f); + ASSERT_EQ(yPos->GetValue(), 82.0f); - auto stripId = firstStrip->FindValue("id"); + auto stripId = firstStrip->Get("id"); - ASSERT_EQ(stripId->GetDoubleValue(), 0.0f); + ASSERT_EQ(stripId->GetValue(), 0.0f); auto firstAction = dynamic_cast(actionsInFirstStrip[0]); - auto firstType = firstAction->FindValue("Type"); + auto firstType = firstAction->Get("Type"); - ASSERT_EQ(firstType->GetStringValue(), "OnInteract"); + ASSERT_EQ(firstType->GetValue(), "OnInteract"); - auto firstCallback = firstAction->FindValue("__callbackID__"); + auto firstCallback = firstAction->Get("__callbackID__"); - ASSERT_EQ(firstCallback->GetStringValue(), ""); + ASSERT_EQ(firstCallback->GetValue(), ""); auto secondAction = dynamic_cast(actionsInFirstStrip[1]); - auto secondType = secondAction->FindValue("Type"); + auto secondType = secondAction->Get("Type"); - ASSERT_EQ(secondType->GetStringValue(), "FlyUp"); + ASSERT_EQ(secondType->GetValue(), "FlyUp"); - auto secondCallback = secondAction->FindValue("__callbackID__"); + auto secondCallback = secondAction->Get("__callbackID__"); - ASSERT_EQ(secondCallback->GetStringValue(), ""); + ASSERT_EQ(secondCallback->GetValue(), ""); - auto secondDistance = secondAction->FindValue("Distance"); + auto secondDistance = secondAction->Get("Distance"); - ASSERT_EQ(secondDistance->GetDoubleValue(), 25.0f); + ASSERT_EQ(secondDistance->GetValue(), 25.0f); auto thirdAction = dynamic_cast(actionsInFirstStrip[2]); - auto thirdType = thirdAction->FindValue("Type"); + auto thirdType = thirdAction->Get("Type"); - ASSERT_EQ(thirdType->GetStringValue(), "FlyDown"); + ASSERT_EQ(thirdType->GetValue(), "FlyDown"); - auto thirdCallback = thirdAction->FindValue("__callbackID__"); + auto thirdCallback = thirdAction->Get("__callbackID__"); - ASSERT_EQ(thirdCallback->GetStringValue(), ""); + ASSERT_EQ(thirdCallback->GetValue(), ""); - auto thirdDistance = thirdAction->FindValue("Distance"); + auto thirdDistance = thirdAction->Get("Distance"); - ASSERT_EQ(thirdDistance->GetDoubleValue(), 25.0f); + ASSERT_EQ(thirdDistance->GetValue(), 25.0f); } /** * @brief Tests that having no BitStream returns a nullptr. */ TEST(dCommonTests, AMFDeserializeNullTest) { - auto result = ReadFromBitStream(nullptr); + std::unique_ptr result(ReadFromBitStream(nullptr)); ASSERT_EQ(result.get(), nullptr); } @@ -361,25 +364,25 @@ TEST(dCommonTests, AMFBadConversionTest) { testFileStream.close(); - auto resultFromFn = ReadFromBitStream(&testBitStream); + std::unique_ptr resultFromFn(ReadFromBitStream(&testBitStream)); auto result = static_cast(resultFromFn.get()); // Actually a string value. - ASSERT_EQ(result->FindValue("BehaviorID"), nullptr); + ASSERT_EQ(result->Get("BehaviorID"), nullptr); // Does not exist in the associative portion - ASSERT_EQ(result->FindValue("DOES_NOT_EXIST"), nullptr); + ASSERT_EQ(result->Get("DOES_NOT_EXIST"), nullptr); - result->PushBackValue(new AMFTrueValue()); + result->Push(true); // Exists and is correct type - ASSERT_NE(result->GetValueAt(0), nullptr); + ASSERT_NE(result->Get(0), nullptr); // Value exists but is wrong typing - ASSERT_EQ(result->GetValueAt(0), nullptr); + ASSERT_EQ(result->Get(0), nullptr); // Value is out of bounds - ASSERT_EQ(result->GetValueAt(1), nullptr); + ASSERT_EQ(result->Get(1), nullptr); } /** diff --git a/tests/dCommonTests/Amf3Tests.cpp b/tests/dCommonTests/Amf3Tests.cpp new file mode 100644 index 00000000..a51fe4ba --- /dev/null +++ b/tests/dCommonTests/Amf3Tests.cpp @@ -0,0 +1,116 @@ +#include + +#include + +#include "Amf3.h" + +TEST(dCommonTests, AMF3AssociativeArrayTest) { + + AMFArrayValue array; + array.Insert("true", true); + array.Insert("false", false); + + // test associative can insert values + ASSERT_EQ(array.GetAssociative().size(), 2); + ASSERT_EQ(array.Get("true")->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get("false")->GetValueType(), eAmf::False); + + // Test associative can remove values + array.Remove("true"); + ASSERT_EQ(array.GetAssociative().size(), 1); + ASSERT_EQ(array.Get("true"), nullptr); + ASSERT_EQ(array.Get("false")->GetValueType(), eAmf::False); + + array.Remove("false"); + ASSERT_EQ(array.GetAssociative().size(), 0); + ASSERT_EQ(array.Get("true"), nullptr); + ASSERT_EQ(array.Get("false"), nullptr); + + // Test that multiple of the same key respect only the first element of that key + array.Insert("true", true); + array.Insert("true", false); + ASSERT_EQ(array.GetAssociative().size(), 1); + ASSERT_EQ(array.Get("true")->GetValueType(), eAmf::True); + array.Remove("true"); + + // Now test the dense portion + // Get some out of bounds values and cast to incorrect template types + array.Push(true); + array.Push(false); + + ASSERT_EQ(array.GetDense().size(), 2); + ASSERT_EQ(array.Get(0)->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(1)->GetValueType(), eAmf::False); + ASSERT_EQ(array.Get(155), nullptr); + + array.Pop(); + + ASSERT_EQ(array.GetDense().size(), 1); + ASSERT_EQ(array.Get(0)->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(1), nullptr); + + array.Pop(); + + ASSERT_EQ(array.GetDense().size(), 0); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(1), nullptr); +} + +TEST(dCommonTests, AMF3InsertionAssociativeTest) { + AMFArrayValue array; + array.Insert("CString", "string"); + array.Insert("String", std::string("string")); + array.Insert("False", false); + array.Insert("True", true); + array.Insert("Integer", 42U); + array.Insert("Double", 42.0); + array.InsertArray("Array"); + array.Insert>("Undefined", {}); + array.Insert("Null", nullptr); + + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("CString")->GetValueType(), eAmf::String); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("String")->GetValueType(), eAmf::String); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("False")->GetValueType(), eAmf::False); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("True")->GetValueType(), eAmf::True); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("Integer")->GetValueType(), eAmf::Integer); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("Double")->GetValueType(), eAmf::Double); + std::cout << "test" << std::endl; + ASSERT_EQ(array.GetArray("Array")->GetValueType(), eAmf::Array); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("Null")->GetValueType(), eAmf::Null); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get>("Undefined")->GetValueType(), eAmf::Undefined); + std::cout << "test" << std::endl; +} + +TEST(dCommonTests, AMF3InsertionDenseTest) { + AMFArrayValue array; + array.Push("string"); + array.Push("CString"); + array.Push(false); + array.Push(true); + array.Push(42U); + array.Push(42.0); + array.PushArray(); + array.Push(nullptr); + array.Push>({}); + + ASSERT_EQ(array.Get(0)->GetValueType(), eAmf::String); + ASSERT_EQ(array.Get(1)->GetValueType(), eAmf::String); + ASSERT_EQ(array.Get(2)->GetValueType(), eAmf::False); + ASSERT_EQ(array.Get(3)->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get(4)->GetValueType(), eAmf::Integer); + ASSERT_EQ(array.Get(5)->GetValueType(), eAmf::Double); + ASSERT_EQ(array.GetArray(6)->GetValueType(), eAmf::Array); + ASSERT_EQ(array.Get(7)->GetValueType(), eAmf::Null); + ASSERT_EQ(array.Get>(8)->GetValueType(), eAmf::Undefined); +} diff --git a/tests/dCommonTests/CMakeLists.txt b/tests/dCommonTests/CMakeLists.txt index 444afbdd..a345863d 100644 --- a/tests/dCommonTests/CMakeLists.txt +++ b/tests/dCommonTests/CMakeLists.txt @@ -1,5 +1,6 @@ set(DCOMMONTEST_SOURCES "AMFDeserializeTests.cpp" + "Amf3Tests.cpp" "HeaderSkipTest.cpp" "TestLDFFormat.cpp" "TestNiPoint3.cpp" diff --git a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp index 631f0d2d..047f56d6 100644 --- a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp +++ b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp @@ -1,5 +1,5 @@ #include "Action.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "AMFDeserialize.h" #include "GameMessages.h" #include "GameDependencies.h" @@ -40,8 +40,8 @@ protected: } AMFArrayValue* ReadArrayFromBitStream(RakNet::BitStream* inStream) { AMFDeserialize des; - AMFValue* readArray = des.Read(inStream); - EXPECT_EQ(readArray->GetValueType(), AMFValueType::AMFArray); + AMFBaseValue* readArray = des.Read(inStream); + EXPECT_EQ(readArray->GetValueType(), eAmf::Array); return static_cast(readArray); } }; From 2117a18d62bd4f7e7757b65f118b886a57ec06cc Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 13 May 2023 23:23:09 +0100 Subject: [PATCH 055/116] Enable artifact uploading and replace upload parameters (#1091) --- .github/workflows/build-and-test.yml | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index ab3917c1..8a81def7 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -36,22 +36,16 @@ jobs: testPreset: "ci-${{matrix.os}}" - name: artifacts uses: actions/upload-artifact@v3 - if: ${{ github.ref == 'ref/head/main' }} with: name: build-${{matrix.os}} path: | - build - !build/tests - !build/Testing - !build/CMakeFiles - !build/DartConfiguration.tcl - !build/CTestTestfile.cmake - !build/CMakeCache.txt - !build/build.ninja - !build/_deps - !build/cmake_install.cmake - !build/*.a - !build/*.lib - !build/*.dir - !build/*.vcxproj - !build/*.vcxproj.filters + build/*Server* + build/*.ini + build/*.so + build/*.dll + build/vanity/ + build/navmeshes/ + build/migrations/ + build/*.dcf + !build/*.pdb + !build/d*/ From 9708ea28dce2b659ecbae855ed62d6b9b0c4f6fc Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 13 May 2023 18:21:17 -0500 Subject: [PATCH 056/116] refactor: removed hardcoded ag laser logic (#1079) * Removed hardcoded laser logic * Address feedback --- .../02_server/Map/AG/AgLaserSensorServer.cpp | 61 +++++-------------- .../02_server/Map/AG/AgLaserSensorServer.h | 3 +- .../Map/AG/AgMonumentLaserServer.cpp | 25 ++++---- .../02_server/Map/AG/AgMonumentLaserServer.h | 6 +- 4 files changed, 30 insertions(+), 65 deletions(-) diff --git a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp index 703625d2..7fcea9fa 100644 --- a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp +++ b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp @@ -2,56 +2,27 @@ #include "PhantomPhysicsComponent.h" #include "SkillComponent.h" -#include "EntityManager.h" -#include "AgMonumentLaserServer.h" -#include "EntityManager.h" #include "ePhysicsEffectType.h" -#include "eReplicaComponentType.h" void AgLaserSensorServer::OnStartup(Entity* self) { - - PhantomPhysicsComponent* physComp = static_cast(self->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); - physComp->SetPhysicsEffectActive(true); - physComp->SetEffectType(ePhysicsEffectType::REPULSE); - physComp->SetDirectionalMultiplier(static_cast(m_RepelForce)); - physComp->SetDirection(NiPoint3::UNIT_Y); - - m_Skill = self->GetComponent(); + self->SetBoolean(u"active", true); + auto repelForce = self->GetVarAs(u"repelForce"); + if (!repelForce) repelForce = m_RepelForce; + auto* phantomPhysicsComponent = self->GetComponent(); + if (!phantomPhysicsComponent) return; + phantomPhysicsComponent->SetPhysicsEffectActive(true); + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE); + phantomPhysicsComponent->SetDirectionalMultiplier(repelForce); + phantomPhysicsComponent->SetDirection(NiPoint3::UNIT_Y); } void AgLaserSensorServer::OnCollisionPhantom(Entity* self, Entity* target) { - - if (!m_Skill) return; - - - Entity* laser = nullptr; - - for (auto script : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT)) { - - AgMonumentLaserServer* hasLaser = (AgMonumentLaserServer*)script; - - if (hasLaser) { - const auto source = script->GetPosition(); - const auto obj = self->GetObjectID(); - - if (obj == 76690936093053 && Vector3::DistanceSquared(source, NiPoint3(149.007f, 417.083f, 218.346f)) <= 1.0f) { - laser = script; - break; - } else if (obj == 75866302318824 && Vector3::DistanceSquared(source, NiPoint3(48.6403f, 403.803f, 196.711f)) <= 1.0f) { - laser = script; - break; - } else if (obj == 75866302318822 && Vector3::DistanceSquared(source, NiPoint3(19.2155f, 420.083f, 249.226f)) <= 1.0f) { - laser = script; - break; - } else if (obj == 75866302318823 && Vector3::DistanceSquared(source, NiPoint3(-6.61596f, 404.633f, 274.323f)) <= 1.0f) { - laser = script; - break; - } - } - } - - if (laser != nullptr) { - m_Skill->CalculateBehavior(m_SkillCastID, 15714, target->GetObjectID()); - } + auto active = self->GetVar(u"active"); + if (!active) return; + auto skillCastID = self->GetVarAs(u"skillCastID"); + if (skillCastID == 0) skillCastID = m_SkillCastID; + auto* skillComponent = self->GetComponent(); + if (!skillComponent) return; + skillComponent->CastSkill(m_SkillCastID, target->GetObjectID()); } diff --git a/dScripts/02_server/Map/AG/AgLaserSensorServer.h b/dScripts/02_server/Map/AG/AgLaserSensorServer.h index 72e09dd8..ee7fb6ec 100644 --- a/dScripts/02_server/Map/AG/AgLaserSensorServer.h +++ b/dScripts/02_server/Map/AG/AgLaserSensorServer.h @@ -8,8 +8,7 @@ public: void OnStartup(Entity* self); void OnCollisionPhantom(Entity* self, Entity* target); private: - SkillComponent* m_Skill; - int m_RepelForce = -25; + float m_RepelForce = -25.0f; int m_SkillCastID = 163; }; diff --git a/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp b/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp index 6efda89e..b2062935 100644 --- a/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp @@ -1,20 +1,17 @@ #include "AgMonumentLaserServer.h" +#include "EntityManager.h" void AgMonumentLaserServer::OnStartup(Entity* self) { - /* - self->SetProximityRadius(m_Radius, "MonumentLaser"); - - std::cout << "Monument Laser " << self->GetObjectID() << " is at " << self->GetPosition().GetX() - << ","<< self->GetPosition().GetY() << "," << self->GetPosition().GetZ() << std::endl; - */ -} - -void AgMonumentLaserServer::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - /* - if (status == "ENTER") { - - std::cout << "Monument laser ID: " << self->GetObjectID() << std::endl; + auto lasers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); + for (auto laser : lasers) { + if (laser) laser->SetBoolean(u"active", true); + } +} + +void AgMonumentLaserServer::OnDie(Entity* self, Entity* killer) { + auto lasers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); + for (auto laser : lasers) { + if (laser) laser->SetBoolean(u"active", false); } - */ } diff --git a/dScripts/02_server/Map/AG/AgMonumentLaserServer.h b/dScripts/02_server/Map/AG/AgMonumentLaserServer.h index 56979c55..8163948b 100644 --- a/dScripts/02_server/Map/AG/AgMonumentLaserServer.h +++ b/dScripts/02_server/Map/AG/AgMonumentLaserServer.h @@ -3,8 +3,6 @@ class AgMonumentLaserServer : public CppScripts::Script { public: - void OnStartup(Entity* self); - void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status); -private: - float m_Radius = 25.0f; + void OnStartup(Entity* self) override; + void OnDie(Entity* self, Entity* killer) override; }; From 1f3df0873055eeca0468a566292f7890a85d23fa Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 13 May 2023 16:22:13 -0700 Subject: [PATCH 057/116] Update GameMessages.cpp --- dGame/dGameMessages/GameMessages.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index f7bd3b7d..c178f6c7 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -70,6 +70,7 @@ #include "PetComponent.h" #include "ModuleAssemblyComponent.h" #include "VehiclePhysicsComponent.h" +#include "RenderComponent.h" #include "PossessableComponent.h" #include "PossessorComponent.h" #include "RacingControlComponent.h" From 59387e5fe3c4a37d294d573c20624e300cc98252 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Wed, 17 May 2023 13:17:34 -0500 Subject: [PATCH 058/116] fix: update type in am blue x script (#1095) Fixes #1094 --- dScripts/02_server/Map/AM/AmBlueX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dScripts/02_server/Map/AM/AmBlueX.cpp b/dScripts/02_server/Map/AM/AmBlueX.cpp index 312cdc47..8e32694c 100644 --- a/dScripts/02_server/Map/AM/AmBlueX.cpp +++ b/dScripts/02_server/Map/AM/AmBlueX.cpp @@ -18,7 +18,7 @@ void AmBlueX::OnSkillEventFired(Entity* self, Entity* caster, const std::string& auto* character = caster->GetCharacter(); if (character != nullptr) { - character->SetPlayerFlag(self->GetVar(m_FlagVariable), true); + character->SetPlayerFlag(self->GetVar(m_FlagVariable), true); } EntityInfo info{}; From 238751f14ee1bcbb95643e0781e45e137c466475 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 25 May 2023 13:29:46 -0700 Subject: [PATCH 059/116] Remove extra cout (#1101) --- dCommon/Amf3.h | 1 - 1 file changed, 1 deletion(-) diff --git a/dCommon/Amf3.h b/dCommon/Amf3.h index 4dba039f..4c649524 100644 --- a/dCommon/Amf3.h +++ b/dCommon/Amf3.h @@ -342,7 +342,6 @@ public: */ template AMFValue* Get(uint32_t index) const { - std::cout << (index < this->dense.size()) << std::endl; return index < this->dense.size() ? dynamic_cast*>(this->dense.at(index)) : nullptr; From e47169fec580a6d4a7b00711f3067eed34c95a0f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 26 May 2023 21:22:31 -0700 Subject: [PATCH 060/116] Fix: Some platforms not using the same RNG for every roll (#1103) * Test changes * Update ObjectIDManager.h * Revert "Update ObjectIDManager.h" This reverts commit 3e4d169718d0bc64b61fb5feaf39437ca4284294. * Revert "Test changes" This reverts commit 8e16573f937473785f91e04a13b177084fee3ed0. * Use random engine --- dWorldServer/ObjectIDManager.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/dWorldServer/ObjectIDManager.cpp b/dWorldServer/ObjectIDManager.cpp index ef5fb9a5..9490c0a7 100644 --- a/dWorldServer/ObjectIDManager.cpp +++ b/dWorldServer/ObjectIDManager.cpp @@ -1,8 +1,5 @@ #include "ObjectIDManager.h" -// Std -#include - // Custom Classes #include "MasterPackets.h" #include "Database.h" @@ -48,11 +45,7 @@ void ObjectIDManager::HandleRequestPersistentIDResponse(uint64_t requestID, uint //! Handles cases where we have to get a unique object ID synchronously uint32_t ObjectIDManager::GenerateRandomObjectID() { - std::random_device rd; - - std::mt19937 rng(rd()); - - return uni(rng); + return uni(Game::randomEngine); } From f26e66da4d1fe8a2575ba81d961f21921e7b6d9c Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 28 May 2023 04:30:20 -0700 Subject: [PATCH 061/116] small updates to typs --- dGame/LeaderboardManager.cpp | 26 ++++++++++++-------------- dGame/LeaderboardManager.h | 13 +++++++------ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 4b236384..81cdbb8b 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -41,24 +41,23 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) { std::ostringstream leaderboard; Game::logger->Log("LeaderboardManager", "game is %i info type %i ", gameID, infoType); leaderboard << "ADO.Result=7:1"; // Unused in 1.10.64, but is in captures - leaderboard << "\nResult.Count=1:1"; // number of results, always 1? - if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key" - leaderboard << "\nResult[0].RowCount=1:" << entries.size(); // number of rows + leaderboard << "\nResult.Count=1:1"; // number of results, always 1 + if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key". Live doesn't include this if there are no entries. + leaderboard << "\nResult[0].RowCount=1:" << entries.size(); int32_t rowNumber = 0; for (auto& entry : entries) { for (auto* data : entry) { - Game::logger->Log("LeaderboardManager", "writing data %s", data->GetString().c_str()); WriteLeaderboardRow(leaderboard, rowNumber, data); } rowNumber++; } - Game::logger->Log("LeaderboardManager", "leaderboard is %s", leaderboard.str().c_str()); + // Serialize the thing to a BitStream uint32_t leaderboardSize = leaderboard.tellp(); bitStream->Write(leaderboardSize); // Doing this all in 1 call so there is no possbility of a dangling pointer. - bitStream->WriteAlignedBytes(reinterpret_cast(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboard.tellp() * 2); + bitStream->WriteAlignedBytes(reinterpret_cast(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboardSize * sizeof(char16_t)); if (leaderboardSize > 0) bitStream->Write(0); bitStream->Write0(); bitStream->Write0(); @@ -90,7 +89,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); switch (leaderboardType) { case Type::ShootingGallery: - entry.push_back(new LDFData(u"HitPercentage", rows->getDouble("hitPercentage"))); + entry.push_back(new LDFData(u"HitPercentage", (rows->getInt("hitPercentage") / 100.0f))); // HitPercentage:3 between 0 and 1 entry.push_back(new LDFData(u"Score", rows->getInt("score"))); // Score:1 @@ -144,7 +143,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { } } -std::string Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { +const std::string Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { std::string columns; switch (leaderboardType) { case Type::ShootingGallery: @@ -178,7 +177,7 @@ std::string Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { return columns; } -std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { +const std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { std::string columns; switch (leaderboardType) { case Type::ShootingGallery: @@ -212,7 +211,7 @@ std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { return columns; } -std::string Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { +const std::string Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { std::string orderBase; switch (leaderboardType) { case Type::ShootingGallery: @@ -297,8 +296,8 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { ) )QUERY"; - std::string orderBase = GetOrdering(this->leaderboardType); - std::string selectBase = GetColumns(this->leaderboardType); + const std::string orderBase = GetOrdering(this->leaderboardType); + const std::string selectBase = GetColumns(this->leaderboardType); constexpr uint16_t STRING_LENGTH = 1526; char lookupBuffer[STRING_LENGTH]; @@ -327,13 +326,12 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { } std::unique_ptr baseResult(baseQuery->executeQuery()); - Game::logger->Log("LeaderboardManager", "%s", baseRankingBuffer); + if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game. uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); // Create and execute the actual save here - Game::logger->Log("LeaderboardManager", "query is %s", lookupBuffer); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); query->setInt(1, this->gameID); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index f84e4228..6a7ba665 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -20,8 +20,6 @@ typedef uint32_t GameID; class Leaderboard { public: - using LeaderboardEntry = std::vector; - using LeaderboardEntries = std::vector; // Enums for leaderboards enum InfoType : uint32_t { @@ -76,9 +74,9 @@ public: void Send(LWOOBJID targetID); // Helper functions to get the columns, ordering and insert format for a leaderboard - static std::string GetColumns(Type leaderboardType); - static std::string GetInsertFormat(Type leaderboardType); - static std::string GetOrdering(Type leaderboardType); + static const std::string GetColumns(Type leaderboardType); + static const std::string GetInsertFormat(Type leaderboardType); + static const std::string GetOrdering(Type leaderboardType); private: inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data); @@ -89,6 +87,9 @@ private: // to send it to a client. void QueryToLdf(std::unique_ptr& rows); + using LeaderboardEntry = std::vector; + using LeaderboardEntries = std::vector; + LeaderboardEntries entries; LWOOBJID relatedPlayer; GameID gameID; @@ -98,7 +99,7 @@ private: }; class LeaderboardManager : public Singleton { - typedef std::map LeaderboardCache; + using LeaderboardCache = std::map; public: void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10); From 0107d05d55364fd01a9e5241275585577abbbcf3 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 30 May 2023 04:11:37 -0700 Subject: [PATCH 062/116] draft --- dGame/LeaderboardManager.cpp | 215 ++++++------------ dGame/LeaderboardManager.h | 61 +++-- dGame/dComponents/RacingControlComponent.cpp | 4 +- dGame/dGameMessages/GameMessages.cpp | 2 +- .../02_server/Map/AG/NpcAgCourseStarter.cpp | 2 +- dScripts/ActivityManager.cpp | 4 +- .../dlu/9_Update_Leaderboard_Storage.sql | 10 +- 7 files changed, 123 insertions(+), 175 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 81cdbb8b..d153a1fd 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -11,12 +11,15 @@ #include "GeneralUtils.h" #include "Entity.h" #include "LDFFormat.h" +#include "DluAssert.h" #include #include "CDActivitiesTable.h" #include "Metrics.hpp" -LeaderboardManager::LeaderboardCache LeaderboardManager::leaderboardCache = {}; +namespace LeaderboardManager { + LeaderboardCache leaderboardCache; +} Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type leaderboardType) { this->gameID = gameID; @@ -143,7 +146,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { } } -const std::string Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { +const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { std::string columns; switch (leaderboardType) { case Type::ShootingGallery: @@ -177,7 +180,7 @@ const std::string Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { return columns; } -const std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { +const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { std::string columns; switch (leaderboardType) { case Type::ShootingGallery: @@ -211,7 +214,7 @@ const std::string Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType return columns; } -const std::string Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { +const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { std::string orderBase; switch (leaderboardType) { case Type::ShootingGallery: @@ -296,19 +299,18 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { ) )QUERY"; - const std::string orderBase = GetOrdering(this->leaderboardType); - const std::string selectBase = GetColumns(this->leaderboardType); + const auto orderBase = GetOrdering(this->leaderboardType); + const auto selectBase = GetColumns(this->leaderboardType); constexpr uint16_t STRING_LENGTH = 1526; char lookupBuffer[STRING_LENGTH]; // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. if (this->infoType == InfoType::Friends) { - snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), - orderBase.c_str(), friendsQuery, selectBase.c_str(), resultStart, resultEnd); - } - else { - snprintf(lookupBuffer, STRING_LENGTH, queryBase.c_str(), - orderBase.c_str(), "", selectBase.c_str(), resultStart, resultEnd); + snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), + orderBase.data(), friendsQuery, selectBase.data(), resultStart, resultEnd); + } else { + snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), + orderBase.data(), "", selectBase.data(), resultStart, resultEnd); } std::string baseLookupStr; @@ -355,186 +357,99 @@ void Leaderboard::Send(LWOOBJID targetID) { } } -void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...) { - va_list args; - va_start(args, argumentCount); - SaveScore(playerID, gameID, leaderboardType, args); - va_end(args); -} +std::string LeaderboardManager::FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate) { + auto insertFormat = Leaderboard::GetInsertFormat(type); -std::string FormatInsert(const std::string& columns, const std::string& format, va_list args, bool useUpdate) { - const char* insertClause = "INSERT"; - const char* updateClause = "UPDATE"; - const char* queryType = useUpdate ? updateClause : insertClause; + auto* queryType = useUpdate ? "UPDATE" : "INSERT"; - const char* insertFilter = ", character_id = ?, game_id = ?, timesPlayed = 1"; - const char* updateFilter = ", timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?"; - const char* usedFilter = useUpdate ? updateFilter : insertFilter; + auto* usedFilter = useUpdate ? + ", timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?" : + ", character_id = ?, game_id = ?"; + // First fill in the format constexpr uint16_t STRING_LENGTH = 400; char formattedInsert[STRING_LENGTH]; - auto queryBase = "%s leaderboard SET %s %s;"; - snprintf(formattedInsert, STRING_LENGTH, queryBase, queryType, format.c_str(), usedFilter); + snprintf(formattedInsert, STRING_LENGTH, "%s leaderboard SET %s %s;", queryType, insertFormat.data(), usedFilter); + // Then fill in our score char finishedQuery[STRING_LENGTH]; - vsnprintf(finishedQuery, STRING_LENGTH, formattedInsert, args); + snprintf(finishedQuery, STRING_LENGTH, formattedInsert, score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); + DluAssert() return finishedQuery; } -void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list activityScore) { - std::string selectedColumns = Leaderboard::GetColumns(leaderboardType); - std::string insertFormat = Leaderboard::GetInsertFormat(leaderboardType); - const char* lookup = "SELECT %s FROM leaderboard WHERE character_id = ? AND game_id = ?;"; +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t primaryScore, uint32_t secondaryScore, uint32_t tertiaryScore) { + auto* lookup = "SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;"; - constexpr uint16_t STRING_LENGTH = 400; - char lookupBuffer[STRING_LENGTH]; - snprintf(lookupBuffer, STRING_LENGTH, lookup, selectedColumns.c_str()); - - std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); + std::unique_ptr query(Database::CreatePreppedStmt(lookup)); query->setInt(1, playerID); query->setInt(2, gameID); std::unique_ptr myScoreResult(query->executeQuery()); - std::va_list argsCopy; - va_copy(argsCopy, activityScore); std::string saveQuery; + Score newScore(primaryScore, secondaryScore, tertiaryScore); if (myScoreResult->next()) { + Score oldScore; + bool lowerScoreBetter = false; switch (leaderboardType) { + // Higher score better case Leaderboard::Type::ShootingGallery: { - int32_t oldScore = myScoreResult->getInt("score"); - int32_t score; - score = va_arg(argsCopy, int32_t); - - int32_t oldHitPercentage = myScoreResult->getFloat("hitPercentage"); - int32_t hitPercentage; - hitPercentage = va_arg(argsCopy, int32_t); - - int32_t oldStreak = myScoreResult->getInt("streak"); - int32_t streak; - streak = va_arg(argsCopy, int32_t); - - if (score > oldScore || // If score is better - (score == oldScore && hitPercentage > oldHitPercentage) || // or if the score is tied and the hitPercentage is better - (score == oldScore && hitPercentage == oldHitPercentage && streak > oldStreak)) { // or if the score and hitPercentage are tied and the streak is better - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } - break; - } - case Leaderboard::Type::Racing: { - uint32_t oldLapTime = myScoreResult->getFloat("bestLapTime"); - uint32_t lapTime; - lapTime = va_arg(argsCopy, uint32_t); - - uint32_t oldTime = myScoreResult->getFloat("bestTime"); - uint32_t newTime; - newTime = va_arg(argsCopy, uint32_t); - - bool won; - won = va_arg(argsCopy, int32_t); - - if (newTime < oldTime || - (newTime == oldTime && lapTime < oldLapTime)) { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } else if (won) { - std::unique_ptr incrementStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;")); - incrementStatement->setInt(1, playerID); - incrementStatement->setInt(2, gameID); - incrementStatement->executeUpdate(); - } - break; - } - case Leaderboard::Type::UnusedLeaderboard4: { - int32_t oldScore = myScoreResult->getInt("score"); - int32_t points; - points = va_arg(argsCopy, int32_t); - - if (points > oldScore) { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } - break; - } - case Leaderboard::Type::MonumentRace: { - int32_t oldTime = myScoreResult->getInt("bestTime"); - int32_t time; - time = va_arg(argsCopy, int32_t); - - if (time < oldTime) { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } + oldScore.SetPrimaryScore(myScoreResult->getInt("score")); + oldScore.SetSecondaryScore(myScoreResult->getInt("hitPercentage")); + oldScore.SetTertiaryScore(myScoreResult->getInt("streak")); break; } case Leaderboard::Type::FootRace: { - int32_t oldTime = myScoreResult->getInt("bestTime"); - int32_t time; - time = va_arg(argsCopy, int32_t); - - if (time > oldTime) { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } + oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); break; } case Leaderboard::Type::Survival: { - int32_t oldTime = myScoreResult->getInt("bestTime"); - int32_t time; - time = va_arg(argsCopy, int32_t); - - int32_t oldPoints = myScoreResult->getInt("score"); - int32_t points; - points = va_arg(argsCopy, int32_t); - - if (points > oldPoints || (points == oldPoints && time < oldTime)) { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } + // Config option may reverse these + oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); + oldScore.SetSecondaryScore(myScoreResult->getInt("score")); break; } case Leaderboard::Type::SurvivalNS: { - int32_t oldTime = myScoreResult->getInt("bestTime"); - int32_t time; - time = va_arg(argsCopy, int32_t); - - int32_t oldWave = myScoreResult->getInt("score"); - int32_t wave; - wave = va_arg(argsCopy, int32_t); - - if (time < oldTime || (time == oldTime && wave > oldWave)) { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } + oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); + oldScore.SetSecondaryScore(myScoreResult->getInt("score")); break; } + case Leaderboard::Type::UnusedLeaderboard4: case Leaderboard::Type::Donations: { - int32_t oldScore = myScoreResult->getInt("score"); - int32_t score; - score = va_arg(argsCopy, int32_t); - - if (score > oldScore) { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, true); - } + oldScore.SetPrimaryScore(myScoreResult->getInt("score")); break; } + case Leaderboard::Type::Racing: + oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); + oldScore.SetSecondaryScore(myScoreResult->getInt("bestLapTime")); + lowerScoreBetter = true; + break; + case Leaderboard::Type::MonumentRace: + oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); + lowerScoreBetter = true; + // Do score checking here + break; case Leaderboard::Type::None: default: - Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); - va_end(argsCopy); + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); return; } + bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore; + if (newHighScore) { + saveQuery = FormatInsert(leaderboardType, newScore, true); + } else if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore) { + saveQuery = "UPDATE leaderboard SET numWins = numWins + 1, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"; + } else { + saveQuery = "UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"; + } } else { - saveQuery = FormatInsert(selectedColumns, insertFormat, activityScore, false); - } - std::unique_ptr saveStatement; - if (!saveQuery.empty()) { - Game::logger->Log("LeaderboardManager", "Executing update with query %s", saveQuery.c_str()); - std::unique_ptr updateStatement(Database::CreatePreppedStmt(saveQuery)); - saveStatement = std::move(updateStatement); - } else { - Game::logger->Log("LeaderboardManager", "No new score to save, incrementing numTimesPlayed"); - // Increment the numTimes this player has played this game. - std::unique_ptr updateStatement(Database::CreatePreppedStmt("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;")); - saveStatement = std::move(updateStatement); + saveQuery = FormatInsert(leaderboardType, newScore, false); } + + std::unique_ptr saveStatement(Database::CreatePreppedStmt(saveQuery)); saveStatement->setInt(1, playerID); saveStatement->setInt(2, gameID); saveStatement->execute(); - va_end(argsCopy); } void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart, uint32_t resultEnd) { diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 6a7ba665..0d810a67 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -1,7 +1,8 @@ -#pragma once -#include +#ifndef __LEADERBOARDMANAGER__H__ +#define __LEADERBOARDMANAGER__H__ + #include -#include +#include #include #include "Singleton.h" @@ -62,7 +63,7 @@ public: /** * Builds the leaderboard from the database based on the associated gameID - * + * * @param resultStart The index to start the leaderboard at. Zero indexed. * @param resultEnd The index to end the leaderboard at. Zero indexed. */ @@ -74,9 +75,9 @@ public: void Send(LWOOBJID targetID); // Helper functions to get the columns, ordering and insert format for a leaderboard - static const std::string GetColumns(Type leaderboardType); - static const std::string GetInsertFormat(Type leaderboardType); - static const std::string GetOrdering(Type leaderboardType); + static const std::string_view GetColumns(Type leaderboardType); + static const std::string_view GetInsertFormat(Type leaderboardType); + static const std::string_view GetOrdering(Type leaderboardType); private: inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data); @@ -98,9 +99,40 @@ private: bool weekly; }; -class LeaderboardManager : public Singleton { +namespace LeaderboardManager { + class Score { + public: + Score() { + primaryScore = 0; + secondaryScore = 0; + tertiaryScore = 0; + } + Score(uint32_t primaryScore, uint32_t secondaryScore = 0, uint32_t tertiaryScore = 0) { + this->primaryScore = primaryScore; + this->secondaryScore = secondaryScore; + this->tertiaryScore = tertiaryScore; + } + bool operator<(const Score& rhs) const { + return primaryScore < rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore < rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore < rhs.tertiaryScore); + } + bool operator>(const Score& rhs) const { + return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore); + } + void SetPrimaryScore(const uint32_t score) { primaryScore = score; } + uint32_t GetPrimaryScore() const { return primaryScore; } + + void SetSecondaryScore(const uint32_t score) { secondaryScore = score; } + uint32_t GetSecondaryScore() const { return secondaryScore; } + + void SetTertiaryScore(const uint32_t score) { tertiaryScore = score; } + uint32_t GetTertiaryScore() const { return tertiaryScore; } + private: + uint32_t primaryScore; + uint32_t secondaryScore; + uint32_t tertiaryScore; + }; + using LeaderboardCache = std::map; -public: void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10); /** @@ -111,12 +143,13 @@ public: * @param argumentCount The number of arguments in the va_list * @param ... The score to save */ - void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...); + void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t primaryScore, uint32_t secondaryScore = 0, uint32_t tertiaryScore = 0); - static Leaderboard::Type GetLeaderboardType(const GameID gameID); - static LeaderboardCache leaderboardCache; -private: - void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args); void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); + std::string FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate); + + Leaderboard::Type GetLeaderboardType(const GameID gameID); + extern LeaderboardCache leaderboardCache; }; +#endif //!__LEADERBOARDMANAGER__H__ diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index f74c92fa..efd6b44e 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -400,8 +400,8 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, const auto score = m_LoadedPlayers * 10 + data->finished; LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); - auto leaderboardType = LeaderboardManager::Instance().GetLeaderboardType(m_ActivityID); - LeaderboardManager::Instance().SaveScore(player->GetObjectID(), m_ActivityID, leaderboardType, 3, data->bestLapTime, data->raceTime, data->finished == 1); + // auto leaderboardType = LeaderboardManager::Instance().GetLeaderboardType(m_ActivityID); + // LeaderboardManager::Instance().SaveScore(player->GetObjectID(), m_ActivityID, leaderboardType, 3, data->bestLapTime, data->raceTime, data->finished == 1); // Giving rewards GameMessages::SendNotifyRacingClient( diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index dae0636a..5bdec2ac 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1661,7 +1661,7 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream->ReadBit(); - LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID(), resultsStart, resultsEnd); + // LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID(), resultsStart, resultsEnd); } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index 670fd7ee..20e749ee 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -94,7 +94,7 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std EntityManager::Instance()->SerializeEntity(self); auto leaderboardType = LeaderboardManager::GetLeaderboardType(scriptedActivityComponent->GetActivityID()); - LeaderboardManager::Instance().SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), leaderboardType, 1, finish); + // LeaderboardManager::Instance().SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), leaderboardType, 1, finish); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", scriptedActivityComponent->GetActivityID(), 0, sender->GetObjectID(), diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 85365e01..96186688 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -88,7 +88,7 @@ void ActivityManager::SaveScore(Entity* self, LWOOBJID playerID, uint32_t val1, // Save the new score to the leaderboard and show the leaderboard to the player auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); Game::logger->Log("ActivityManager", "leaderboard type %i %i args %i %i %i", leaderboardType, gameID, val1, val2, val3); - LeaderboardManager::Instance().SaveScore(playerID, gameID, leaderboardType, 3, val1, val2, val3); + // LeaderboardManager::Instance().SaveScore(playerID, gameID, leaderboardType, 3, val1, val2, val3); // Makes the leaderboard show up for the player GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", gameID, 0, playerID, "", player->GetSystemAddress()); @@ -125,7 +125,7 @@ void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID, // Save the new score to the leaderboard and show the leaderboard to the player auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); Game::logger->Log("ActivityManager", "gameID %i", gameID, activityID); - LeaderboardManager::Instance().SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID(), 0, numResults); + // LeaderboardManager::Instance().SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID(), 0, numResults); } void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval, diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index c90ba4a2..6721e74e 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -1,12 +1,12 @@ ALTER TABLE leaderboard - ADD COLUMN hitPercentage FLOAT NOT NULL DEFAULT 0, + ADD COLUMN hitPercentage INT NOT NULL DEFAULT 0, ADD COLUMN streak INT NOT NULL DEFAULT 0, - ADD COLUMN bestLapTime FLOAT NOT NULL DEFAULT 0, + ADD COLUMN bestLapTime INT NOT NULL DEFAULT 0, ADD COLUMN numWins INT NOT NULL DEFAULT 0, - ADD COLUMN timesPlayed INT NOT NULL DEFAULT 0, - MODIFY time FLOAT NOT NULL DEFAULT 0; + ADD COLUMN timesPlayed INT NOT NULL DEFAULT 1, + MODIFY time INT NOT NULL DEFAULT 0; -ALTER TABLE leaderboard CHANGE time bestTime float; +ALTER TABLE leaderboard CHANGE time bestTime INT; ALTER TABLE leaderboard CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); UPDATE leaderboard SET streak = bestTime where game_id = 1864; From 7b1626901a13a19bd85b26e20cf03bc489365d4a Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 30 May 2023 04:18:32 -0700 Subject: [PATCH 063/116] Add some debug asserts --- dGame/LeaderboardManager.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d153a1fd..3af5abce 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -1,3 +1,5 @@ +#define _DEBUG + #include "LeaderboardManager.h" #include #include "Database.h" @@ -318,7 +320,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { bool neededFormatting = GetRankingQuery(baseLookupStr); // If we need to format the base ranking query, do so, otherwise just copy the query since it's already formatted. - if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.c_str()); + if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.data()); else std::copy(baseLookupStr.begin(), baseLookupStr.end() + 1, baseRankingBuffer); std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseRankingBuffer)); @@ -369,12 +371,13 @@ std::string LeaderboardManager::FormatInsert(const Leaderboard::Type& type, cons // First fill in the format constexpr uint16_t STRING_LENGTH = 400; char formattedInsert[STRING_LENGTH]; - snprintf(formattedInsert, STRING_LENGTH, "%s leaderboard SET %s %s;", queryType, insertFormat.data(), usedFilter); + int32_t res = snprintf(formattedInsert, STRING_LENGTH, "%s leaderboard SET %s %s;", queryType, insertFormat.data(), usedFilter); + DluAssert(res != -1); // Then fill in our score char finishedQuery[STRING_LENGTH]; - snprintf(finishedQuery, STRING_LENGTH, formattedInsert, score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); - DluAssert() + res = snprintf(finishedQuery, STRING_LENGTH, formattedInsert, score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); + DluAssert(res != -1); return finishedQuery; } @@ -386,7 +389,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead query->setInt(2, gameID); std::unique_ptr myScoreResult(query->executeQuery()); - std::string saveQuery; + std::string saveQuery("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"); Score newScore(primaryScore, secondaryScore, tertiaryScore); if (myScoreResult->next()) { Score oldScore; @@ -439,8 +442,6 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead saveQuery = FormatInsert(leaderboardType, newScore, true); } else if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore) { saveQuery = "UPDATE leaderboard SET numWins = numWins + 1, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"; - } else { - saveQuery = "UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"; } } else { saveQuery = FormatInsert(leaderboardType, newScore, false); From f5f599764d8bdcb4a439ad8a39581f78e5de264c Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 30 May 2023 04:23:48 -0700 Subject: [PATCH 064/116] more const and views --- dGame/LeaderboardManager.cpp | 26 ++++++++------------------ dGame/LeaderboardManager.h | 2 +- dGame/dGameMessages/GameMessages.cpp | 2 +- dGame/dGameMessages/GameMessages.h | 2 +- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 3af5abce..695978fb 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -149,7 +149,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { } const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { - std::string columns; + const char* columns; switch (leaderboardType) { case Type::ShootingGallery: columns = "hitPercentage, score, streak"; @@ -157,12 +157,11 @@ const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType case Type::Racing: columns = "bestLapTime, bestTime, numWins"; break; + case Type::Donations: case Type::UnusedLeaderboard4: columns = "score"; break; case Type::MonumentRace: - columns = "bestTime"; - break; case Type::FootRace: columns = "bestTime"; break; @@ -172,9 +171,6 @@ const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType case Type::SurvivalNS: columns = "bestTime, score"; break; - case Type::Donations: - columns = "score"; - break; case Type::None: // This type is included here simply to resolve a compiler warning on mac about unused enum types break; @@ -183,7 +179,7 @@ const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType } const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { - std::string columns; + const char* columns; switch (leaderboardType) { case Type::ShootingGallery: columns = "score=%i, hitPercentage=%i, streak=%i"; @@ -191,12 +187,11 @@ const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboar case Type::Racing: columns = "bestLapTime=%i, bestTime=%i, numWins=numWins + %i"; break; + case Type::Donations: case Type::UnusedLeaderboard4: columns = "score=%i"; break; case Type::MonumentRace: - columns = "bestTime=%i"; - break; case Type::FootRace: columns = "bestTime=%i"; break; @@ -206,9 +201,6 @@ const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboar case Type::SurvivalNS: columns = "bestTime=%i, score=%i"; break; - case Type::Donations: - columns = "score=%i"; - break; case Type::None: // This type is included here simply to resolve a compiler warning on mac about unused enum types break; @@ -217,7 +209,7 @@ const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboar } const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { - std::string orderBase; + const char* orderBase; switch (leaderboardType) { case Type::ShootingGallery: orderBase = "score DESC, streak DESC, hitPercentage DESC"; @@ -225,6 +217,7 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp case Type::Racing: orderBase = "bestTime ASC, bestLapTime ASC, numWins DESC"; break; + case Type::Donations: case Type::UnusedLeaderboard4: orderBase = "score DESC"; break; @@ -240,9 +233,6 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp case Type::SurvivalNS: orderBase = "bestTime DESC, score DESC"; break; - case Type::Donations: - orderBase = "score DESC"; - break; case Type::None: // This type is included here simply to resolve a compiler warning on mac about unused enum types break; @@ -352,7 +342,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { QueryToLdf(result); } -void Leaderboard::Send(LWOOBJID targetID) { +void Leaderboard::Send(const LWOOBJID targetID) const { auto* player = EntityManager::Instance()->GetEntity(relatedPlayer); if (player != nullptr) { GameMessages::SendActivitySummaryLeaderboardData(targetID, this, player->GetSystemAddress()); @@ -465,7 +455,7 @@ Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { auto* activitiesTable = CDClientManager::Instance().GetTable(); std::vector activities = activitiesTable->Query([=](const CDActivities& entry) { - return (entry.ActivityID == gameID); + return entry.ActivityID == gameID; }); auto type = !activities.empty() ? static_cast(activities.at(0).leaderboardType) : Leaderboard::Type::None; leaderboardCache.insert_or_assign(gameID, type); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 0d810a67..8f39aac4 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -72,7 +72,7 @@ public: /** * Sends the leaderboard to the client specified by targetID. */ - void Send(LWOOBJID targetID); + void Send(const LWOOBJID targetID) const; // Helper functions to get the columns, ordering and insert format for a leaderboard static const std::string_view GetColumns(Type leaderboardType); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 5deeb393..b78cacda 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1639,7 +1639,7 @@ void GameMessages::HandleActivitySummaryLeaderboardData(RakNet::BitStream* instr Game::logger->Log("AGS", "We got mail!"); } -void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, Leaderboard* leaderboard, const SystemAddress& sysAddr) { +void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, const Leaderboard* leaderboard, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index d64248e4..7e7a8f70 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -561,7 +561,7 @@ namespace GameMessages { void SendUpdateReputation(const LWOOBJID objectId, const int64_t reputation, const SystemAddress& sysAddr); // Leaderboards - void SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, Leaderboard* leaderboard, + void SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, const Leaderboard* leaderboard, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS); void HandleActivitySummaryLeaderboardData(RakNet::BitStream* instream, Entity* entity, const SystemAddress& sysAddr); void SendRequestActivitySummaryLeaderboardData(const LWOOBJID& objectID, const LWOOBJID& targetID, From 83da45575e745f1df92c90fbb8a124e9a35fa2ad Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 30 May 2023 04:28:50 -0700 Subject: [PATCH 065/116] CONST --- dGame/LeaderboardManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 8f39aac4..fe5bc16d 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -107,7 +107,7 @@ namespace LeaderboardManager { secondaryScore = 0; tertiaryScore = 0; } - Score(uint32_t primaryScore, uint32_t secondaryScore = 0, uint32_t tertiaryScore = 0) { + Score(const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0) { this->primaryScore = primaryScore; this->secondaryScore = secondaryScore; this->tertiaryScore = tertiaryScore; From a43e03255cfca2572c0d840ab676fcad96e59704 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 30 May 2023 04:38:19 -0700 Subject: [PATCH 066/116] It compiles at least now --- dGame/LeaderboardManager.cpp | 13 +-- dGame/LeaderboardManager.h | 82 ++++++++----------- .../dComponents/ScriptedActivityComponent.cpp | 2 +- dGame/dGameMessages/GameMessageHandler.cpp | 2 +- 4 files changed, 46 insertions(+), 53 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 695978fb..b61b1f49 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -35,11 +35,11 @@ Leaderboard::~Leaderboard() { for (auto& entry : entries) for (auto data : entry) delete data; } -void Leaderboard::WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { +inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { leaderboard << "\nResult[0].Row[" << index << "]." << data->GetString(); } -void Leaderboard::Serialize(RakNet::BitStream* bitStream) { +void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { bitStream->Write(gameID); bitStream->Write(infoType); @@ -172,6 +172,7 @@ const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType columns = "bestTime, score"; break; case Type::None: + columns = ""; // This type is included here simply to resolve a compiler warning on mac about unused enum types break; } @@ -202,6 +203,7 @@ const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboar columns = "bestTime=%i, score=%i"; break; case Type::None: + columns = ""; // This type is included here simply to resolve a compiler warning on mac about unused enum types break; } @@ -234,6 +236,7 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp orderBase = "bestTime DESC, score DESC"; break; case Type::None: + orderBase = ""; // This type is included here simply to resolve a compiler warning on mac about unused enum types break; } @@ -349,7 +352,7 @@ void Leaderboard::Send(const LWOOBJID targetID) const { } } -std::string LeaderboardManager::FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate) { +std::string FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate) { auto insertFormat = Leaderboard::GetInsertFormat(type); auto* queryType = useUpdate ? "UPDATE" : "INSERT"; @@ -371,7 +374,7 @@ std::string LeaderboardManager::FormatInsert(const Leaderboard::Type& type, cons return finishedQuery; } -void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t primaryScore, uint32_t secondaryScore, uint32_t tertiaryScore) { +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const uint32_t primaryScore, const uint32_t secondaryScore, const uint32_t tertiaryScore) { auto* lookup = "SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;"; std::unique_ptr query(Database::CreatePreppedStmt(lookup)); @@ -443,7 +446,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, GameID gameID, Lead saveStatement->execute(); } -void LeaderboardManager::SendLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart, uint32_t resultEnd) { +void LeaderboardManager::SendLeaderboard(const uint32_t gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart, const uint32_t resultEnd) { Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(resultStart, resultEnd); leaderboard.Send(targetID); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index fe5bc16d..7aac2b12 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -17,7 +17,39 @@ namespace RakNet { class BitStream; }; -typedef uint32_t GameID; +class Score { +public: + Score() { + primaryScore = 0; + secondaryScore = 0; + tertiaryScore = 0; + } + Score(const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0) { + this->primaryScore = primaryScore; + this->secondaryScore = secondaryScore; + this->tertiaryScore = tertiaryScore; + } + bool operator<(const Score& rhs) const { + return primaryScore < rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore < rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore < rhs.tertiaryScore); + } + bool operator>(const Score& rhs) const { + return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore); + } + void SetPrimaryScore(const uint32_t score) { primaryScore = score; } + uint32_t GetPrimaryScore() const { return primaryScore; } + + void SetSecondaryScore(const uint32_t score) { secondaryScore = score; } + uint32_t GetSecondaryScore() const { return secondaryScore; } + + void SetTertiaryScore(const uint32_t score) { tertiaryScore = score; } + uint32_t GetTertiaryScore() const { return tertiaryScore; } +private: + uint32_t primaryScore; + uint32_t secondaryScore; + uint32_t tertiaryScore; +}; + +using GameID = uint32_t; class Leaderboard { public: @@ -50,7 +82,7 @@ public: * * Expensive! Leaderboards are very string intensive so be wary of performatnce calling this method. */ - void Serialize(RakNet::BitStream* bitStream); + void Serialize(RakNet::BitStream* bitStream) const; /** * Based on the associated gameID, return true if the score provided @@ -79,8 +111,6 @@ public: static const std::string_view GetInsertFormat(Type leaderboardType); static const std::string_view GetOrdering(Type leaderboardType); private: - inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data); - // Returns true if the string needs formatting bool GetRankingQuery(std::string& lookupReturn) const; @@ -100,53 +130,13 @@ private: }; namespace LeaderboardManager { - class Score { - public: - Score() { - primaryScore = 0; - secondaryScore = 0; - tertiaryScore = 0; - } - Score(const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0) { - this->primaryScore = primaryScore; - this->secondaryScore = secondaryScore; - this->tertiaryScore = tertiaryScore; - } - bool operator<(const Score& rhs) const { - return primaryScore < rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore < rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore < rhs.tertiaryScore); - } - bool operator>(const Score& rhs) const { - return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore); - } - void SetPrimaryScore(const uint32_t score) { primaryScore = score; } - uint32_t GetPrimaryScore() const { return primaryScore; } - - void SetSecondaryScore(const uint32_t score) { secondaryScore = score; } - uint32_t GetSecondaryScore() const { return secondaryScore; } - - void SetTertiaryScore(const uint32_t score) { tertiaryScore = score; } - uint32_t GetTertiaryScore() const { return tertiaryScore; } - private: - uint32_t primaryScore; - uint32_t secondaryScore; - uint32_t tertiaryScore; - }; using LeaderboardCache = std::map; void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10); - /** - * @brief Public facing Score saving method. This method is simply a wrapper to ensure va_end is called properly. - * - * @param playerID The player whos score to save - * @param gameID The ID of the game which was played - * @param argumentCount The number of arguments in the va_list - * @param ... The score to save - */ - void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t primaryScore, uint32_t secondaryScore = 0, uint32_t tertiaryScore = 0); + void SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0); - void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); - std::string FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate); + void GetLeaderboard(const uint32_t gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID = LWOOBJID_EMPTY); Leaderboard::Type GetLeaderboardType(const GameID gameID); extern LeaderboardCache leaderboardCache; diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 555332f4..b7d473cf 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -36,7 +36,7 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit for (CDActivities activity : activities) { m_ActivityInfo = activity; - if (static_cast(activity.leaderboardType) == LeaderboardType::Racing && Game::config->GetValue("solo_racing") == "1") { + if (static_cast(activity.leaderboardType) == Leaderboard::Type::Racing && Game::config->GetValue("solo_racing") == "1") { m_ActivityInfo.minTeamSize = 1; m_ActivityInfo.minTeams = 1; } diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index b76f391e..ca7a98cb 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -45,7 +45,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System Entity* entity = EntityManager::Instance()->GetEntity(objectID); User* usr = UserManager::Instance()->GetUser(sysAddr); - if (messageID != 888) Game::logger->Log("GameMessageHandler", "message %i", messageID); + if (messageID != eGameMessageType::READY_FOR_UPDATES) Game::logger->Log("GameMessageHandler", "message %i", messageID); if (!entity) { Game::logger->Log("GameMessageHandler", "Failed to find associated entity (%llu), aborting GM (%X)!", objectID, messageID); From 0ecc5d83c37ab26f1583b759b444fe862c77ab46 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 30 May 2023 17:30:50 -0700 Subject: [PATCH 067/116] Fix out of bounds access Fixes an issue where we would try to access an array out of the physics bounds --- dPhysics/dpGrid.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index 1631c91a..c3259b51 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -43,8 +43,8 @@ void dpGrid::Add(dpEntity* entity) { if (cellX < 0) cellX = 0; if (cellZ < 0) cellZ = 0; - if (cellX > NUM_CELLS) cellX = NUM_CELLS; - if (cellZ > NUM_CELLS) cellZ = NUM_CELLS; + if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; + if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; //Add to cell: m_Cells[cellX][cellZ].push_front(entity); @@ -87,8 +87,8 @@ void dpGrid::Delete(dpEntity* entity) { if (oldCellX < 0) oldCellX = 0; if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX > NUM_CELLS) oldCellX = NUM_CELLS; - if (oldCellZ > NUM_CELLS) oldCellZ = NUM_CELLS; + if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; + if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; m_Cells[oldCellX][oldCellZ].remove(entity); From e1a7b4993eb3ad333bb3c7d2131f588a65dba478 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 30 May 2023 18:21:10 -0700 Subject: [PATCH 068/116] look ma, more work --- dGame/LeaderboardManager.cpp | 45 +++++++++++++++--------------------- dGame/LeaderboardManager.h | 1 + 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index b61b1f49..5830b980 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -68,16 +68,6 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { bitStream->Write0(); } -bool Leaderboard::GetRankingQuery(std::string& lookupReturn) const { - if (this->infoType == InfoType::Top) { - lookupReturn = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY %s LIMIT 1"; - return true; - } else { - lookupReturn = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ? LIMIT 1"; - return false; - } -} - void Leaderboard::QueryToLdf(std::unique_ptr& rows) { if (rows->rowsCount() == 0) return; @@ -276,7 +266,8 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { ORDER BY ranking ASC; )QUERY"; - const char* friendsQuery = + // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. + std::string friendsQuery = R"QUERY( AND ( character_id IN ( SELECT fr.requested_player FROM ( @@ -294,23 +285,25 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { ) )QUERY"; + [[likely]] if (this->infoType != InfoType::Friends) friendsQuery.clear(); const auto orderBase = GetOrdering(this->leaderboardType); const auto selectBase = GetColumns(this->leaderboardType); - constexpr uint16_t STRING_LENGTH = 1526; + constexpr uint16_t STRING_LENGTH = 2048; char lookupBuffer[STRING_LENGTH]; - // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. - if (this->infoType == InfoType::Friends) { - snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), - orderBase.data(), friendsQuery, selectBase.data(), resultStart, resultEnd); - } else { - snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), - orderBase.data(), "", selectBase.data(), resultStart, resultEnd); - } + int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), selectBase.data(), resultStart, resultEnd); + DluAssert(res != -1); std::string baseLookupStr; char baseRankingBuffer[STRING_LENGTH]; - bool neededFormatting = GetRankingQuery(baseLookupStr); + bool neededFormatting; + [[unlikely]] if (this->infoType == InfoType::Top) { + baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY %s LIMIT 1"; + neededFormatting = true; + } else { + baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ? LIMIT 1"; + neededFormatting = false; + } // If we need to format the base ranking query, do so, otherwise just copy the query since it's already formatted. if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.data()); @@ -318,9 +311,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseRankingBuffer)); baseQuery->setInt(1, this->gameID); - if (!neededFormatting) { - baseQuery->setInt(2, this->relatedPlayer); - } + if (!neededFormatting) baseQuery->setInt(2, this->relatedPlayer); std::unique_ptr baseResult(baseQuery->executeQuery()); @@ -415,16 +406,18 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID oldScore.SetPrimaryScore(myScoreResult->getInt("score")); break; } - case Leaderboard::Type::Racing: + case Leaderboard::Type::Racing: { oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); oldScore.SetSecondaryScore(myScoreResult->getInt("bestLapTime")); lowerScoreBetter = true; break; - case Leaderboard::Type::MonumentRace: + } + case Leaderboard::Type::MonumentRace: { oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); lowerScoreBetter = true; // Do score checking here break; + } case Leaderboard::Type::None: default: Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 7aac2b12..1dff91bf 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -2,6 +2,7 @@ #define __LEADERBOARDMANAGER__H__ #include +#include #include #include From 8a1f27517652eee16bf1f9b86b954f803e079878 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 31 May 2023 03:10:28 -0700 Subject: [PATCH 069/116] add a const --- dGame/LeaderboardManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 5830b980..c41c3765 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -236,7 +236,7 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { resultStart++; resultEnd++; - std::string queryBase = + const std::string queryBase = R"QUERY( WITH leaderboardsRanked AS ( SELECT leaderboard.*, charinfo.name, From 47deca6f4f2f79bdcb23378377d8174168ada229 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 31 May 2023 23:04:33 -0700 Subject: [PATCH 070/116] Update migration Better column names and maintainability Better updating Convert all data to floats --- .../dlu/9_Update_Leaderboard_Storage.sql | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index 6721e74e..89712147 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -1,12 +1,18 @@ ALTER TABLE leaderboard - ADD COLUMN hitPercentage INT NOT NULL DEFAULT 0, - ADD COLUMN streak INT NOT NULL DEFAULT 0, - ADD COLUMN bestLapTime INT NOT NULL DEFAULT 0, + ADD COLUMN tertiaryScore FLOAT NOT NULL DEFAULT 0, ADD COLUMN numWins INT NOT NULL DEFAULT 0, ADD COLUMN timesPlayed INT NOT NULL DEFAULT 1, MODIFY time INT NOT NULL DEFAULT 0; -ALTER TABLE leaderboard CHANGE time bestTime INT; -ALTER TABLE leaderboard CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); +/* Can only ALTER one column at a time... */ +ALTER TABLE leaderboard + CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); +ALTER TABLE leaderboard RENAME COLUMN score TO primaryScore; +ALTER TABLE leaderboard RENAME COLUMN time TO secondaryScore; +ALTER TABLE leaderboard MODIFY COLUMN secondaryScore FLOAT NOT NULL DEFAULT 0 AFTER primaryScore; +ALTER TABLE leaderboard MODIFY COLUMN primaryScore FLOAT NOT NULL DEFAULT 0; -UPDATE leaderboard SET streak = bestTime where game_id = 1864; +/* A bit messy, but better than going through a bunch of code fixes all to be run once. */ +UPDATE leaderboard SET + primaryScore = secondaryScore, + secondaryScore = 0 WHERE game_id IN (1, 44, 46, 47, 48, 49, 53, 103, 104, 108, 1901); From b8878da61b431c77f761495841a057f480475c22 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 31 May 2023 23:05:19 -0700 Subject: [PATCH 071/116] Convert to using only floats This will cover all of our bases for any type of score. No need to do any conversions. --- dGame/LeaderboardManager.cpp | 200 ++++++++++++----------------------- dGame/LeaderboardManager.h | 34 +++--- 2 files changed, 79 insertions(+), 155 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index c41c3765..7246f434 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -1,7 +1,8 @@ -#define _DEBUG - #include "LeaderboardManager.h" + +#include #include + #include "Database.h" #include "EntityManager.h" #include "Character.h" @@ -14,7 +15,6 @@ #include "Entity.h" #include "LDFFormat.h" #include "DluAssert.h" -#include #include "CDActivitiesTable.h" #include "Metrics.hpp" @@ -32,7 +32,12 @@ Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoTy } Leaderboard::~Leaderboard() { + Clear(); +} + +void Leaderboard::Clear() { for (auto& entry : entries) for (auto data : entry) delete data; + } inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { @@ -44,7 +49,7 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { bitStream->Write(infoType); std::ostringstream leaderboard; - Game::logger->Log("LeaderboardManager", "game is %i info type %i ", gameID, infoType); + leaderboard << "ADO.Result=7:1"; // Unused in 1.10.64, but is in captures leaderboard << "\nResult.Count=1:1"; // number of results, always 1 if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key". Live doesn't include this if there are no entries. @@ -63,12 +68,12 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { bitStream->Write(leaderboardSize); // Doing this all in 1 call so there is no possbility of a dangling pointer. bitStream->WriteAlignedBytes(reinterpret_cast(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboardSize * sizeof(char16_t)); - if (leaderboardSize > 0) bitStream->Write(0); bitStream->Write0(); bitStream->Write0(); } void Leaderboard::QueryToLdf(std::unique_ptr& rows) { + Clear(); if (rows->rowsCount() == 0) return; this->entries.reserve(rows->rowsCount()); @@ -84,49 +89,49 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); switch (leaderboardType) { case Type::ShootingGallery: - entry.push_back(new LDFData(u"HitPercentage", (rows->getInt("hitPercentage") / 100.0f))); + entry.push_back(new LDFData(u"HitPercentage", (rows->getInt("primaryScore") / 100.0f))); // HitPercentage:3 between 0 and 1 - entry.push_back(new LDFData(u"Score", rows->getInt("score"))); + entry.push_back(new LDFData(u"Score", rows->getInt("secondaryScore"))); // Score:1 - entry.push_back(new LDFData(u"Streak", rows->getInt("streak"))); + entry.push_back(new LDFData(u"Streak", rows->getInt("tertiaryScore"))); // Streak:1 break; case Type::Racing: - entry.push_back(new LDFData(u"BestLapTime", rows->getDouble("bestLapTime"))); + entry.push_back(new LDFData(u"BestTime", rows->getDouble("primaryScore"))); // BestLapTime:3 - entry.push_back(new LDFData(u"BestTime", rows->getDouble("bestTime"))); + entry.push_back(new LDFData(u"BestLapTime", rows->getDouble("secondaryScore"))); // BestTime:3 entry.push_back(new LDFData(u"License", 1)); // License:1 - 1 if player has completed mission 637 and 0 otherwise - entry.push_back(new LDFData(u"NumWins", rows->getInt("numWins"))); + entry.push_back(new LDFData(u"NumWins", rows->getInt("tertiaryScore"))); // NumWins:1 break; case Type::UnusedLeaderboard4: - entry.push_back(new LDFData(u"Points", rows->getInt("score"))); + entry.push_back(new LDFData(u"Points", rows->getInt("primaryScore"))); // Points:1 break; case Type::MonumentRace: - entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("primaryScore"))); // Time:1(?) break; case Type::FootRace: - entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("primaryScore"))); // Time:1 break; case Type::Survival: - entry.push_back(new LDFData(u"Points", rows->getInt("score"))); + entry.push_back(new LDFData(u"Points", rows->getInt("primaryScore"))); // Points:1 - entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("secondaryScore"))); // Time:1 break; case Type::SurvivalNS: - entry.push_back(new LDFData(u"Wave", rows->getInt("score"))); + entry.push_back(new LDFData(u"Wave", rows->getInt("primaryScore"))); // Wave:1 - entry.push_back(new LDFData(u"Time", rows->getInt("bestTime"))); + entry.push_back(new LDFData(u"Time", rows->getInt("secondaryScore"))); // Time:1 break; case Type::Donations: - entry.push_back(new LDFData(u"Points", rows->getInt("score"))); + entry.push_back(new LDFData(u"Points", rows->getInt("primaryScore"))); // Score:1 break; case Type::None: @@ -139,98 +144,33 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { } const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { - const char* columns; - switch (leaderboardType) { - case Type::ShootingGallery: - columns = "hitPercentage, score, streak"; - break; - case Type::Racing: - columns = "bestLapTime, bestTime, numWins"; - break; - case Type::Donations: - case Type::UnusedLeaderboard4: - columns = "score"; - break; - case Type::MonumentRace: - case Type::FootRace: - columns = "bestTime"; - break; - case Type::Survival: - columns = "bestTime, score"; - break; - case Type::SurvivalNS: - columns = "bestTime, score"; - break; - case Type::None: - columns = ""; - // This type is included here simply to resolve a compiler warning on mac about unused enum types - break; - } - return columns; + return "primaryScore, secondaryScore, tertiaryScore"; } const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { - const char* columns; - switch (leaderboardType) { - case Type::ShootingGallery: - columns = "score=%i, hitPercentage=%i, streak=%i"; - break; - case Type::Racing: - columns = "bestLapTime=%i, bestTime=%i, numWins=numWins + %i"; - break; - case Type::Donations: - case Type::UnusedLeaderboard4: - columns = "score=%i"; - break; - case Type::MonumentRace: - case Type::FootRace: - columns = "bestTime=%i"; - break; - case Type::Survival: - columns = "bestTime=%i, score=%i"; - break; - case Type::SurvivalNS: - columns = "bestTime=%i, score=%i"; - break; - case Type::None: - columns = ""; - // This type is included here simply to resolve a compiler warning on mac about unused enum types - break; - } - return columns; + return "primaryScore %f, secondaryScore %f, tertiaryScore %f"; } const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { - const char* orderBase; + // Use a switch case and return desc for all 3 columns if higher is better and asc if lower is better switch (leaderboardType) { case Type::ShootingGallery: - orderBase = "score DESC, streak DESC, hitPercentage DESC"; - break; - case Type::Racing: - orderBase = "bestTime ASC, bestLapTime ASC, numWins DESC"; - break; - case Type::Donations: - case Type::UnusedLeaderboard4: - orderBase = "score DESC"; - break; - case Type::MonumentRace: - orderBase = "bestTime ASC"; - break; case Type::FootRace: - orderBase = "bestTime DESC"; - break; - case Type::Survival: - orderBase = "score DESC, bestTime DESC"; - break; + case Type::UnusedLeaderboard4: case Type::SurvivalNS: - orderBase = "bestTime DESC, score DESC"; - break; + case Type::Donations: + return "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC"; + case Type::Racing: + case Type::MonumentRace: + return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC"; case Type::None: - orderBase = ""; - // This type is included here simply to resolve a compiler warning on mac about unused enum types - break; + case Type::Survival: + return Game::config->GetValue("classic_survival_scoring") == "1" ? + "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC" : + "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC"; + default: + return ""; } - return orderBase; } void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { @@ -285,34 +225,22 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { ) )QUERY"; - [[likely]] if (this->infoType != InfoType::Friends) friendsQuery.clear(); + if (this->infoType != InfoType::Friends) friendsQuery.clear(); const auto orderBase = GetOrdering(this->leaderboardType); const auto selectBase = GetColumns(this->leaderboardType); - constexpr uint16_t STRING_LENGTH = 2048; - char lookupBuffer[STRING_LENGTH]; - int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), selectBase.data(), resultStart, resultEnd); - DluAssert(res != -1); - - std::string baseLookupStr; - char baseRankingBuffer[STRING_LENGTH]; - bool neededFormatting; - [[unlikely]] if (this->infoType == InfoType::Top) { - baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY %s LIMIT 1"; - neededFormatting = true; + std::string baseLookup; + if (this->infoType == InfoType::Top) { + baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY "; + baseLookup += orderBase.data(); } else { - baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ? LIMIT 1"; - neededFormatting = false; + baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = "; + baseLookup += std::to_string(this->relatedPlayer); } + baseLookup += " LIMIT 1"; - // If we need to format the base ranking query, do so, otherwise just copy the query since it's already formatted. - if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.data()); - else std::copy(baseLookupStr.begin(), baseLookupStr.end() + 1, baseRankingBuffer); - - std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseRankingBuffer)); + std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseLookup)); baseQuery->setInt(1, this->gameID); - if (!neededFormatting) baseQuery->setInt(2, this->relatedPlayer); - std::unique_ptr baseResult(baseQuery->executeQuery()); if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game. @@ -320,6 +248,10 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); // Create and execute the actual save here + constexpr uint16_t STRING_LENGTH = 2048; + char lookupBuffer[STRING_LENGTH]; + [[maybe_unused]] int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), selectBase.data(), resultStart, resultEnd); + DluAssert(res != -1); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); query->setInt(1, this->gameID); @@ -365,7 +297,7 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons return finishedQuery; } -void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const uint32_t primaryScore, const uint32_t secondaryScore, const uint32_t tertiaryScore) { +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const float primaryScore, const float secondaryScore, const float tertiaryScore) { auto* lookup = "SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;"; std::unique_ptr query(Database::CreatePreppedStmt(lookup)); @@ -381,46 +313,46 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID switch (leaderboardType) { // Higher score better case Leaderboard::Type::ShootingGallery: { - oldScore.SetPrimaryScore(myScoreResult->getInt("score")); - oldScore.SetSecondaryScore(myScoreResult->getInt("hitPercentage")); - oldScore.SetTertiaryScore(myScoreResult->getInt("streak")); + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); + oldScore.SetTertiaryScore(myScoreResult->getInt("tertiaryScore")); break; } case Leaderboard::Type::FootRace: { - oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); break; } case Leaderboard::Type::Survival: { // Config option may reverse these - oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); - oldScore.SetSecondaryScore(myScoreResult->getInt("score")); + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); break; } case Leaderboard::Type::SurvivalNS: { - oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); - oldScore.SetSecondaryScore(myScoreResult->getInt("score")); + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); break; } case Leaderboard::Type::UnusedLeaderboard4: case Leaderboard::Type::Donations: { - oldScore.SetPrimaryScore(myScoreResult->getInt("score")); + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); break; } case Leaderboard::Type::Racing: { - oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); - oldScore.SetSecondaryScore(myScoreResult->getInt("bestLapTime")); + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); lowerScoreBetter = true; break; } case Leaderboard::Type::MonumentRace: { - oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime")); + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); lowerScoreBetter = true; // Do score checking here break; } case Leaderboard::Type::None: default: - Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType); + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i for game %i. Cannot save score!", leaderboardType, gameID); return; } bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore; diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 1dff91bf..92d90615 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -25,7 +25,7 @@ public: secondaryScore = 0; tertiaryScore = 0; } - Score(const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0) { + Score(const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0) { this->primaryScore = primaryScore; this->secondaryScore = secondaryScore; this->tertiaryScore = tertiaryScore; @@ -36,18 +36,18 @@ public: bool operator>(const Score& rhs) const { return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore); } - void SetPrimaryScore(const uint32_t score) { primaryScore = score; } - uint32_t GetPrimaryScore() const { return primaryScore; } + void SetPrimaryScore(const float score) { primaryScore = score; } + float GetPrimaryScore() const { return primaryScore; } - void SetSecondaryScore(const uint32_t score) { secondaryScore = score; } - uint32_t GetSecondaryScore() const { return secondaryScore; } + void SetSecondaryScore(const float score) { secondaryScore = score; } + float GetSecondaryScore() const { return secondaryScore; } - void SetTertiaryScore(const uint32_t score) { tertiaryScore = score; } - uint32_t GetTertiaryScore() const { return tertiaryScore; } + void SetTertiaryScore(const float score) { tertiaryScore = score; } + float GetTertiaryScore() const { return tertiaryScore; } private: - uint32_t primaryScore; - uint32_t secondaryScore; - uint32_t tertiaryScore; + float primaryScore; + float secondaryScore; + float tertiaryScore; }; using GameID = uint32_t; @@ -73,10 +73,11 @@ public: Donations, None }; - + Leaderboard() = delete; Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None); ~Leaderboard(); + void Clear(); /** * Serialize the Leaderboard to a BitStream @@ -85,15 +86,6 @@ public: */ void Serialize(RakNet::BitStream* bitStream) const; - /** - * Based on the associated gameID, return true if the score provided - * is better than the current entries' score - * @param score - * @return true - * @return false - */ - bool IsScoreBetter(const uint32_t score) const { return false; }; - /** * Builds the leaderboard from the database based on the associated gameID * @@ -135,7 +127,7 @@ namespace LeaderboardManager { using LeaderboardCache = std::map; void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10); - void SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0); + void SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0); void GetLeaderboard(const uint32_t gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID = LWOOBJID_EMPTY); From 8267823ca4a33dddbe8ff73a0ec15d8aba9e649a Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 31 May 2023 23:17:13 -0700 Subject: [PATCH 072/116] More simplification --- dGame/LeaderboardManager.cpp | 45 ++++++++++++++++-------------------- dGame/LeaderboardManager.h | 4 +--- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 7246f434..89f438f4 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -143,14 +143,6 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { } } -const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType) { - return "primaryScore, secondaryScore, tertiaryScore"; -} - -const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) { - return "primaryScore %f, secondaryScore %f, tertiaryScore %f"; -} - const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { // Use a switch case and return desc for all 3 columns if higher is better and asc if lower is better switch (leaderboardType) { @@ -179,7 +171,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { const std::string queryBase = R"QUERY( WITH leaderboardsRanked AS ( - SELECT leaderboard.*, charinfo.name, + SELECT leaderboard.primaryScore, leaderboard.secondaryScore, leaderboard.tertiaryScore, charinfo.name, RANK() OVER ( ORDER BY %s, UNIX_TIMESTAMP(last_played) ASC, id DESC @@ -197,7 +189,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { SELECT MAX(ranking) AS lowestRank FROM leaderboardsRanked ) - SELECT %s, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking + SELECT leaderboardsRanked.*, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking WHERE leaderboardsRanked.ranking BETWEEN LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, %i), lowestRanking.lowestRank - 10) @@ -227,7 +219,6 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { if (this->infoType != InfoType::Friends) friendsQuery.clear(); const auto orderBase = GetOrdering(this->leaderboardType); - const auto selectBase = GetColumns(this->leaderboardType); std::string baseLookup; if (this->infoType == InfoType::Top) { @@ -250,7 +241,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { // Create and execute the actual save here constexpr uint16_t STRING_LENGTH = 2048; char lookupBuffer[STRING_LENGTH]; - [[maybe_unused]] int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), selectBase.data(), resultStart, resultEnd); + [[maybe_unused]] int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), resultStart, resultEnd); DluAssert(res != -1); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); @@ -276,23 +267,27 @@ void Leaderboard::Send(const LWOOBJID targetID) const { } std::string FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate) { - auto insertFormat = Leaderboard::GetInsertFormat(type); + std::string insertStatement; + if (useUpdate) { + insertStatement = + R"QUERY( + UPDATE leaderboard + SET primaryScore %f, secondaryScore %f, tertiaryScore %f, + timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?; + )QUERY"; + } else { + insertStatement = + R"QUERY( + INSERT leaderboard SET + primaryScore %f, secondaryScore %f, tertiaryScore %f, + character_id = ?, game_id = ?; + )QUERY"; + } - auto* queryType = useUpdate ? "UPDATE" : "INSERT"; - - auto* usedFilter = useUpdate ? - ", timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?" : - ", character_id = ?, game_id = ?"; - - // First fill in the format constexpr uint16_t STRING_LENGTH = 400; - char formattedInsert[STRING_LENGTH]; - int32_t res = snprintf(formattedInsert, STRING_LENGTH, "%s leaderboard SET %s %s;", queryType, insertFormat.data(), usedFilter); - DluAssert(res != -1); - // Then fill in our score char finishedQuery[STRING_LENGTH]; - res = snprintf(finishedQuery, STRING_LENGTH, formattedInsert, score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); + int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); DluAssert(res != -1); return finishedQuery; } diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 92d90615..b4927ced 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -99,9 +99,7 @@ public: */ void Send(const LWOOBJID targetID) const; - // Helper functions to get the columns, ordering and insert format for a leaderboard - static const std::string_view GetColumns(Type leaderboardType); - static const std::string_view GetInsertFormat(Type leaderboardType); + // Helper function to get the columns, ordering and insert format for a leaderboard static const std::string_view GetOrdering(Type leaderboardType); private: // Returns true if the string needs formatting From 9fabff16e49994dd6513c64f22fe6b3f72dcd6ae Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 2 Jun 2023 04:44:49 -0700 Subject: [PATCH 073/116] Update AMFDeserialize (#1096) Per ISO C++ standard 9.7.1 5.3, "Otherwise the type of the enumerator is the same as that of the preceding enumerator unless the incremented value is not representable in that type, in which case the type is an unspecified integral type sufficient to contain the incremented value. If no such type exists, the program is ill-formed." it is not undefined behavior to set a scoped enum to a value outside of its constant range because all values of the underlying type can represent the scoped enum --- dCommon/AMFDeserialize.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dCommon/AMFDeserialize.cpp b/dCommon/AMFDeserialize.cpp index 9eee1f12..648d1ed1 100644 --- a/dCommon/AMFDeserialize.cpp +++ b/dCommon/AMFDeserialize.cpp @@ -13,10 +13,8 @@ AMFBaseValue* AMFDeserialize::Read(RakNet::BitStream* inStream) { if (!inStream) return nullptr; AMFBaseValue* returnValue = nullptr; // Read in the value type from the bitStream - uint8_t i; - inStream->Read(i); - if (i > static_cast(eAmf::Dictionary)) return nullptr; - eAmf marker = static_cast(i); + eAmf marker; + inStream->Read(marker); // Based on the typing, create the value associated with that and return the base value class switch (marker) { case eAmf::Undefined: { From 8ae1e1bc6b1cbbd926bfc97d8be05483af094388 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 3 Jun 2023 00:40:46 -0700 Subject: [PATCH 074/116] Fix: remove ability to buy items from a vendor if they don't sell said item (#1105) --- dGame/dComponents/VendorComponent.cpp | 4 ++++ dGame/dComponents/VendorComponent.h | 2 ++ dGame/dGameMessages/GameMessages.cpp | 9 +++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index c9178785..e89cc926 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -134,3 +134,7 @@ void VendorComponent::SetupConstants() { m_RefreshTimeSeconds = vendorComps[0].refreshTimeSeconds; m_LootMatrixID = vendorComps[0].LootMatrixIndex; } + +bool VendorComponent::SellsItem(const LOT item) const { + return m_Inventory.find(item) != m_Inventory.end(); +} diff --git a/dGame/dComponents/VendorComponent.h b/dGame/dComponents/VendorComponent.h index bf372bf2..cbff0cfd 100644 --- a/dGame/dComponents/VendorComponent.h +++ b/dGame/dComponents/VendorComponent.h @@ -67,6 +67,8 @@ public: * Called on startup of vendor to setup the variables for the component. */ void SetupConstants(); + + bool SellsItem(const LOT item) const; private: /** * The buy scalar. diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c178f6c7..16460025 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4733,12 +4733,17 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti const auto isCommendationVendor = entity->GetLOT() == 13806; - VendorComponent* vend = static_cast(entity->GetComponent(eReplicaComponentType::VENDOR)); + auto* vend = entity->GetComponent(); if (!vend && !isCommendationVendor) return; - InventoryComponent* inv = static_cast(player->GetComponent(eReplicaComponentType::INVENTORY)); + auto* inv = player->GetComponent(); if (!inv) return; + if (!isCommendationVendor && !vend->SellsItem(item)) { + Game::logger->Log("GameMessages", "User %llu %s tried to buy an item %i from a vendor when they do not sell said item", player->GetObjectID(), user->GetUsername().c_str(), item); + return; + } + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable(); CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable(); From b5897556551055548144e124e247477a3c0f1858 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 3 Jun 2023 16:28:27 -0700 Subject: [PATCH 075/116] Fix out of bounds access in dpGrid (#1106) Fixes an issue where we would try to access an array out of the physics bounds --- dPhysics/dpGrid.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index 1631c91a..c3259b51 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -43,8 +43,8 @@ void dpGrid::Add(dpEntity* entity) { if (cellX < 0) cellX = 0; if (cellZ < 0) cellZ = 0; - if (cellX > NUM_CELLS) cellX = NUM_CELLS; - if (cellZ > NUM_CELLS) cellZ = NUM_CELLS; + if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; + if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; //Add to cell: m_Cells[cellX][cellZ].push_front(entity); @@ -87,8 +87,8 @@ void dpGrid::Delete(dpEntity* entity) { if (oldCellX < 0) oldCellX = 0; if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX > NUM_CELLS) oldCellX = NUM_CELLS; - if (oldCellZ > NUM_CELLS) oldCellZ = NUM_CELLS; + if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; + if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; m_Cells[oldCellX][oldCellZ].remove(entity); From 96fc6e81d88298a88d4c9ec615a542891eb5d190 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 5 Jun 2023 02:24:00 -0700 Subject: [PATCH 076/116] Update sql to work The old way was supposed to work but doesn't. Oh well! --- dGame/LeaderboardManager.cpp | 2 +- migrations/dlu/9_Update_Leaderboard_Storage.sql | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 89f438f4..dd890bd6 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -287,7 +287,7 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons constexpr uint16_t STRING_LENGTH = 400; // Then fill in our score char finishedQuery[STRING_LENGTH]; - int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); + [[maybe_unused]] int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); DluAssert(res != -1); return finishedQuery; } diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index 89712147..a68cc2d8 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -7,10 +7,8 @@ ALTER TABLE leaderboard /* Can only ALTER one column at a time... */ ALTER TABLE leaderboard CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); -ALTER TABLE leaderboard RENAME COLUMN score TO primaryScore; -ALTER TABLE leaderboard RENAME COLUMN time TO secondaryScore; -ALTER TABLE leaderboard MODIFY COLUMN secondaryScore FLOAT NOT NULL DEFAULT 0 AFTER primaryScore; -ALTER TABLE leaderboard MODIFY COLUMN primaryScore FLOAT NOT NULL DEFAULT 0; +ALTER TABLE leaderboard CHANGE score primaryScore FLOAT NOT NULL DEFAULT 0; +ALTER TABLE leaderboard CHANGE time secondaryScore FLOAT NOT NULL DEFAULT 0 AFTER primaryScore; /* A bit messy, but better than going through a bunch of code fixes all to be run once. */ UPDATE leaderboard SET From 5bff441c01cecac91936c08b002f67d392f0e50d Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 5 Jun 2023 02:31:49 -0700 Subject: [PATCH 077/116] Fix query crashing Just select all columns since we need most of them anyways --- dGame/LeaderboardManager.cpp | 5 +++-- tests/dGameTests/LeaderboardTests.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index dd890bd6..d9ba6a87 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -84,7 +84,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { entry.reserve(MAX_NUM_DATA_PER_ROW); entry.push_back(new LDFData(u"CharacterID", rows->getInt("character_id"))); entry.push_back(new LDFData(u"LastPlayed", rows->getUInt64("lastPlayed"))); - entry.push_back(new LDFData(u"NumPlayed", 1)); + entry.push_back(new LDFData(u"NumPlayed", rows->getInt("timesPlayed"))); entry.push_back(new LDFData(u"name", GeneralUtils::ASCIIToUTF16(rows->getString("name").c_str()))); entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); switch (leaderboardType) { @@ -168,10 +168,11 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { resultStart++; resultEnd++; + // We need everything except 1 column so i'm selecting * from leaderboard const std::string queryBase = R"QUERY( WITH leaderboardsRanked AS ( - SELECT leaderboard.primaryScore, leaderboard.secondaryScore, leaderboard.tertiaryScore, charinfo.name, + SELECT leaderboard.*, charinfo.name, RANK() OVER ( ORDER BY %s, UNIX_TIMESTAMP(last_played) ASC, id DESC diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index b3480f51..b7946368 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -30,10 +30,10 @@ protected: Leaderboard leaderboard(gameID, infoType, false, 14231, type); leaderboard.SetupLeaderboard(); leaderboard.Serialize(&bitStream); - // TestLeaderboard(leaderboard, 1); - // TestLeaderboard(leaderboard, 10); - // TestLeaderboard(leaderboard, 100); - // TestLeaderboard(leaderboard, 1000); + TestLeaderboard(leaderboard, 1); + TestLeaderboard(leaderboard, 10); + TestLeaderboard(leaderboard, 100); + TestLeaderboard(leaderboard, 1000); } CBITSTREAM; From c572f2a58dfd71ab18339b0e3f3142fcab30a609 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 5 Jun 2023 02:43:02 -0700 Subject: [PATCH 078/116] better tabs and organization --- dGame/LeaderboardManager.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d9ba6a87..a1e6d31e 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -146,22 +146,21 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { // Use a switch case and return desc for all 3 columns if higher is better and asc if lower is better switch (leaderboardType) { + case Type::Racing: + case Type::MonumentRace: + return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC"; + case Type::Survival: + return Game::config->GetValue("classic_survival_scoring") == "1" ? + "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC" : + "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC"; case Type::ShootingGallery: case Type::FootRace: case Type::UnusedLeaderboard4: case Type::SurvivalNS: case Type::Donations: - return "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC"; - case Type::Racing: - case Type::MonumentRace: - return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC"; case Type::None: - case Type::Survival: - return Game::config->GetValue("classic_survival_scoring") == "1" ? - "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC" : - "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC"; default: - return ""; + return "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC"; } } @@ -221,6 +220,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { if (this->infoType != InfoType::Friends) friendsQuery.clear(); const auto orderBase = GetOrdering(this->leaderboardType); + // For top query, we want to just rank all scores, but for all others we need the scores around a specific player std::string baseLookup; if (this->infoType == InfoType::Top) { baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY "; @@ -239,12 +239,12 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); - // Create and execute the actual save here - constexpr uint16_t STRING_LENGTH = 2048; - char lookupBuffer[STRING_LENGTH]; - [[maybe_unused]] int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), resultStart, resultEnd); + // Create and execute the actual save here. Using a heap allocated buffer to avoid stack overflow + constexpr uint16_t STRING_LENGTH = 4096; + std::unique_ptr lookupBuffer = std::make_unique(STRING_LENGTH); + [[maybe_unused]] int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), resultStart, resultEnd); DluAssert(res != -1); - std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer)); + std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer.get())); query->setInt(1, this->gameID); if (this->infoType == InfoType::Friends) { From a5e63529dc085569c748c78887309369710ec0ac Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 5 Jun 2023 02:50:40 -0700 Subject: [PATCH 079/116] const and compile save --- dGame/LeaderboardManager.cpp | 29 +++++++++++++++-------------- dGame/LeaderboardManager.h | 7 +------ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index a1e6d31e..cf399601 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -200,19 +200,20 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. std::string friendsQuery = - R"QUERY( AND ( - character_id IN ( - SELECT fr.requested_player FROM ( - SELECT CASE - WHEN player_id = ? THEN friend_id - WHEN friend_id = ? THEN player_id - END AS requested_player - FROM friends - ) AS fr - JOIN charinfo AS ci - ON ci.id = fr.requested_player - WHERE fr.requested_player IS NOT NULL - ) + R"QUERY( + AND ( + character_id IN ( + SELECT fr.requested_player FROM ( + SELECT CASE + WHEN player_id = ? THEN friend_id + WHEN friend_id = ? THEN player_id + END AS requested_player + FROM friends + ) AS fr + JOIN charinfo AS ci + ON ci.id = fr.requested_player + WHERE fr.requested_player IS NOT NULL + ) OR character_id = ? ) )QUERY"; @@ -378,7 +379,7 @@ Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { if (lookup != leaderboardCache.end()) return lookup->second; auto* activitiesTable = CDClientManager::Instance().GetTable(); - std::vector activities = activitiesTable->Query([=](const CDActivities& entry) { + std::vector activities = activitiesTable->Query([gameID](const CDActivities& entry) { return entry.ActivityID == gameID; }); auto type = !activities.empty() ? static_cast(activities.at(0).leaderboardType) : Leaderboard::Type::None; diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index b4927ced..2512eb87 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -102,9 +102,6 @@ public: // Helper function to get the columns, ordering and insert format for a leaderboard static const std::string_view GetOrdering(Type leaderboardType); private: - // Returns true if the string needs formatting - bool GetRankingQuery(std::string& lookupReturn) const; - // Takes the resulting query from a leaderboard lookup and converts it to the LDF we need // to send it to a client. void QueryToLdf(std::unique_ptr& rows); @@ -123,12 +120,10 @@ private: namespace LeaderboardManager { using LeaderboardCache = std::map; - void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10); + void SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart = 0, const uint32_t resultEnd = 10); void SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0); - void GetLeaderboard(const uint32_t gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID = LWOOBJID_EMPTY); - Leaderboard::Type GetLeaderboardType(const GameID gameID); extern LeaderboardCache leaderboardCache; }; From 259f0c8371b2689fa7641d5fd45dfe508ec9297a Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 5 Jun 2023 04:10:59 -0700 Subject: [PATCH 080/116] Working in game again hooray --- dGame/LeaderboardManager.cpp | 28 +++++++++---------- dGame/LeaderboardManager.h | 11 +++++--- dGame/dComponents/RacingControlComponent.cpp | 3 +- dGame/dGameMessages/GameMessages.cpp | 2 +- .../02_server/Map/AG/NpcAgCourseStarter.cpp | 3 +- dScripts/ActivityManager.cpp | 10 ++----- dScripts/ActivityManager.h | 2 +- .../ai/ACT/FootRace/BaseFootRaceManager.cpp | 2 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 9 +++--- 9 files changed, 34 insertions(+), 36 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index cf399601..7ae1e0f9 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -20,7 +20,7 @@ #include "Metrics.hpp" namespace LeaderboardManager { - LeaderboardCache leaderboardCache; + std::map leaderboardCache; } Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type leaderboardType) { @@ -36,8 +36,7 @@ Leaderboard::~Leaderboard() { } void Leaderboard::Clear() { - for (auto& entry : entries) for (auto data : entry) delete data; - + for (auto& entry : entries) for (auto ldfData : entry) delete ldfData; } inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { @@ -68,6 +67,7 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { bitStream->Write(leaderboardSize); // Doing this all in 1 call so there is no possbility of a dangling pointer. bitStream->WriteAlignedBytes(reinterpret_cast(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboardSize * sizeof(char16_t)); + if (leaderboardSize > 0) bitStream->Write(0); bitStream->Write0(); bitStream->Write0(); } @@ -192,7 +192,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { SELECT leaderboardsRanked.*, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking WHERE leaderboardsRanked.ranking BETWEEN - LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, %i), lowestRanking.lowestRank - 10) + LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, %i), lowestRanking.lowestRank - 9) AND LEAST(GREATEST(myRank + 5, %i), lowestRanking.lowestRank) ORDER BY ranking ASC; @@ -228,7 +228,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { baseLookup += orderBase.data(); } else { baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = "; - baseLookup += std::to_string(this->relatedPlayer); + baseLookup += std::to_string(static_cast(this->relatedPlayer)); } baseLookup += " LIMIT 1"; @@ -243,7 +243,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { // Create and execute the actual save here. Using a heap allocated buffer to avoid stack overflow constexpr uint16_t STRING_LENGTH = 4096; std::unique_ptr lookupBuffer = std::make_unique(STRING_LENGTH); - [[maybe_unused]] int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), resultStart, resultEnd); + [[maybe_unused]] int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), friendsQuery.c_str(), resultStart, resultEnd); DluAssert(res != -1); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer.get())); @@ -256,7 +256,6 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { } else { query->setInt(2, relatedPlayerLeaderboardId); } - std::unique_ptr result(query->executeQuery()); QueryToLdf(result); } @@ -274,14 +273,14 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons insertStatement = R"QUERY( UPDATE leaderboard - SET primaryScore %f, secondaryScore %f, tertiaryScore %f, + SET primaryScore = %f, secondaryScore = %f, tertiaryScore = %f, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?; )QUERY"; } else { insertStatement = R"QUERY( INSERT leaderboard SET - primaryScore %f, secondaryScore %f, tertiaryScore %f, + primaryScore = %f, secondaryScore = %f, tertiaryScore = %f, character_id = ?, game_id = ?; )QUERY"; } @@ -294,12 +293,13 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons return finishedQuery; } -void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const float primaryScore, const float secondaryScore, const float tertiaryScore) { +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore, const float tertiaryScore) { + const Leaderboard::Type leaderboardType = GetLeaderboardType(activityId); auto* lookup = "SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;"; std::unique_ptr query(Database::CreatePreppedStmt(lookup)); query->setInt(1, playerID); - query->setInt(2, gameID); + query->setInt(2, activityId); std::unique_ptr myScoreResult(query->executeQuery()); std::string saveQuery("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"); @@ -349,7 +349,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID } case Leaderboard::Type::None: default: - Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i for game %i. Cannot save score!", leaderboardType, gameID); + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i for game %i. Cannot save score!", leaderboardType, activityId); return; } bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore; @@ -364,11 +364,11 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID std::unique_ptr saveStatement(Database::CreatePreppedStmt(saveQuery)); saveStatement->setInt(1, playerID); - saveStatement->setInt(2, gameID); + saveStatement->setInt(2, activityId); saveStatement->execute(); } -void LeaderboardManager::SendLeaderboard(const uint32_t gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart, const uint32_t resultEnd) { +void LeaderboardManager::SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart, const uint32_t resultEnd) { Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(resultStart, resultEnd); leaderboard.Send(targetID); diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 2512eb87..165e870f 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -77,6 +77,11 @@ public: Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None); ~Leaderboard(); + + /** + * @brief Resets the leaderboard state and frees its allocated memory + * + */ void Clear(); /** @@ -118,14 +123,12 @@ private: }; namespace LeaderboardManager { - - using LeaderboardCache = std::map; void SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart = 0, const uint32_t resultEnd = 10); - void SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0); + void SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0); Leaderboard::Type GetLeaderboardType(const GameID gameID); - extern LeaderboardCache leaderboardCache; + extern std::map leaderboardCache; }; #endif //!__LEADERBOARDMANAGER__H__ diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 4a8668ca..9ccfe12a 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -379,8 +379,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu const auto score = m_LoadedPlayers * 10 + data->finished; LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); - // auto leaderboardType = LeaderboardManager::Instance().GetLeaderboardType(m_ActivityID); - // LeaderboardManager::Instance().SaveScore(player->GetObjectID(), m_ActivityID, leaderboardType, 3, data->bestLapTime, data->raceTime, data->finished == 1); + LeaderboardManager::SaveScore(player->GetObjectID(), m_ActivityID, static_cast(data->bestLapTime), static_cast(data->raceTime), static_cast(data->finished == 1)); // Giving rewards GameMessages::SendNotifyRacingClient( diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 46f5cb93..198ea151 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1669,7 +1669,7 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream->ReadBit(); - // LeaderboardManager::Instance().SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID(), resultsStart, resultsEnd); + LeaderboardManager::SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID(), resultsStart, resultsEnd); } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index 20e749ee..2a619b6b 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -93,8 +93,7 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std } EntityManager::Instance()->SerializeEntity(self); - auto leaderboardType = LeaderboardManager::GetLeaderboardType(scriptedActivityComponent->GetActivityID()); - // LeaderboardManager::Instance().SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), leaderboardType, 1, finish); + LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), static_cast(finish)); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", scriptedActivityComponent->GetActivityID(), 0, sender->GetObjectID(), diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 96186688..57557ae6 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -79,16 +79,14 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const } } -void ActivityManager::SaveScore(Entity* self, LWOOBJID playerID, uint32_t val1, uint32_t val2, uint32_t val3) { +void ActivityManager::SaveScore(Entity* self, const LWOOBJID playerID, const float primaryScore, const float secondaryScore, const float tertiaryScore) const { auto* player = EntityManager::Instance()->GetEntity(playerID); if (!player) return; auto* sac = self->GetComponent(); uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); // Save the new score to the leaderboard and show the leaderboard to the player - auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); - Game::logger->Log("ActivityManager", "leaderboard type %i %i args %i %i %i", leaderboardType, gameID, val1, val2, val3); - // LeaderboardManager::Instance().SaveScore(playerID, gameID, leaderboardType, 3, val1, val2, val3); + LeaderboardManager::SaveScore(playerID, gameID, primaryScore, secondaryScore, tertiaryScore); // Makes the leaderboard show up for the player GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", gameID, 0, playerID, "", player->GetSystemAddress()); @@ -123,9 +121,7 @@ void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID, auto* sac = self->GetComponent(); uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); // Save the new score to the leaderboard and show the leaderboard to the player - auto leaderboardType = LeaderboardManager::GetLeaderboardType(gameID); - Game::logger->Log("ActivityManager", "gameID %i", gameID, activityID); - // LeaderboardManager::Instance().SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID(), 0, numResults); + LeaderboardManager::SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID(), 0, numResults); } void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval, diff --git a/dScripts/ActivityManager.h b/dScripts/ActivityManager.h index 633fd5d8..a2202bfb 100644 --- a/dScripts/ActivityManager.h +++ b/dScripts/ActivityManager.h @@ -18,7 +18,7 @@ public: static bool TakeActivityCost(const Entity* self, LWOOBJID playerID); static uint32_t GetActivityID(const Entity* self); void StopActivity(Entity* self, LWOOBJID playerID, uint32_t score, uint32_t value1 = 0, uint32_t value2 = 0, bool quit = false); - void SaveScore(Entity* self, LWOOBJID playerID, uint32_t val1 = 0, uint32_t val2 = 0, uint32_t val3 = 0); + void SaveScore(Entity* self, const LWOOBJID playerID, const float primaryScore, const float secondaryScore = 0.0f, const float tertiaryScore = 0.0f) const; virtual uint32_t CalculateActivityRating(Entity* self, LWOOBJID playerID); static void GetLeaderboardData(Entity* self, LWOOBJID playerID, uint32_t activityID, uint32_t numResults = 0); // void FreezePlayer(Entity *self, const LWOOBJID playerID, const bool state) const; diff --git a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp index 3efb5ff4..412d9d88 100644 --- a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp +++ b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp @@ -42,7 +42,7 @@ void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, st } StopActivity(self, player->GetObjectID(), 0, param1); - SaveScore(self, player->GetObjectID(), param1, param2, param3); + SaveScore(self, player->GetObjectID(), static_cast(param1), static_cast(param2), static_cast(param3)); } } } diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index a37551ed..558c24c4 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -150,7 +150,7 @@ void SGCannon::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button if (IsPlayerInActivity(self, player->GetObjectID())) return; self->SetNetworkVar(ClearVariable, true); StartGame(self); - } else if (button == 0 && ((identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay"))){ + } else if (button == 0 && ((identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay"))) { RemovePlayer(player->GetObjectID()); UpdatePlayer(self, player->GetObjectID(), true); } else if (button == 1 && identifier == u"Shooting_Gallery_Exit") { @@ -436,8 +436,8 @@ void SGCannon::RemovePlayer(LWOOBJID playerID) { } } -void SGCannon::OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled){ - if (canceled){ +void SGCannon::OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled) { + if (canceled) { StopGame(self, canceled); RemovePlayer(player); } @@ -565,7 +565,8 @@ void SGCannon::StopGame(Entity* self, bool cancel) { LootGenerator::Instance().GiveActivityLoot(player, self, GetGameID(self), self->GetVar(TotalScoreVariable)); StopActivity(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), self->GetVar(MaxStreakVariable), percentage); - SaveScore(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), percentage, self->GetVar(MaxStreakVariable)); + SaveScore(self, player->GetObjectID(), + static_cast(self->GetVar(TotalScoreVariable)), percentage, static_cast(self->GetVar(MaxStreakVariable))); self->SetNetworkVar(AudioFinalWaveDoneVariable, true); // Give the player the model rewards they earned From b4aa5db305f4cfac832ba159985b8f04b1bc0d9c Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 5 Jun 2023 15:10:08 -0700 Subject: [PATCH 081/116] Comment out tests rest in pepperoni tests --- tests/dGameTests/LeaderboardTests.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index b7946368..5157e5d6 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -71,8 +71,9 @@ protected: * 19: [13-04-23 00:39:19] [LeaderboardManager] average time passed for 1000 leaderboard entries is 279457375ns */ -TEST_F(LeaderboardTests, LeaderboardSpeedTest) { - RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); - RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); - RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); -} +// Commented tests out because we dont have a sql server running for tests +// TEST_F(LeaderboardTests, LeaderboardSpeedTest) { + // RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); + // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); + // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); +// } From dab075fc39c8ebfa1471b24e0f147d32d832bb3a Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 5 Jun 2023 15:19:52 -0700 Subject: [PATCH 082/116] forgor about this one --- tests/dGameTests/GameDependencies.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index c0fb8bce..87f56ad0 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -33,7 +33,7 @@ protected: Game::logger = new dLogger("./testing.log", true, true); Game::server = new dServerMock(); Game::config = new dConfig("worldconfig.ini"); - Database::Connect(Game::config->GetValue("mysql_host"), Game::config->GetValue("mysql_database"), Game::config->GetValue("mysql_username"), Game::config->GetValue("mysql_password")); + // Database::Connect(Game::config->GetValue("mysql_host"), Game::config->GetValue("mysql_database"), Game::config->GetValue("mysql_username"), Game::config->GetValue("mysql_password")); } void TearDownDependencies() { From c99e2a372bf6ab1f5343bbd442c5417c782fd3e6 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 5 Jun 2023 16:04:56 -0700 Subject: [PATCH 083/116] Add weekly filter --- dGame/LeaderboardManager.cpp | 16 ++++++++++------ dGame/LeaderboardManager.h | 2 +- tests/dGameTests/LeaderboardTests.cpp | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 7ae1e0f9..bd362bf2 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -164,7 +164,7 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp } } -void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { +void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t resultEnd) { resultStart++; resultEnd++; // We need everything except 1 column so i'm selecting * from leaderboard @@ -198,8 +198,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { ORDER BY ranking ASC; )QUERY"; - // If we are getting the friends leaderboard, add the friends query, otherwise fill it in with nothing. - std::string friendsQuery = + std::string friendsFilter = R"QUERY( AND ( character_id IN ( @@ -218,7 +217,12 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { ) )QUERY"; - if (this->infoType != InfoType::Friends) friendsQuery.clear(); + std::string weeklyFilter = " AND date >= curdate() - INTERVAL DAYOFWEEK(curdate()) - 7 DAY"; + + std::string filter; + // Setup our filter based on the query type + if (this->infoType == InfoType::Friends) filter += friendsFilter; + if (this->weekly) filter += weeklyFilter; const auto orderBase = GetOrdering(this->leaderboardType); // For top query, we want to just rank all scores, but for all others we need the scores around a specific player @@ -243,7 +247,7 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) { // Create and execute the actual save here. Using a heap allocated buffer to avoid stack overflow constexpr uint16_t STRING_LENGTH = 4096; std::unique_ptr lookupBuffer = std::make_unique(STRING_LENGTH); - [[maybe_unused]] int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), friendsQuery.c_str(), resultStart, resultEnd); + [[maybe_unused]] int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd); DluAssert(res != -1); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer.get())); @@ -370,7 +374,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi void LeaderboardManager::SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart, const uint32_t resultEnd) { Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); - leaderboard.SetupLeaderboard(resultStart, resultEnd); + leaderboard.SetupLeaderboard(weekly, resultStart, resultEnd); leaderboard.Send(targetID); } diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index 165e870f..e2ce3f97 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -97,7 +97,7 @@ public: * @param resultStart The index to start the leaderboard at. Zero indexed. * @param resultEnd The index to end the leaderboard at. Zero indexed. */ - void SetupLeaderboard(uint32_t resultStart = 0, uint32_t resultEnd = 10); + void SetupLeaderboard(bool weekly, uint32_t resultStart = 0, uint32_t resultEnd = 10); /** * Sends the leaderboard to the client specified by targetID. diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp index 5157e5d6..8cb833a3 100644 --- a/tests/dGameTests/LeaderboardTests.cpp +++ b/tests/dGameTests/LeaderboardTests.cpp @@ -28,7 +28,7 @@ protected: void RunTests(uint32_t gameID, Leaderboard::Type type, Leaderboard::InfoType infoType) { Game::logger->Log("LeaderboardTests", "Testing leaderboard %i for Serialize speed", infoType); Leaderboard leaderboard(gameID, infoType, false, 14231, type); - leaderboard.SetupLeaderboard(); + leaderboard.SetupLeaderboard(true, 0, 10); leaderboard.Serialize(&bitStream); TestLeaderboard(leaderboard, 1); TestLeaderboard(leaderboard, 10); From 12d7ab9034f148ea53407160c13606dc2c0602bf Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 6 Jun 2023 22:48:41 -0700 Subject: [PATCH 084/116] Remove null check in GetPosition (#1109) Get ready for null pointer errors --- dGame/Entity.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 6de6ba62..907e8e63 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1827,8 +1827,6 @@ bool Entity::IsSleeping() const { const NiPoint3& Entity::GetPosition() const { - if (!this) return NiPoint3::ZERO; - auto* controllable = GetComponent(); if (controllable != nullptr) { From 2a0f63c0a1ad7bef842bddbbbf647d934362791f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 14 Jun 2023 15:44:22 -0700 Subject: [PATCH 085/116] Fix all smashables not playing animations (#1112) Fixes an issue where most smashables did not explode into bricks upon death. This included anything that was spawned or didnt have the flag is_smashable set. Tested that in races, all objects smash into bricks Tested that the player properly explodes in their car if they crash Tested that Shooting Gallery plays the special smash animation when a ship is smashed Tested that all spawned objects play smash animations * Fix warning, Fix modular assembly not smashing * Rename variable to correct name --- dGame/Entity.cpp | 4 ++-- dGame/dComponents/DestroyableComponent.cpp | 4 ++-- dGame/dComponents/DestroyableComponent.h | 4 ++-- dGame/dComponents/InventoryComponent.cpp | 1 - dScripts/EquipmentScripts/BuccaneerValiantShip.cpp | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 907e8e63..bac07713 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -386,8 +386,8 @@ void Entity::Initialize() { comp->SetMaxCoins(currencyValues[0].maxvalue); } - // extraInfo overrides - comp->SetIsSmashable(GetVarAs(u"is_smashable") != 0); + // extraInfo overrides. Client ORs the database smashable and the luz smashable. + comp->SetIsSmashable(comp->GetIsSmashable() | (GetVarAs(u"is_smashable") != 0)); } } else { comp->SetHealth(1); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 01ebf5c1..db8a2013 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -51,7 +51,7 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_IsGMImmune = false; m_IsShielded = false; m_DamageToAbsorb = 0; - m_HasBricks = false; + m_IsModuleAssembly = m_Parent->HasComponent(eReplicaComponentType::MODULE_ASSEMBLY); m_DirtyThreatList = false; m_HasThreats = false; m_ExplodeFactor = 1.0f; @@ -163,7 +163,7 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_IsSmashed); if (m_IsSmashable) { - outBitStream->Write(m_HasBricks); + outBitStream->Write(m_IsModuleAssembly); outBitStream->Write(m_ExplodeFactor != 1.0f); if (m_ExplodeFactor != 1.0f) outBitStream->Write(m_ExplodeFactor); } diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 66c8374d..5e5133b7 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -239,7 +239,7 @@ public: * Returns whether or not this entity has bricks flying out when smashed * @return whether or not this entity has bricks flying out when smashed */ - bool GetHasBricks() const { return m_HasBricks; } + bool GetHasBricks() const { return m_IsModuleAssembly; } /** * Sets the multiplier for the explosion that's visible when the bricks fly out when this entity is smashed @@ -546,7 +546,7 @@ private: /** * Whether this entity has bricks flying out when smashed (causes the client to look up the files) */ - bool m_HasBricks; + bool m_IsModuleAssembly; /** * The rate at which bricks fly out when smashed diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 907356ce..618e93b6 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1002,7 +1002,6 @@ void InventoryComponent::HandlePossession(Item* item) { // Setup the destroyable stats auto* destroyableComponent = mount->GetComponent(); if (destroyableComponent) { - destroyableComponent->SetIsSmashable(false); destroyableComponent->SetIsImmune(true); } diff --git a/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp b/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp index 3db214b5..15954622 100644 --- a/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp +++ b/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp @@ -11,7 +11,7 @@ void BuccaneerValiantShip::OnStartup(Entity* self) { // Kill self if missed self->AddCallbackTimer(1.1F, [self]() { - self->Kill(); + self->Smash(); }); } }); From 1a74c028c2eff7661d6ec3bcebadc777aed369ec Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 16 Jun 2023 16:09:46 -0500 Subject: [PATCH 086/116] fix: make vanity npc's use default equipment if none is specified (#1116) --- dGame/dUtilities/VanityUtilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 7fabfbce..ed425fe5 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -163,7 +163,7 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin auto* inventoryComponent = entity->GetComponent(); - if (inventoryComponent != nullptr) { + if (inventoryComponent && !inventory.empty()) { inventoryComponent->SetNPCItems(inventory); } From 0d6bd33f9e592e3a4ef016dc3fc4b8f29cf8e7f1 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 16 Jun 2023 21:30:28 -0700 Subject: [PATCH 087/116] Remove unused problematic code (#1115) --- dZoneManager/Level.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dZoneManager/Level.h b/dZoneManager/Level.h index 83daeedb..0f8fa72d 100644 --- a/dZoneManager/Level.h +++ b/dZoneManager/Level.h @@ -30,12 +30,6 @@ public: struct SceneObjectDataChunk { std::map objects; - SceneObject& GetObject(LWOOBJID id) { - for (std::map::iterator it = objects.begin(); it != objects.end(); ++it) { - if (it->first == id) return it->second; - } - } - const void PrintAllObjects() { for (std::map::iterator it = objects.begin(); it != objects.end(); ++it) { std::cout << "\t ID: " << it->first << " LOT: " << it->second.lot << std::endl; From f46bc33dd48e82a757f1e043180ffb759b61df3b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 17 Jun 2023 17:20:05 -0700 Subject: [PATCH 088/116] Fix prereq bug (#1118) --- dGame/dComponents/InventoryComponent.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 618e93b6..626c7ee9 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -38,7 +38,7 @@ #include "CDObjectSkillsTable.h" #include "CDSkillBehaviorTable.h" -InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) { +InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) { this->m_Dirty = true; this->m_Equipped = {}; this->m_Pushed = {}; @@ -830,14 +830,22 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { const auto position = m_Parent->GetPosition(); - for (auto* lauchPad : rocketLauchPads) { - if (Vector3::DistanceSquared(lauchPad->GetPosition(), position) > 13 * 13) continue; + for (auto* launchPad : rocketLauchPads) { + if (!launchPad) continue; + + auto prereq = launchPad->GetVarAsString(u"rocketLaunchPreCondition"); + if (!prereq.empty()) { + PreconditionExpression expression(prereq); + if (!expression.Check(m_Parent)) continue; + } + + if (Vector3::DistanceSquared(launchPad->GetPosition(), position) > 13 * 13) continue; auto* characterComponent = m_Parent->GetComponent(); if (characterComponent != nullptr) characterComponent->SetLastRocketItemID(item->GetId()); - lauchPad->OnUse(m_Parent); + launchPad->OnUse(m_Parent); break; } From 2d31b7e4bb913a6df9d3bab988ca9b652a2e8238 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 18 Jun 2023 00:00:36 -0700 Subject: [PATCH 089/116] Fix incorrect serialization of SendTeleport (#1121) * Fix incorrect serialization of SendTeleport - Fixes all incorrect teleports in the game - remove hacks in mast teleport - ... - ...... Update GameMessages.cpp * Remove stupid argument there got it all out * remove extra true --- dGame/dComponents/RacingControlComponent.cpp | 11 ++++------- dGame/dGameMessages/GameMessages.cpp | 3 +-- dGame/dGameMessages/GameMessages.h | 2 +- dScripts/02_server/Map/GF/MastTeleport.cpp | 10 +--------- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 4a4ead59..c16e99fb 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -124,8 +124,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Make sure the player is at the correct position. GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); // Spawn the vehicle entity. @@ -243,11 +242,9 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Make sure everything has the correct position. GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); GameMessages::SendTeleport(carEntity->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); } void RacingControlComponent::OnRacingClientReady(Entity* player) { @@ -634,7 +631,7 @@ void RacingControlComponent::Update(float deltaTime) { GameMessages::SendTeleport( player.playerID, player.respawnPosition, player.respawnRotation, - playerEntity->GetSystemAddress(), true, true); + playerEntity->GetSystemAddress(), true); vehicle->SetPosition(player.respawnPosition); vehicle->SetRotation(player.respawnRotation); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 16460025..0c3207d6 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -120,7 +120,7 @@ void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const Syste SEND_PACKET; } -void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation, bool noGravTeleport) { +void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); @@ -141,7 +141,6 @@ void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, c bitStream.Write(pos.y); bitStream.Write(pos.z); bitStream.Write(bUseNavmesh); - bitStream.Write(noGravTeleport); bitStream.Write(rot.w != 1.0f); if (rot.w != 1.0f) bitStream.Write(rot.w); diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 7e7a8f70..94bdd3ea 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -40,7 +40,7 @@ enum class eRebuildState : uint32_t; namespace GameMessages { class PropertyDataMessage; void SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender); - void SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation = false, bool noGravTeleport = true); + void SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation = false); void SendPlayAnimation(Entity* entity, const std::u16string& animationName, float fPriority = 0.0f, float fScale = 1.0f); void SendPlayerReady(Entity* entity, const SystemAddress& sysAddr); void SendPlayerAllowedRespawn(LWOOBJID entityID, bool doNotPromptRespawn, const SystemAddress& systemAddress); diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index 311da34a..5f8795a3 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -43,15 +43,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendTeleport(playerId, position, rotation, player->GetSystemAddress(), true); - // Hacky fix for odd rotations - auto mastName = self->GetVar(u"MastName"); - if (mastName == u"Elephant") { - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 140.0f, player->GetSystemAddress()); - } else if (mastName == u"Jail") { - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 100.0f, player->GetSystemAddress()); - } else if (mastName == u""){ - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 203.0f, player->GetSystemAddress()); - } + GameMessages::SendTeleport(playerId, position, rotation, player->GetSystemAddress(), true); const auto cinematic = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Cinematic")); const auto leanIn = self->GetVar(u"LeanIn"); From 132d31d3aba5df0bf089407a32af39ead259125c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 20 Jun 2023 07:19:21 -0700 Subject: [PATCH 090/116] Fix vehicle serialization during races (#1122) * Fix vehicle serialization during races - Add missing frame stats reading - correct the inversion of rotation - correct serialization order - use proper dirty flags Tested that racers are no longer sideways on certain vertical slopes and stay in sync throughout the whole race. * Update ClientPackets.cpp * Update ClientPackets.cpp * Update VehiclePhysicsComponent.h --- dGame/dComponents/VehiclePhysicsComponent.cpp | 49 +++++++++++++++---- dGame/dComponents/VehiclePhysicsComponent.h | 21 ++++++++ dNet/ClientPackets.cpp | 31 ++++++++++-- 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/dGame/dComponents/VehiclePhysicsComponent.cpp b/dGame/dComponents/VehiclePhysicsComponent.cpp index d981acf7..58bf7ebb 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.cpp +++ b/dGame/dComponents/VehiclePhysicsComponent.cpp @@ -19,34 +19,47 @@ VehiclePhysicsComponent::~VehiclePhysicsComponent() { } void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) { + if (pos == m_Position) return; + m_DirtyPosition = true; m_Position = pos; } void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) { + if (rot == m_Rotation) return; m_DirtyPosition = true; m_Rotation = rot; } void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) { + if (vel == m_Velocity) return; m_DirtyPosition = true; m_Velocity = vel; } void VehiclePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) { + if (vel == m_AngularVelocity) return; m_DirtyPosition = true; m_AngularVelocity = vel; } void VehiclePhysicsComponent::SetIsOnGround(bool val) { + if (val == m_IsOnGround) return; m_DirtyPosition = true; m_IsOnGround = val; } void VehiclePhysicsComponent::SetIsOnRail(bool val) { + if (val == m_IsOnRail) return; m_DirtyPosition = true; m_IsOnRail = val; } +void VehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) { + if (m_RemoteInputInfo == remoteInputInfo) return; + this->m_RemoteInputInfo = remoteInputInfo; + m_DirtyRemoteInput = true; +} + void VehiclePhysicsComponent::SetDirtyPosition(bool val) { m_DirtyPosition = val; } @@ -63,9 +76,15 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI outBitStream->Write(bIsInitialUpdate || m_DirtyPosition); if (bIsInitialUpdate || m_DirtyPosition) { - outBitStream->Write(m_Position); + m_DirtyPosition = false; + outBitStream->Write(m_Position.x); + outBitStream->Write(m_Position.y); + outBitStream->Write(m_Position.z); - outBitStream->Write(m_Rotation); + outBitStream->Write(m_Rotation.x); + outBitStream->Write(m_Rotation.y); + outBitStream->Write(m_Rotation.z); + outBitStream->Write(m_Rotation.w); outBitStream->Write(m_IsOnGround); outBitStream->Write(m_IsOnRail); @@ -73,20 +92,33 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI outBitStream->Write(bIsInitialUpdate || m_DirtyVelocity); if (bIsInitialUpdate || m_DirtyVelocity) { - outBitStream->Write(m_Velocity); + outBitStream->Write(m_Velocity.x); + outBitStream->Write(m_Velocity.y); + outBitStream->Write(m_Velocity.z); + m_DirtyVelocity = false; } outBitStream->Write(bIsInitialUpdate || m_DirtyAngularVelocity); if (bIsInitialUpdate || m_DirtyAngularVelocity) { - outBitStream->Write(m_AngularVelocity); + outBitStream->Write(m_AngularVelocity.x); + outBitStream->Write(m_AngularVelocity.y); + outBitStream->Write(m_AngularVelocity.z); + m_DirtyAngularVelocity = false; } - outBitStream->Write0(); + outBitStream->Write0(); // local_space_info. TODO: Implement this - outBitStream->Write0(); + outBitStream->Write(m_DirtyRemoteInput || bIsInitialUpdate); // remote_input_info + if (m_DirtyRemoteInput || bIsInitialUpdate) { + outBitStream->Write(m_RemoteInputInfo.m_RemoteInputX); + outBitStream->Write(m_RemoteInputInfo.m_RemoteInputY); + outBitStream->Write(m_RemoteInputInfo.m_IsPowersliding); + outBitStream->Write(m_RemoteInputInfo.m_IsModified); + m_DirtyRemoteInput = false; + } - outBitStream->Write(0.0f); + outBitStream->Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race. if (!bIsInitialUpdate) { outBitStream->Write0(); @@ -95,7 +127,7 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI if (bIsInitialUpdate) { outBitStream->Write(m_EndBehavior); - outBitStream->Write1(); + outBitStream->Write1(); // is input locked? } outBitStream->Write0(); @@ -104,7 +136,6 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI void VehiclePhysicsComponent::Update(float deltaTime) { if (m_SoftUpdate > 5) { EntityManager::Instance()->SerializeEntity(m_Parent); - m_SoftUpdate = 0; } else { m_SoftUpdate += deltaTime; diff --git a/dGame/dComponents/VehiclePhysicsComponent.h b/dGame/dComponents/VehiclePhysicsComponent.h index 64609edf..e314bef1 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.h +++ b/dGame/dComponents/VehiclePhysicsComponent.h @@ -5,6 +5,24 @@ #include "Component.h" #include "eReplicaComponentType.h" +struct RemoteInputInfo { + void operator=(const RemoteInputInfo& other) { + m_RemoteInputX = other.m_RemoteInputX; + m_RemoteInputY = other.m_RemoteInputY; + m_IsPowersliding = other.m_IsPowersliding; + m_IsModified = other.m_IsModified; + } + + bool operator==(const RemoteInputInfo& other) { + return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified; + } + + float m_RemoteInputX; + float m_RemoteInputY; + bool m_IsPowersliding; + bool m_IsModified; +}; + /** * Physics component for vehicles. */ @@ -94,6 +112,7 @@ public: void SetDirtyPosition(bool val); void SetDirtyVelocity(bool val); void SetDirtyAngularVelocity(bool val); + void SetRemoteInputInfo(const RemoteInputInfo&); private: bool m_DirtyPosition; @@ -110,4 +129,6 @@ private: float m_SoftUpdate = 0; uint32_t m_EndBehavior; + RemoteInputInfo m_RemoteInputInfo; + bool m_DirtyRemoteInput; }; diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 1c22bdcd..313be6b0 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -136,6 +136,33 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac inStream.Read(angVelocity.z); } + // TODO figure out how to use these. Ignoring for now, but reading in if they exist. + bool hasLocalSpaceInfo{}; + LWOOBJID objectId{}; + NiPoint3 localSpacePosition{}; + bool hasLinearVelocity{}; + NiPoint3 linearVelocity{}; + if (inStream.Read(hasLocalSpaceInfo) && hasLocalSpaceInfo) { + inStream.Read(objectId); + inStream.Read(localSpacePosition.x); + inStream.Read(localSpacePosition.y); + inStream.Read(localSpacePosition.z); + if (inStream.Read(hasLinearVelocity) && hasLinearVelocity) { + inStream.Read(linearVelocity.x); + inStream.Read(linearVelocity.y); + inStream.Read(linearVelocity.z); + } + } + bool hasRemoteInputInfo{}; + RemoteInputInfo remoteInput{}; + + if (inStream.Read(hasRemoteInputInfo) && hasRemoteInputInfo) { + inStream.Read(remoteInput.m_RemoteInputX); + inStream.Read(remoteInput.m_RemoteInputY); + inStream.Read(remoteInput.m_IsPowersliding); + inStream.Read(remoteInput.m_IsModified); + } + bool updateChar = true; if (possessorComponent != nullptr) { @@ -150,9 +177,6 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac auto* vehiclePhysicsComponent = possassableEntity->GetComponent(); if (vehiclePhysicsComponent != nullptr) { - // This is flipped for whatever reason - rotation = NiQuaternion(rotation.z, rotation.y, rotation.x, rotation.w); - vehiclePhysicsComponent->SetPosition(position); vehiclePhysicsComponent->SetRotation(rotation); vehiclePhysicsComponent->SetIsOnGround(onGround); @@ -161,6 +185,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac vehiclePhysicsComponent->SetDirtyVelocity(velocityFlag); vehiclePhysicsComponent->SetAngularVelocity(angVelocity); vehiclePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag); + vehiclePhysicsComponent->SetRemoteInputInfo(remoteInput); } else { // Need to get the mount's controllable physics auto* controllablePhysicsComponent = possassableEntity->GetComponent(); From fe23c7c5f7543a95c9c327ac9cefab21f0395645 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 20 Jun 2023 08:40:16 -0700 Subject: [PATCH 091/116] Allow default scripts (#1117) Fix an issue where vanity script overwrote always --- dGame/dUtilities/VanityUtilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index ed425fe5..703f7d30 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -119,7 +119,7 @@ void VanityUtilities::SpawnVanity() { auto* scriptComponent = npcEntity->GetComponent(); - if (scriptComponent != nullptr) { + if (scriptComponent && !npc.m_Script.empty()) { scriptComponent->SetScript(npc.m_Script); scriptComponent->SetSerialized(false); From d340874284c8d1043dae92ff50d4d799234e9711 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 21 Jun 2023 19:46:01 -0700 Subject: [PATCH 092/116] more bug fixing - fix weekly leaderboards - fix ag classic vs dlu scoring - fix sorting for survival ns - fix sorting for racing --- dGame/LeaderboardManager.cpp | 23 ++++++++++++++------ dGame/dComponents/RacingControlComponent.cpp | 6 ++--- dScripts/BaseSurvivalServer.cpp | 4 +++- dScripts/BaseWavesServer.cpp | 2 +- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index bd362bf2..2fd48dc3 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -151,12 +151,13 @@ const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardTyp return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC"; case Type::Survival: return Game::config->GetValue("classic_survival_scoring") == "1" ? - "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC" : - "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC"; + "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC" : + "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC"; + case Type::SurvivalNS: + return "primaryScore DESC, secondaryScore ASC, tertiaryScore DESC"; case Type::ShootingGallery: case Type::FootRace: case Type::UnusedLeaderboard4: - case Type::SurvivalNS: case Type::Donations: case Type::None: default: @@ -217,7 +218,7 @@ void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t r ) )QUERY"; - std::string weeklyFilter = " AND date >= curdate() - INTERVAL DAYOFWEEK(curdate()) - 7 DAY"; + std::string weeklyFilter = " AND UNIX_TIMESTAMP(last_played) BETWEEN UNIX_TIMESTAMP(date_sub(now(),INTERVAL 1 WEEK)) AND UNIX_TIMESTAMP(now()) "; std::string filter; // Setup our filter based on the query type @@ -247,7 +248,7 @@ void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t r // Create and execute the actual save here. Using a heap allocated buffer to avoid stack overflow constexpr uint16_t STRING_LENGTH = 4096; std::unique_ptr lookupBuffer = std::make_unique(STRING_LENGTH); - [[maybe_unused]] int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd); + int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd); DluAssert(res != -1); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer.get())); @@ -292,7 +293,7 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons constexpr uint16_t STRING_LENGTH = 400; // Then fill in our score char finishedQuery[STRING_LENGTH]; - [[maybe_unused]] int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); + int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); DluAssert(res != -1); return finishedQuery; } @@ -324,7 +325,6 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi break; } case Leaderboard::Type::Survival: { - // Config option may reverse these oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); break; @@ -357,6 +357,15 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi return; } bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore; + // Nimbus station has a weird leaderboard where we need a custom scoring system + if (leaderboardType == Leaderboard::Type::SurvivalNS) { + newHighScore = newScore.GetPrimaryScore() > oldScore.GetPrimaryScore() || + (newScore.GetPrimaryScore() == oldScore.GetPrimaryScore() && newScore.GetSecondaryScore() < oldScore.GetSecondaryScore()); + } else if (leaderboardType == Leaderboard::Type::Survival && Game::config->GetValue("classic_survival_scoring") == "1") { + Score oldScoreFlipped(oldScore.GetSecondaryScore(), oldScore.GetPrimaryScore()); + Score newScoreFlipped(newScore.GetSecondaryScore(), newScore.GetPrimaryScore()); + newHighScore = newScoreFlipped > oldScoreFlipped; + } if (newHighScore) { saveQuery = FormatInsert(leaderboardType, newScore, true); } else if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore) { diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 9ccfe12a..dd7921db 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -50,7 +50,7 @@ RacingControlComponent::RacingControlComponent(Entity* parent) m_MainWorld = 1200; const auto worldID = Game::server->GetZoneID(); - if (dZoneManager::Instance()->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10; + if (dZoneManager::Instance()->CheckIfAccessibleZone((worldID / 10) * 10)) m_MainWorld = (worldID / 10) * 10; m_ActivityID = 42; CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); @@ -323,7 +323,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) { // Reset imagination to half its current value, rounded up to the nearest value divisible by 10, as it was done in live. if (destroyableComponent) destroyableComponent->SetImagination(respawnImagination); EntityManager::Instance()->SerializeEntity(vehicle); - }); + }); auto* characterComponent = player->GetComponent(); if (characterComponent != nullptr) { @@ -379,7 +379,6 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu const auto score = m_LoadedPlayers * 10 + data->finished; LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); - LeaderboardManager::SaveScore(player->GetObjectID(), m_ActivityID, static_cast(data->bestLapTime), static_cast(data->raceTime), static_cast(data->finished == 1)); // Giving rewards GameMessages::SendNotifyRacingClient( @@ -838,6 +837,7 @@ void RacingControlComponent::Update(float deltaTime) { "Completed time %llu, %llu", raceTime, raceTime * 1000); + LeaderboardManager::SaveScore(playerEntity->GetObjectID(), m_ActivityID, static_cast(player.bestLapTime), static_cast(player.raceTime), static_cast(player.finished == 1)); // Entire race time missionComponent->Progress(eMissionTaskType::RACING, (raceTime) * 1000, (LWOOBJID)eRacingTaskParam::TOTAL_TRACK_TIME); diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index ac775787..7f522eb5 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -8,6 +8,8 @@ #include "eMissionState.h" #include "MissionComponent.h" #include "Character.h" +#include "Game.h" +#include "dConfig.h" void BaseSurvivalServer::SetGameVariables(Entity* self) { this->constants = std::move(GetConstants()); @@ -354,6 +356,7 @@ void BaseSurvivalServer::GameOver(Entity* self) { const auto score = GetActivityValue(self, playerID, 0); const auto time = GetActivityValue(self, playerID, 1); + SaveScore(self, playerID, score, time); GameMessages::SendNotifyClientZoneObject(self->GetObjectID(), u"Update_ScoreBoard", time, 0, playerID, std::to_string(score), UNASSIGNED_SYSTEM_ADDRESS); @@ -377,7 +380,6 @@ void BaseSurvivalServer::GameOver(Entity* self) { } StopActivity(self, playerID, score, time); - SaveScore(self, playerID, time, score); } state.waveNumber = 1; diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 48144960..e240c7ca 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -378,7 +378,7 @@ void BaseWavesServer::GameOver(Entity* self, bool won) { } StopActivity(self, playerID, wave, time, score); - SaveScore(self, playerID, time, wave); + SaveScore(self, playerID, wave, time); } } From 238fc98ea541af108ee07a82b2e377c07b99aa14 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 21 Jun 2023 21:46:11 -0700 Subject: [PATCH 093/116] Fix shooting gallery leaderboard bugs - add weekly functionality for top scores - Fix shooting gallery score saving - remove extra leaderboard fetch --- dGame/LeaderboardManager.cpp | 16 +++++++------- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 21 +++++-------------- .../dlu/9_Update_Leaderboard_Storage.sql | 6 ++++-- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 2fd48dc3..f9e44b2a 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -89,12 +89,12 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); switch (leaderboardType) { case Type::ShootingGallery: - entry.push_back(new LDFData(u"HitPercentage", (rows->getInt("primaryScore") / 100.0f))); - // HitPercentage:3 between 0 and 1 - entry.push_back(new LDFData(u"Score", rows->getInt("secondaryScore"))); + entry.push_back(new LDFData(u"Score", rows->getInt("primaryScore"))); // Score:1 - entry.push_back(new LDFData(u"Streak", rows->getInt("tertiaryScore"))); + entry.push_back(new LDFData(u"Streak", rows->getInt("secondaryScore"))); // Streak:1 + entry.push_back(new LDFData(u"HitPercentage", (rows->getInt("tertiaryScore") / 100.0f))); + // HitPercentage:3 between 0 and 1 break; case Type::Racing: entry.push_back(new LDFData(u"BestTime", rows->getDouble("primaryScore"))); @@ -229,14 +229,14 @@ void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t r // For top query, we want to just rank all scores, but for all others we need the scores around a specific player std::string baseLookup; if (this->infoType == InfoType::Top) { - baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY "; + baseLookup = "SELECT id, last_played FROM leaderboard WHERE game_id = ? " + (this->weekly ? weeklyFilter : std::string("")) + " ORDER BY "; baseLookup += orderBase.data(); } else { - baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = "; + baseLookup = "SELECT id, last_played FROM leaderboard WHERE game_id = ? " + (this->weekly ? weeklyFilter : std::string("")) + " AND character_id = "; baseLookup += std::to_string(static_cast(this->relatedPlayer)); } baseLookup += " LIMIT 1"; - + Game::logger->LogDebug("LeaderboardManager", "query is %s", baseLookup.c_str()); std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseLookup)); baseQuery->setInt(1, this->gameID); std::unique_ptr baseResult(baseQuery->executeQuery()); @@ -251,7 +251,7 @@ void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t r int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd); DluAssert(res != -1); std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer.get())); - + Game::logger->LogDebug("LeaderboardManager", "Query is %s vars are %i %i %i", lookupBuffer.get(), this->gameID, this->relatedPlayer, relatedPlayerLeaderboardId); query->setInt(1, this->gameID); if (this->infoType == InfoType::Friends) { query->setInt(2, this->relatedPlayer); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 558c24c4..5b0dfc36 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -546,13 +546,13 @@ void SGCannon::StopGame(Entity* self, bool cancel) { // The player won, store all the score and send rewards if (!cancel) { - int32_t percentage = 50; + int32_t percentage = 0.0f; auto misses = self->GetVar(MissesVariable); auto fired = self->GetVar(ShotsFiredVariable); - // if (fired > 0) { - // percentage = misses / fired; - // } + if (fired > 0) { + percentage = misses / fired; + } auto* missionComponent = player->GetComponent(); @@ -566,7 +566,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { StopActivity(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), self->GetVar(MaxStreakVariable), percentage); SaveScore(self, player->GetObjectID(), - static_cast(self->GetVar(TotalScoreVariable)), percentage, static_cast(self->GetVar(MaxStreakVariable))); + static_cast(self->GetVar(TotalScoreVariable)), static_cast(self->GetVar(MaxStreakVariable)), percentage); self->SetNetworkVar(AudioFinalWaveDoneVariable, true); // Give the player the model rewards they earned @@ -580,17 +580,6 @@ void SGCannon::StopGame(Entity* self, bool cancel) { self->SetNetworkVar(u"UI_Rewards", GeneralUtils::to_u16string(self->GetVar(TotalScoreVariable)) + u"_0_0_0_0_0_0" ); - - GameMessages::SendRequestActivitySummaryLeaderboardData( - player->GetObjectID(), - self->GetObjectID(), - player->GetSystemAddress(), - GetGameID(self), - 1, - 10, - 0, - false - ); } GameMessages::SendActivityStop(self->GetObjectID(), false, cancel, player->GetSystemAddress()); diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql index a68cc2d8..c87e3501 100644 --- a/migrations/dlu/9_Update_Leaderboard_Storage.sql +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -5,8 +5,6 @@ ALTER TABLE leaderboard MODIFY time INT NOT NULL DEFAULT 0; /* Can only ALTER one column at a time... */ -ALTER TABLE leaderboard - CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); ALTER TABLE leaderboard CHANGE score primaryScore FLOAT NOT NULL DEFAULT 0; ALTER TABLE leaderboard CHANGE time secondaryScore FLOAT NOT NULL DEFAULT 0 AFTER primaryScore; @@ -14,3 +12,7 @@ ALTER TABLE leaderboard CHANGE time secondaryScore FLOAT NOT NULL DEFAULT 0 AFTE UPDATE leaderboard SET primaryScore = secondaryScore, secondaryScore = 0 WHERE game_id IN (1, 44, 46, 47, 48, 49, 53, 103, 104, 108, 1901); + +/* Do this last so we dont update entry times erroneously */ +ALTER TABLE leaderboard + CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); From d0e79d19fc2c4167dd5cd4c561b8cff12ac9ca94 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 21 Jun 2023 21:48:58 -0700 Subject: [PATCH 094/116] Update Metrics.hpp --- dCommon/Metrics.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dCommon/Metrics.hpp b/dCommon/Metrics.hpp index 7009701b..c03c914f 100644 --- a/dCommon/Metrics.hpp +++ b/dCommon/Metrics.hpp @@ -20,7 +20,6 @@ enum class MetricVariable : int32_t CPUTime, Sleep, Frame, - Leaderboard, }; struct Metric From 8156e5cc91f2907287a94e4e5fed50aed9429f4c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 21 Jun 2023 21:50:16 -0700 Subject: [PATCH 095/116] Update MigrationRunner.cpp --- dDatabase/MigrationRunner.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index 3cc4266e..5e70c401 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -109,7 +109,7 @@ void MigrationRunner::RunSQLiteMigrations() { // Check if there is an entry in the migration history table on the cdclient database. cdstmt = CDClientDatabase::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;"); - cdstmt.bind((int32_t)1, migration.name.c_str()); + cdstmt.bind((int32_t) 1, migration.name.c_str()); auto cdres = cdstmt.execQuery(); bool doExit = !cdres.eof(); cdres.finalize(); @@ -127,7 +127,7 @@ void MigrationRunner::RunSQLiteMigrations() { if (doExit) { // Insert into cdclient database if there is an entry in the main database but not the cdclient database. cdstmt = CDClientDatabase::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); - cdstmt.bind((int32_t)1, migration.name.c_str()); + cdstmt.bind((int32_t) 1, migration.name.c_str()); cdstmt.execQuery().finalize(); cdstmt.finalize(); continue; @@ -148,7 +148,7 @@ void MigrationRunner::RunSQLiteMigrations() { // Insert into cdclient database. cdstmt = CDClientDatabase::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); - cdstmt.bind((int32_t)1, migration.name.c_str()); + cdstmt.bind((int32_t) 1, migration.name.c_str()); cdstmt.execQuery().finalize(); cdstmt.finalize(); CDClientDatabase::ExecuteQuery("COMMIT;"); From 393733cc67a8e73090809ed7620c10d883d8056f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 21 Jun 2023 21:50:54 -0700 Subject: [PATCH 096/116] Update GameMessageHandler.cpp --- dGame/dGameMessages/GameMessageHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index ca7a98cb..be751598 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -45,7 +45,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System Entity* entity = EntityManager::Instance()->GetEntity(objectID); User* usr = UserManager::Instance()->GetUser(sysAddr); - if (messageID != eGameMessageType::READY_FOR_UPDATES) Game::logger->Log("GameMessageHandler", "message %i", messageID); + if (!entity) { Game::logger->Log("GameMessageHandler", "Failed to find associated entity (%llu), aborting GM (%X)!", objectID, messageID); From 85aa82b4b902b71c7f612f95c33ebf09c4196ece Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 21 Jun 2023 21:53:10 -0700 Subject: [PATCH 097/116] cleanup --- dGame/dGameMessages/GameMessages.cpp | 1 - tests/dGameTests/CMakeLists.txt | 1 - tests/dGameTests/GameDependencies.h | 2 - tests/dGameTests/LeaderboardTests.cpp | 79 --------------------------- 4 files changed, 83 deletions(-) delete mode 100644 tests/dGameTests/LeaderboardTests.cpp diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index f1f345ea..deae57d3 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1646,7 +1646,6 @@ void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, bitStream.Write(eGameMessageType::SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA); leaderboard->Serialize(&bitStream); - PacketUtils::SavePacket("leaderboardData.bin", (const char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed()); SEND_PACKET; } diff --git a/tests/dGameTests/CMakeLists.txt b/tests/dGameTests/CMakeLists.txt index 30b5e20b..b1fdaa07 100644 --- a/tests/dGameTests/CMakeLists.txt +++ b/tests/dGameTests/CMakeLists.txt @@ -1,6 +1,5 @@ set(DGAMETEST_SOURCES "GameDependencies.cpp" - "LeaderboardTests.cpp" ) add_subdirectory(dComponentsTests) diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 87f56ad0..353b53b8 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -6,7 +6,6 @@ #include "dServer.h" #include "EntityInfo.h" #include "EntityManager.h" -#include "Database.h" #include "dConfig.h" #include @@ -33,7 +32,6 @@ protected: Game::logger = new dLogger("./testing.log", true, true); Game::server = new dServerMock(); Game::config = new dConfig("worldconfig.ini"); - // Database::Connect(Game::config->GetValue("mysql_host"), Game::config->GetValue("mysql_database"), Game::config->GetValue("mysql_username"), Game::config->GetValue("mysql_password")); } void TearDownDependencies() { diff --git a/tests/dGameTests/LeaderboardTests.cpp b/tests/dGameTests/LeaderboardTests.cpp deleted file mode 100644 index 8cb833a3..00000000 --- a/tests/dGameTests/LeaderboardTests.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "LeaderboardManager.h" - -#include "BitStream.h" -#include "GameDependencies.h" -#include "Metrics.hpp" -#include - -class LeaderboardTests : public GameDependenciesTest { -protected: - void SetUp() override { - SetUpDependencies(); - } - void TearDown() override { - TearDownDependencies(); - } - - void TestLeaderboard(Leaderboard& leaderboard, int32_t entries) { - bitStream.Reset(); - Metrics::StartMeasurement(MetricVariable::Leaderboard); - for (int32_t i = 0; i < MAX_MEASURMENT_POINTS; i++) leaderboard.Serialize(&bitStream); - Metrics::EndMeasurement(MetricVariable::Leaderboard); - - auto timePassed = Metrics::GetMetric(MetricVariable::Leaderboard)->average; - Game::logger->Log("LeaderboardManager", "average time passed for %i leaderboard entries is %lluns", entries, timePassed); - bitStream.Reset(); - } - - void RunTests(uint32_t gameID, Leaderboard::Type type, Leaderboard::InfoType infoType) { - Game::logger->Log("LeaderboardTests", "Testing leaderboard %i for Serialize speed", infoType); - Leaderboard leaderboard(gameID, infoType, false, 14231, type); - leaderboard.SetupLeaderboard(true, 0, 10); - leaderboard.Serialize(&bitStream); - TestLeaderboard(leaderboard, 1); - TestLeaderboard(leaderboard, 10); - TestLeaderboard(leaderboard, 100); - TestLeaderboard(leaderboard, 1000); - } - - CBITSTREAM; -}; - -/** - * Initial metrics - * 19: [12-04-23 23:56:31] [LeaderboardManager] average time passed for 1 leaderboard entries is 1671700ns - * 19: [12-04-23 23:56:31] [LeaderboardManager] average time passed for 10 leaderboard entries is 8388900ns - * 19: [12-04-23 23:56:31] [LeaderboardManager] average time passed for 100 leaderboard entries is 54680133ns - * 19: [12-04-23 23:56:33] [LeaderboardManager] average time passed for 1000 leaderboard entries is 506289325ns - - * Only do each std::to_string once - * 19: [12-04-23 23:57:31] [LeaderboardManager] average time passed for 1 leaderboard entries is 1472700ns - * 19: [12-04-23 23:57:31] [LeaderboardManager] average time passed for 10 leaderboard entries is 7035650ns - * 19: [12-04-23 23:57:31] [LeaderboardManager] average time passed for 100 leaderboard entries is 45147466ns - * 19: [12-04-23 23:57:33] [LeaderboardManager] average time passed for 1000 leaderboard entries is 435724550ns - * - * Only do Result[0].Row[index] once - * 19: [12-04-23 23:59:43] [LeaderboardManager] average time passed for 1 leaderboard entries is 1357700ns - * 19: [12-04-23 23:59:43] [LeaderboardManager] average time passed for 10 leaderboard entries is 6635350ns - * 19: [12-04-23 23:59:43] [LeaderboardManager] average time passed for 100 leaderboard entries is 40247800ns - * 19: [12-04-23 23:59:45] [LeaderboardManager] average time passed for 1000 leaderboard entries is 400965900ns - * - * Switch to ostringstream - * 19: [13-04-23 00:24:44] [LeaderboardManager] average time passed for 1 leaderboard entries is 1334300ns - * 19: [13-04-23 00:24:44] [LeaderboardManager] average time passed for 10 leaderboard entries is 5566250ns - * 19: [13-04-23 00:24:44] [LeaderboardManager] average time passed for 100 leaderboard entries is 34640066ns - * 19: [13-04-23 00:24:46] [LeaderboardManager] average time passed for 1000 leaderboard entries is 357226950ns - * - * No more std::to_string and revert "Only do Result[0].Row[index] once" - * 19: [13-04-23 00:39:18] [LeaderboardManager] average time passed for 1 leaderboard entries is 979200ns - * 19: [13-04-23 00:39:18] [LeaderboardManager] average time passed for 10 leaderboard entries is 4053350ns - * 19: [13-04-23 00:39:18] [LeaderboardManager] average time passed for 100 leaderboard entries is 24785233ns - * 19: [13-04-23 00:39:19] [LeaderboardManager] average time passed for 1000 leaderboard entries is 279457375ns - */ - -// Commented tests out because we dont have a sql server running for tests -// TEST_F(LeaderboardTests, LeaderboardSpeedTest) { - // RunTests(1864, Leaderboard::Type::ShootingGallery , Leaderboard::InfoType::Top); - // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::MyStanding); - // RunTests(1864, Leaderboard::Type::ShootingGallery, Leaderboard::InfoType::Friends); -// } From 787dac7cd9322ddd7f0a9f200988270027c1a77f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 23 Jun 2023 06:49:58 -0700 Subject: [PATCH 098/116] Update Dockerfile (#1126) Fixes #1124 --- docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index a7d91855..c5638a20 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM gcc:11 as build +FROM gcc:12 as build WORKDIR /build @@ -40,7 +40,7 @@ RUN echo "Build server" && \ cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \ make -j $BUILD_THREADS -FROM gcc:11 as runtime +FROM gcc:12 as runtime RUN --mount=type=cache,id=runtime-apt-cache,target=/var/cache/apt \ apt update && \ From 41898bef86288c68c17cff9b1dcd53f8cf4721b7 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 23 Jun 2023 08:50:15 -0500 Subject: [PATCH 099/116] foot race player flag fix (#1125) and include fixes --- dNavigation/dTerrain/RawFile.h | 1 + dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp | 5 ++--- dZoneManager/LUTriggers.h | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dNavigation/dTerrain/RawFile.h b/dNavigation/dTerrain/RawFile.h index 84afae94..2a702c53 100644 --- a/dNavigation/dTerrain/RawFile.h +++ b/dNavigation/dTerrain/RawFile.h @@ -2,6 +2,7 @@ #include #include +#include class RawChunk; struct RawMesh; diff --git a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp index 4d1ae5f5..769a8fd9 100644 --- a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp +++ b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp @@ -6,8 +6,7 @@ void BaseFootRaceManager::OnStartup(Entity* self) { // TODO: Add to FootRaceStarter group } -void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, - int32_t param2, int32_t param3) { +void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { const auto splitArguments = GeneralUtils::SplitString(args, '_'); if (splitArguments.size() > 1) { @@ -37,7 +36,7 @@ void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, st if (character != nullptr) { character->SetPlayerFlag(115, false); if (param2 != -1) // Certain footraces set a flag - character->SetPlayerFlag(static_cast(param2), true); + character->SetPlayerFlag(param2, true); } StopActivity(self, player->GetObjectID(), 0, param1); diff --git a/dZoneManager/LUTriggers.h b/dZoneManager/LUTriggers.h index a93cd67d..75662778 100644 --- a/dZoneManager/LUTriggers.h +++ b/dZoneManager/LUTriggers.h @@ -3,6 +3,7 @@ #include #include +#include class Command; class Event; From c4135eac46ec025cf1b419856897eee9fae91d5b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 26 Jun 2023 00:51:28 -0700 Subject: [PATCH 100/116] Revert playerflags functions to uint instead of int (#1130) Prevents issue with negative numbers resulting in bugs. --- dGame/Character.cpp | 4 ++-- dGame/Character.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dGame/Character.cpp b/dGame/Character.cpp index 319b9376..dc3e0a71 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -418,7 +418,7 @@ void Character::WriteToDatabase() { delete printer; } -void Character::SetPlayerFlag(const int32_t flagId, const bool value) { +void Character::SetPlayerFlag(const uint32_t flagId, const bool value) { // If the flag is already set, we don't have to recalculate it if (GetPlayerFlag(flagId) == value) return; @@ -465,7 +465,7 @@ void Character::SetPlayerFlag(const int32_t flagId, const bool value) { GameMessages::SendNotifyClientFlagChange(m_ObjectID, flagId, value, m_ParentUser->GetSystemAddress()); } -bool Character::GetPlayerFlag(const int32_t flagId) const { +bool Character::GetPlayerFlag(const uint32_t flagId) const { // Calculate the index first const auto flagIndex = uint32_t(std::floor(flagId / 64)); diff --git a/dGame/Character.h b/dGame/Character.h index 3759f206..79ce0c0c 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -415,14 +415,14 @@ public: * @param flagId the ID of the flag to set * @param value the value to set for the flag */ - void SetPlayerFlag(int32_t flagId, bool value); + void SetPlayerFlag(uint32_t flagId, bool value); /** * Gets the value for a certain character flag * @param flagId the ID of the flag to get a value for * @return the value of the flag given the ID (the default is false, obviously) */ - bool GetPlayerFlag(int32_t flagId) const; + bool GetPlayerFlag(uint32_t flagId) const; /** * Notifies the character that they're now muted From 5cc7479f293f928d59d63f2e787cf7ed0c0b5050 Mon Sep 17 00:00:00 2001 From: Raine <16182738+uwainium@users.noreply.github.com> Date: Sat, 1 Jul 2023 18:40:34 -0400 Subject: [PATCH 101/116] Update credits (#1133) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f51b5e2a..b7e2a101 100644 --- a/README.md +++ b/README.md @@ -338,7 +338,7 @@ This is a Work in Progress, but below are some quick links to documentaion for s ## Former Contributors * TheMachine * Matthew -* [Raine](https://github.com/Rainebannister) +* [Raine](https://github.com/uwainium) * Bricknave ## Special Thanks From 9375c36c7bd65f065da1253fbc1371aca9716d0a Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Mon, 3 Jul 2023 11:58:49 -0500 Subject: [PATCH 102/116] fix: remove hardcoded rotations now that vehicles orient correctly (#1132) --- dGame/dComponents/InventoryComponent.cpp | 12 +----------- dGame/dUtilities/SlashCommandHandler.cpp | 12 ------------ 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 626c7ee9..b0471736 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -995,17 +995,7 @@ void InventoryComponent::HandlePossession(Item* item) { // Check to see if the mount is a vehicle, if so, flip it auto* vehicleComponent = mount->GetComponent(); - if (vehicleComponent) { - auto angles = startRotation.GetEulerAngles(); - // Make it right side up - angles.x -= PI; - // Make it going in the direction of the player - angles.y -= PI; - startRotation = NiQuaternion::FromEulerAngles(angles); - mount->SetRotation(startRotation); - // We're pod racing now - characterComponent->SetIsRacing(true); - } + if (vehicleComponent) characterComponent->SetIsRacing(true); // Setup the destroyable stats auto* destroyableComponent = mount->GetComponent(); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index b65bf723..47e0f0e4 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1267,18 +1267,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - auto vehiclePhysicsComponent = newEntity->GetComponent(); - 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); } From 455f9470a5ea4dd0153d2d43baf4226906985e06 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 15 Jul 2023 13:56:33 -0700 Subject: [PATCH 103/116] Move EntityManager to Game namespace (#1140) * Move EntityManager to Game namespace * move initialization to later Need to wait for dZoneManager to be initialized. * Fix bugs - Cannot delete from a RandomAccessIterator while in a range based for loop. Touchup zone manager initialize replace magic numbers with better named constants replace magic zonecontrol id with a more readable hex alternative condense stack variables move initializers closer to their use initialize entity manager with zone control change initialize timings If zone is not zero we expect to initialize the entity manager during zone manager initialization Add constexpr for zone control LOT * Add proper error handling * revert vanity changes * Update WorldServer.cpp * Update dZoneManager.cpp --- dCommon/Game.h | 2 + dGame/Character.cpp | 6 +- dGame/Entity.cpp | 28 ++-- dGame/EntityManager.cpp | 5 - dGame/EntityManager.h | 15 +-- dGame/LeaderboardManager.cpp | 6 +- dGame/Player.cpp | 16 +-- dGame/TradingManager.cpp | 4 +- dGame/UserManager.cpp | 2 +- dGame/dBehaviors/AirMovementBehavior.cpp | 2 +- dGame/dBehaviors/ApplyBuffBehavior.cpp | 4 +- dGame/dBehaviors/AreaOfEffectBehavior.cpp | 6 +- dGame/dBehaviors/BasicAttackBehavior.cpp | 10 +- dGame/dBehaviors/Behavior.cpp | 2 +- dGame/dBehaviors/BehaviorContext.cpp | 12 +- dGame/dBehaviors/BlockBehavior.cpp | 4 +- dGame/dBehaviors/BuffBehavior.cpp | 8 +- dGame/dBehaviors/CarBoostBehavior.cpp | 4 +- .../dBehaviors/ChangeOrientationBehavior.cpp | 10 +- dGame/dBehaviors/DamageAbsorptionBehavior.cpp | 4 +- dGame/dBehaviors/DamageReductionBehavior.cpp | 4 +- dGame/dBehaviors/DarkInspirationBehavior.cpp | 4 +- dGame/dBehaviors/FallSpeedBehavior.cpp | 8 +- dGame/dBehaviors/ForceMovementBehavior.cpp | 8 +- dGame/dBehaviors/HealBehavior.cpp | 2 +- dGame/dBehaviors/ImaginationBehavior.cpp | 2 +- dGame/dBehaviors/ImmunityBehavior.cpp | 4 +- dGame/dBehaviors/InterruptBehavior.cpp | 4 +- dGame/dBehaviors/JetPackBehavior.cpp | 4 +- dGame/dBehaviors/KnockbackBehavior.cpp | 2 +- dGame/dBehaviors/LootBuffBehavior.cpp | 8 +- dGame/dBehaviors/OverTimeBehavior.cpp | 4 +- dGame/dBehaviors/ProjectileAttackBehavior.cpp | 8 +- dGame/dBehaviors/PropertyTeleportBehavior.cpp | 4 +- dGame/dBehaviors/PullToPointBehavior.cpp | 4 +- dGame/dBehaviors/RemoveBuffBehavior.cpp | 2 +- dGame/dBehaviors/RepairBehavior.cpp | 2 +- dGame/dBehaviors/SkillEventBehavior.cpp | 8 +- dGame/dBehaviors/SpawnBehavior.cpp | 12 +- dGame/dBehaviors/SpeedBehavior.cpp | 8 +- dGame/dBehaviors/StunBehavior.cpp | 6 +- dGame/dBehaviors/SwitchBehavior.cpp | 4 +- dGame/dBehaviors/TacArcBehavior.cpp | 8 +- dGame/dBehaviors/TauntBehavior.cpp | 4 +- dGame/dBehaviors/VentureVisionBehavior.cpp | 4 +- dGame/dBehaviors/VerifyBehavior.cpp | 4 +- dGame/dComponents/BaseCombatAIComponent.cpp | 18 +-- dGame/dComponents/BouncerComponent.cpp | 8 +- dGame/dComponents/BuildBorderComponent.cpp | 2 +- .../ControllablePhysicsComponent.cpp | 8 +- dGame/dComponents/DestroyableComponent.cpp | 56 ++++---- dGame/dComponents/InventoryComponent.cpp | 22 ++-- dGame/dComponents/LUPExhibitComponent.cpp | 2 +- dGame/dComponents/MovementAIComponent.cpp | 6 +- dGame/dComponents/MovingPlatformComponent.cpp | 12 +- dGame/dComponents/PetComponent.cpp | 38 +++--- dGame/dComponents/PhantomPhysicsComponent.cpp | 6 +- dGame/dComponents/PossessorComponent.cpp | 10 +- .../PropertyManagementComponent.cpp | 26 ++-- dGame/dComponents/RacingControlComponent.cpp | 54 ++++---- dGame/dComponents/RailActivatorComponent.cpp | 2 +- dGame/dComponents/RebuildComponent.cpp | 38 +++--- .../RocketLaunchpadControlComponent.cpp | 2 +- .../dComponents/ScriptedActivityComponent.cpp | 14 +- .../dComponents/ShootingGalleryComponent.cpp | 2 +- dGame/dComponents/SkillComponent.cpp | 8 +- dGame/dComponents/SoundTriggerComponent.cpp | 4 +- dGame/dComponents/SwitchComponent.cpp | 8 +- dGame/dComponents/TriggerComponent.cpp | 12 +- dGame/dComponents/VehiclePhysicsComponent.cpp | 2 +- dGame/dGameMessages/GameMessageHandler.cpp | 14 +- dGame/dGameMessages/GameMessages.cpp | 124 +++++++++--------- dGame/dInventory/Item.cpp | 2 +- dGame/dInventory/ItemSetPassiveAbility.cpp | 4 +- dGame/dMission/Mission.cpp | 2 +- dGame/dMission/MissionTask.cpp | 8 +- dGame/dUtilities/SlashCommandHandler.cpp | 60 ++++----- dGame/dUtilities/VanityUtilities.cpp | 14 +- dNet/ClientPackets.cpp | 14 +- .../Enemy/AG/BossSpiderQueenEnemyServer.cpp | 30 ++--- .../02_server/Enemy/AM/AmDarklingDragon.cpp | 6 +- .../02_server/Enemy/FV/FvMaelstromCavalry.cpp | 4 +- .../02_server/Enemy/FV/FvMaelstromDragon.cpp | 10 +- .../02_server/Enemy/General/BaseEnemyApe.cpp | 10 +- .../02_server/Enemy/General/BaseEnemyMech.cpp | 4 +- .../Enemy/General/GfApeSmashingQB.cpp | 2 +- .../General/TreasureChestDragonServer.cpp | 2 +- .../02_server/Equipment/BootyDigServer.cpp | 4 +- .../Equipment/MaestromExtracticatorServer.cpp | 2 +- .../02_server/Map/AG/AgCagedBricksServer.cpp | 2 +- dScripts/02_server/Map/AG/AgMonumentBirds.cpp | 2 +- .../Map/AG/AgMonumentLaserServer.cpp | 4 +- .../02_server/Map/AG/AgMonumentRaceCancel.cpp | 2 +- .../02_server/Map/AG/AgMonumentRaceGoal.cpp | 2 +- .../02_server/Map/AG/NpcAgCourseStarter.cpp | 6 +- dScripts/02_server/Map/AG/NpcWispServer.cpp | 2 +- .../Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp | 6 +- dScripts/02_server/Map/AM/AmBlueX.cpp | 8 +- dScripts/02_server/Map/AM/AmBridge.cpp | 2 +- dScripts/02_server/Map/AM/AmDrawBridge.cpp | 6 +- .../02_server/Map/AM/AmShieldGenerator.cpp | 8 +- .../Map/AM/AmShieldGeneratorQuickbuild.cpp | 12 +- dScripts/02_server/Map/AM/AmSkullkinDrill.cpp | 18 +-- dScripts/02_server/Map/AM/AmSkullkinTower.cpp | 12 +- .../02_server/Map/FV/EnemyRoninSpawner.cpp | 4 +- .../02_server/Map/FV/FvHorsemenTrigger.cpp | 2 +- .../02_server/Map/FV/ImgBrickConsoleQB.cpp | 16 +-- .../Map/FV/Racing/RaceMaelstromGeiser.cpp | 4 +- .../02_server/Map/GF/GfCaptainsCannon.cpp | 4 +- dScripts/02_server/Map/GF/GfTikiTorch.cpp | 2 +- dScripts/02_server/Map/GF/MastTeleport.cpp | 4 +- .../Map/General/ForceVolumeServer.cpp | 2 +- .../General/Ninjago/NjIceRailActivator.cpp | 4 +- .../Map/General/Ninjago/NjRailPostServer.cpp | 2 +- .../02_server/Map/General/PetDigServer.cpp | 12 +- .../02_server/Map/General/PropertyDevice.cpp | 2 +- dScripts/02_server/Map/General/QbSpawner.cpp | 12 +- .../Map/General/WishingWellServer.cpp | 2 +- .../Map/NS/NsConcertChoiceBuildManager.cpp | 6 +- .../02_server/Map/NT/NtAssemblyTubeServer.cpp | 6 +- .../Map/NT/NtCombatChallengeDummy.cpp | 4 +- .../NT/NtCombatChallengeExplodingDummy.cpp | 4 +- .../Map/NT/NtCombatChallengeServer.cpp | 18 +-- .../02_server/Map/NT/NtImagBeamBuffer.cpp | 2 +- .../02_server/Map/NT/NtOverbuildServer.cpp | 2 +- .../02_server/Map/NT/NtParadoxPanelServer.cpp | 4 +- .../02_server/Map/NT/NtParadoxTeleServer.cpp | 6 +- .../Map/NT/NtSentinelWalkwayServer.cpp | 2 +- .../Map/NT/NtVentureCannonServer.cpp | 8 +- dScripts/02_server/Map/PR/HydrantBroken.cpp | 4 +- .../Property/AG_Small/EnemySpiderSpawner.cpp | 6 +- .../Map/Property/AG_Small/ZoneAgProperty.cpp | 22 ++-- .../Map/Property/PropertyBankInteract.cpp | 4 +- .../02_server/Map/VE/VeBricksampleServer.cpp | 2 +- dScripts/02_server/Map/VE/VeEpsilonServer.cpp | 2 +- .../Map/njhub/CatapultBaseServer.cpp | 10 +- .../Map/njhub/CatapultBouncerServer.cpp | 2 +- .../02_server/Map/njhub/CavePrisonCage.cpp | 22 ++-- .../Map/njhub/EnemySkeletonSpawner.cpp | 4 +- .../Map/njhub/MonCoreSmashableDoors.cpp | 2 +- .../Map/njhub/NjNPCMissionSpinjitzuServer.cpp | 2 +- dScripts/02_server/Map/njhub/NjWuNPC.cpp | 8 +- dScripts/02_server/Map/njhub/RainOfArrows.cpp | 8 +- .../boss_instance/NjMonastryBossInstance.cpp | 22 ++-- .../General/MinigameTreasureChestServer.cpp | 2 +- .../Objects/AgSurvivalBuffStation.cpp | 2 +- .../02_server/Objects/StinkyFishTarget.cpp | 6 +- dScripts/ActivityManager.cpp | 6 +- dScripts/BaseConsoleTeleportServer.cpp | 2 +- dScripts/BasePropertyServer.cpp | 42 +++--- dScripts/BaseSurvivalServer.cpp | 14 +- dScripts/BaseWavesServer.cpp | 24 ++-- dScripts/Darkitect.cpp | 4 +- .../EquipmentScripts/PersonalFortress.cpp | 4 +- dScripts/ScriptedPowerupSpawner.cpp | 2 +- dScripts/SpawnPetBaseServer.cpp | 8 +- dScripts/ai/ACT/ActVehicleDeathTrigger.cpp | 4 +- .../ai/ACT/FootRace/BaseFootRaceManager.cpp | 2 +- dScripts/ai/AG/AgBusDoor.cpp | 4 +- dScripts/ai/AG/AgFans.cpp | 10 +- dScripts/ai/AG/AgImagSmashable.cpp | 4 +- dScripts/ai/AG/AgJetEffectServer.cpp | 6 +- dScripts/ai/AG/AgQbElevator.cpp | 2 +- dScripts/ai/AG/AgQbWall.cpp | 2 +- dScripts/ai/AG/AgSpaceStuff.cpp | 8 +- dScripts/ai/FV/ActNinjaSensei.cpp | 2 +- dScripts/ai/FV/ActParadoxPipeFix.cpp | 8 +- dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp | 6 +- dScripts/ai/FV/FvConsoleRightQuickbuild.cpp | 6 +- dScripts/ai/FV/FvDragonSmashingGolemQb.cpp | 2 +- dScripts/ai/FV/FvFacilityBrick.cpp | 6 +- dScripts/ai/FV/FvFlyingCreviceDragon.cpp | 4 +- dScripts/ai/FV/FvNinjaGuard.cpp | 4 +- dScripts/ai/FV/FvPandaSpawnerServer.cpp | 10 +- dScripts/ai/GF/GfBanana.cpp | 12 +- dScripts/ai/GF/GfCampfire.cpp | 2 +- dScripts/ai/GF/PetDigBuild.cpp | 6 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 44 +++---- dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp | 6 +- .../ai/NS/NS_PP_01/PropertyDeathPlane.cpp | 2 +- dScripts/ai/NS/NsConcertInstrument.cpp | 8 +- dScripts/ai/NS/NsConcertQuickBuild.cpp | 14 +- dScripts/ai/NS/NsQbImaginationStatue.cpp | 2 +- dScripts/ai/NS/WH/RockHydrantBroken.cpp | 4 +- dScripts/ai/NS/WH/RockHydrantSmashable.cpp | 4 +- dScripts/ai/NS/WhFans.cpp | 6 +- dScripts/ai/PETS/HydrantSmashable.cpp | 4 +- dScripts/ai/PROPERTY/AG/AgPropGuard.cpp | 4 +- dScripts/ai/PROPERTY/AgPropguards.cpp | 2 +- .../OBJECTS/FvRaceSmashEggImagineServer.cpp | 4 +- .../RACING/OBJECTS/RaceImagineCrateServer.cpp | 4 +- .../ai/RACING/OBJECTS/RaceImaginePowerup.cpp | 2 +- .../ai/RACING/OBJECTS/RaceSmashServer.cpp | 2 +- dScripts/ai/WILD/WildNinjaSensei.cpp | 8 +- dWorldServer/WorldServer.cpp | 26 ++-- dZoneManager/Level.cpp | 2 +- dZoneManager/Spawner.cpp | 8 +- dZoneManager/dZoneManager.cpp | 17 ++- tests/dGameTests/GameDependencies.cpp | 15 ++- tests/dGameTests/GameDependencies.h | 5 +- 200 files changed, 861 insertions(+), 862 deletions(-) diff --git a/dCommon/Game.h b/dCommon/Game.h index 66f3f6b7..f099734a 100644 --- a/dCommon/Game.h +++ b/dCommon/Game.h @@ -10,6 +10,7 @@ class dConfig; class RakPeerInterface; class AssetManager; struct SystemAddress; +class EntityManager; namespace Game { extern dLogger* logger; @@ -22,4 +23,5 @@ namespace Game { extern AssetManager* assetManager; extern SystemAddress chatSysAddr; extern bool shouldShutdown; + extern EntityManager* entityManager; } diff --git a/dGame/Character.cpp b/dGame/Character.cpp index dc3e0a71..aa734271 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -290,7 +290,7 @@ void Character::DoQuickXMLDataParse() { void Character::UnlockEmote(int emoteID) { m_UnlockedEmotes.push_back(emoteID); - GameMessages::SendSetEmoteLockState(EntityManager::Instance()->GetEntity(m_ObjectID), false, emoteID); + GameMessages::SendSetEmoteLockState(Game::entityManager->GetEntity(m_ObjectID), false, emoteID); } void Character::SetBuildMode(bool buildMode) { @@ -424,7 +424,7 @@ void Character::SetPlayerFlag(const uint32_t flagId, const bool value) { if (value) { // Update the mission component: - auto* player = EntityManager::Instance()->GetEntity(m_ObjectID); + auto* player = Game::entityManager->GetEntity(m_ObjectID); if (player != nullptr) { auto* missionComponent = player->GetComponent(); @@ -602,7 +602,7 @@ void Character::SetCoins(int64_t newCoins, eLootSourceType lootSource) { m_Coins = newCoins; - GameMessages::SendSetCurrency(EntityManager::Instance()->GetEntity(m_ObjectID), m_Coins, 0, 0, 0, 0, true, lootSource); + GameMessages::SendSetCurrency(Game::entityManager->GetEntity(m_ObjectID), m_Coins, 0, 0, 0, 0, true, lootSource); } bool Character::HasBeenToWorld(LWOMAPID mapID) const { diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index bac07713..adf26c78 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -263,7 +263,7 @@ void Entity::Initialize() { NiQuaternion rot; const auto& targetSceneName = m_Character->GetTargetScene(); - auto* targetScene = EntityManager::Instance()->GetSpawnPointEntity(targetSceneName); + auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName); if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) { pos = m_Character->GetRespawnPoint(mapID); @@ -735,7 +735,7 @@ void Entity::Initialize() { } }); - if (!m_Character && EntityManager::Instance()->GetGhostingEnabled()) { + if (!m_Character && Game::entityManager->GetGhostingEnabled()) { // Don't ghost what is likely large scene elements if (HasComponent(eReplicaComponentType::SIMPLE_PHYSICS) && HasComponent(eReplicaComponentType::RENDER) && (m_Components.size() == 2 || (HasComponent(eReplicaComponentType::TRIGGER) && m_Components.size() == 3))) { goto no_ghosting; @@ -1284,12 +1284,12 @@ void Entity::Update(const float deltaTime) { } if (m_ShouldDestroyAfterUpdate) { - EntityManager::Instance()->DestroyEntity(this->GetObjectID()); + Game::entityManager->DestroyEntity(this->GetObjectID()); } } void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxName, const std::string& status) { - Entity* other = EntityManager::Instance()->GetEntity(otherEntity); + Entity* other = Game::entityManager->GetEntity(otherEntity); if (!other) return; for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { @@ -1303,7 +1303,7 @@ void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxN } void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) { - auto* other = EntityManager::Instance()->GetEntity(otherEntity); + auto* other = Game::entityManager->GetEntity(otherEntity); if (!other) return; for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { @@ -1350,7 +1350,7 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) { } void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) { - auto* other = EntityManager::Instance()->GetEntity(otherEntity); + auto* other = Game::entityManager->GetEntity(otherEntity); if (!other) return; for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { @@ -1504,13 +1504,13 @@ void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u auto* destroyableComponent = GetComponent(); if (destroyableComponent == nullptr) { - Kill(EntityManager::Instance()->GetEntity(source)); + Kill(Game::entityManager->GetEntity(source)); return; } auto* possessorComponent = GetComponent(); if (possessorComponent) { if (possessorComponent->GetPossessable() != LWOOBJID_EMPTY) { - auto* mount = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* mount = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (mount) possessorComponent->Dismount(mount, true); } } @@ -1538,7 +1538,7 @@ void Entity::Kill(Entity* murderer) { } if (!IsPlayer()) { - EntityManager::Instance()->DestroyEntity(this); + Game::entityManager->DestroyEntity(this); } const auto& grpNameQBShowBricks = GetVar(u"grpNameQBShowBricks"); @@ -1719,7 +1719,7 @@ void Entity::CancelCallbackTimers() { void Entity::ScheduleKillAfterUpdate(Entity* murderer) { //if (m_Info.spawner) m_Info.spawner->ScheduleKill(this); - EntityManager::Instance()->ScheduleForKill(this); + Game::entityManager->ScheduleForKill(this); if (murderer) m_ScheduleKiller = murderer; } @@ -1763,7 +1763,7 @@ void Entity::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) { Entity* Entity::GetOwner() const { if (m_OwnerOverride != LWOOBJID_EMPTY) { - auto* other = EntityManager::Instance()->GetEntity(m_OwnerOverride); + auto* other = Game::entityManager->GetEntity(m_OwnerOverride); if (other != nullptr) { return other->GetOwner(); @@ -1907,7 +1907,7 @@ void Entity::SetPosition(NiPoint3 position) { vehicel->SetPosition(position); } - EntityManager::Instance()->SerializeEntity(this); + Game::entityManager->SerializeEntity(this); } void Entity::SetRotation(NiQuaternion rotation) { @@ -1935,7 +1935,7 @@ void Entity::SetRotation(NiQuaternion rotation) { vehicel->SetRotation(rotation); } - EntityManager::Instance()->SerializeEntity(this); + Game::entityManager->SerializeEntity(this); } bool Entity::GetBoolean(const std::u16string& name) const { @@ -1987,7 +1987,7 @@ std::vector& Entity::GetTargetsInPhantom() { for (auto i = 0u; i < m_TargetsInPhantom.size(); ++i) { const auto id = m_TargetsInPhantom.at(i); - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity == nullptr) { continue; diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 0fc859bd..e0baa61a 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -25,8 +25,6 @@ #include "eReplicaComponentType.h" #include "eReplicaPacketType.h" -EntityManager* EntityManager::m_Address = nullptr; - // Configure which zones have ghosting disabled, mostly small worlds. std::vector EntityManager::m_GhostingExcludedZones = { // Small zones @@ -80,9 +78,6 @@ void EntityManager::Initialize() { if (dZoneManager::Instance()->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false; } -EntityManager::~EntityManager() { -} - Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentEntity, const bool controller, const LWOOBJID explicitId) { // Determine the objectID for the new entity diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index b524344c..9bea0618 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -1,12 +1,13 @@ #ifndef ENTITYMANAGER_H #define ENTITYMANAGER_H -#include "dCommonVars.h" #include #include #include #include +#include "dCommonVars.h" + class Entity; class EntityInfo; class Player; @@ -17,19 +18,8 @@ struct SystemAddress; class EntityManager { public: - static EntityManager* Instance() { - if (!m_Address) { - m_Address = new EntityManager(); - m_Address->Initialize(); - } - - return m_Address; - } - void Initialize(); - ~EntityManager(); - void UpdateEntities(float deltaTime); Entity* CreateEntity(EntityInfo info, User* user = nullptr, Entity* parentEntity = nullptr, bool controller = false, LWOOBJID explicitId = LWOOBJID_EMPTY); void DestroyEntity(const LWOOBJID& objectID); @@ -89,7 +79,6 @@ private: void KillEntities(); void DeleteEntities(); - static EntityManager* m_Address; //For singleton method static std::vector m_GhostingExcludedZones; static std::vector m_GhostingExcludedLOTs; diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d85a95d4..edc39f75 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -66,14 +66,14 @@ uint32_t Leaderboard::GetInfoType() const { } void Leaderboard::Send(LWOOBJID targetID) const { - auto* player = EntityManager::Instance()->GetEntity(relatedPlayer); + auto* player = Game::entityManager->GetEntity(relatedPlayer); if (player != nullptr) { GameMessages::SendActivitySummaryLeaderboardData(targetID, this, player->GetSystemAddress()); } } void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t score, uint32_t time) { - const auto* player = EntityManager::Instance()->GetEntity(playerID); + const auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return; @@ -235,7 +235,7 @@ Leaderboard* LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoTy if (infoType == Standings || infoType == Friends) { auto characterID = 0; - const auto* player = EntityManager::Instance()->GetEntity(playerID); + const auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { auto* character = player->GetCharacter(); if (character != nullptr) diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 2e194e6a..55881dca 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -85,7 +85,7 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) { const auto objid = GetObjectID(); ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, zoneId, 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 == nullptr) { return; @@ -108,7 +108,7 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) { WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift); - EntityManager::Instance()->DestructEntity(entity); + Game::entityManager->DestructEntity(entity); return; }); } @@ -135,13 +135,13 @@ void Player::RemoveLimboConstruction(LWOOBJID objectId) { void Player::ConstructLimboEntities() { for (const auto objectId : m_LimboConstructions) { - auto* entity = EntityManager::Instance()->GetEntity(objectId); + auto* entity = Game::entityManager->GetEntity(objectId); if (entity == nullptr) { continue; } - EntityManager::Instance()->ConstructEntity(entity, m_SystemAddress); + Game::entityManager->ConstructEntity(entity, m_SystemAddress); } m_LimboConstructions.clear(); @@ -224,7 +224,7 @@ Player* Player::GetPlayer(const SystemAddress& sysAddr) { } Player* Player::GetPlayer(const std::string& name) { - const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); + const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); for (auto* character : characters) { if (!character->IsPlayer()) continue; @@ -269,7 +269,7 @@ Player::~Player() { continue; } - auto* entity = EntityManager::Instance()->GetGhostCandidate(id); + auto* entity = Game::entityManager->GetGhostCandidate(id); if (entity != nullptr) { entity->SetObservers(entity->GetObservers() - 1); @@ -285,12 +285,12 @@ Player::~Player() { } if (IsPlayer()) { - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerExit(zoneControl, this); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { diff --git a/dGame/TradingManager.cpp b/dGame/TradingManager.cpp index 281c003d..09d452b3 100644 --- a/dGame/TradingManager.cpp +++ b/dGame/TradingManager.cpp @@ -40,11 +40,11 @@ LWOOBJID Trade::GetParticipantB() const { } Entity* Trade::GetParticipantAEntity() const { - return EntityManager::Instance()->GetEntity(m_ParticipantA); + return Game::entityManager->GetEntity(m_ParticipantA); } Entity* Trade::GetParticipantBEntity() const { - return EntityManager::Instance()->GetEntity(m_ParticipantB); + return Game::entityManager->GetEntity(m_ParticipantB); } void Trade::SetCoins(LWOOBJID participant, uint64_t coins) { diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 0161395c..9e409019 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -220,7 +220,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) { skillComponent->Reset(); } - EntityManager::Instance()->DestroyEntity(chars[i]->GetEntity()); + Game::entityManager->DestroyEntity(chars[i]->GetEntity()); chars[i]->SaveXMLToDatabase(); diff --git a/dGame/dBehaviors/AirMovementBehavior.cpp b/dGame/dBehaviors/AirMovementBehavior.cpp index dbfde465..a6d749d3 100644 --- a/dGame/dBehaviors/AirMovementBehavior.cpp +++ b/dGame/dBehaviors/AirMovementBehavior.cpp @@ -39,7 +39,7 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitS auto* behavior = CreateBehavior(behaviorId); - if (EntityManager::Instance()->GetEntity(target) != nullptr) { + if (Game::entityManager->GetEntity(target) != nullptr) { branch.target = target; } diff --git a/dGame/dBehaviors/ApplyBuffBehavior.cpp b/dGame/dBehaviors/ApplyBuffBehavior.cpp index 35b0f269..c94762aa 100644 --- a/dGame/dBehaviors/ApplyBuffBehavior.cpp +++ b/dGame/dBehaviors/ApplyBuffBehavior.cpp @@ -6,7 +6,7 @@ void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target); if (entity == nullptr) return; @@ -19,7 +19,7 @@ void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS } void ApplyBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) return; diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index dedede2a..e43d542d 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -47,7 +47,7 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b } void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* self = EntityManager::Instance()->GetEntity(context->caster); + auto* self = Game::entityManager->GetEntity(context->caster); if (self == nullptr) { Game::logger->Log("AreaOfEffectBehavior", "Invalid self for (%llu)!", context->originator); @@ -58,7 +58,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream std::vector targets; - auto* presetTarget = EntityManager::Instance()->GetEntity(branch.target); + auto* presetTarget = Game::entityManager->GetEntity(branch.target); if (presetTarget != nullptr) { if (this->m_radius * this->m_radius >= Vector3::DistanceSquared(reference, presetTarget->GetPosition())) { @@ -75,7 +75,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream // Gets all of the valid targets, passing in if should target enemies and friends for (auto validTarget : context->GetValidTargets(m_ignoreFaction, includeFaction, m_TargetSelf == 1, m_targetEnemy == 1, m_targetFriend == 1)) { - auto* entity = EntityManager::Instance()->GetEntity(validTarget); + auto* entity = Game::entityManager->GetEntity(validTarget); if (entity == nullptr) { Game::logger->Log("AreaOfEffectBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator); diff --git a/dGame/dBehaviors/BasicAttackBehavior.cpp b/dGame/dBehaviors/BasicAttackBehavior.cpp index f8693795..0a21383b 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.cpp +++ b/dGame/dBehaviors/BasicAttackBehavior.cpp @@ -9,7 +9,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { if (context->unmanaged) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); auto* destroyableComponent = entity->GetComponent(); if (destroyableComponent != nullptr) { @@ -38,7 +38,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi } void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target); + auto* targetEntity = Game::entityManager->GetEntity(branch.target); if (!targetEntity) { Game::logger->Log("BasicAttackBehavior", "Target targetEntity %llu not found.", branch.target); return; @@ -61,7 +61,7 @@ void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::Bit if (isBlocked) { destroyableComponent->SetAttacksToBlock(std::min(destroyableComponent->GetAttacksToBlock() - 1, 0U)); - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); this->m_OnFailBlocked->Handle(context, bitStream, branch); return; } @@ -155,7 +155,7 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* } void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target); + auto* targetEntity = Game::entityManager->GetEntity(branch.target); if (!targetEntity) { Game::logger->Log("BasicAttackBehavior", "Target entity %llu is null!", branch.target); return; @@ -173,7 +173,7 @@ void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet if (isBlocking) { destroyableComponent->SetAttacksToBlock(destroyableComponent->GetAttacksToBlock() - 1); - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); this->m_OnFailBlocked->Calculate(context, bitStream, branch); return; } diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 8b34507a..6fe84a9f 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -314,7 +314,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { // For use with enemies, to display the correct damage animations on the players void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID secondary) { - auto* targetEntity = EntityManager::Instance()->GetEntity(target); + auto* targetEntity = Game::entityManager->GetEntity(target); if (targetEntity == nullptr) { return; diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index c7db4208..43ba8457 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -27,7 +27,7 @@ BehaviorEndEntry::BehaviorEndEntry() { } uint32_t BehaviorContext::GetUniqueSkillId() const { - auto* entity = EntityManager::Instance()->GetEntity(this->originator); + auto* entity = Game::entityManager->GetEntity(this->originator); if (entity == nullptr) { Game::logger->Log("BehaviorContext", "Invalid entity for (%llu)!", this->originator); @@ -94,11 +94,11 @@ void BehaviorContext::ScheduleUpdate(const LWOOBJID id) { void BehaviorContext::ExecuteUpdates() { for (const auto& id : this->scheduledUpdates) { - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity == nullptr) continue; - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } this->scheduledUpdates.clear(); @@ -308,7 +308,7 @@ void BehaviorContext::Reset() { } std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf, bool targetEnemy, bool targetFriend) const { - auto* entity = EntityManager::Instance()->GetEntity(this->caster); + auto* entity = Game::entityManager->GetEntity(this->caster); std::vector targets; @@ -320,7 +320,7 @@ std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, in if (!ignoreFaction && !includeFaction) { for (auto entry : entity->GetTargetsInPhantom()) { - auto* instance = EntityManager::Instance()->GetEntity(entry); + auto* instance = Game::entityManager->GetEntity(entry); if (instance == nullptr) { continue; @@ -336,7 +336,7 @@ std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, in return targets; } - auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS); + auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS); for (auto* candidate : entities) { const auto id = candidate->GetObjectID(); diff --git a/dGame/dBehaviors/BlockBehavior.cpp b/dGame/dBehaviors/BlockBehavior.cpp index cdbb3d80..19db0267 100644 --- a/dGame/dBehaviors/BlockBehavior.cpp +++ b/dGame/dBehaviors/BlockBehavior.cpp @@ -10,7 +10,7 @@ void BlockBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto target = context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); @@ -40,7 +40,7 @@ void BlockBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt void BlockBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { const auto target = context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/BuffBehavior.cpp b/dGame/dBehaviors/BuffBehavior.cpp index a39fd165..2c06dbd4 100644 --- a/dGame/dBehaviors/BuffBehavior.cpp +++ b/dGame/dBehaviors/BuffBehavior.cpp @@ -10,7 +10,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target); @@ -30,7 +30,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream component->SetMaxArmor(component->GetMaxArmor() + this->m_armor); component->SetMaxImagination(component->GetMaxImagination() + this->m_imagination); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); if (!context->unmanaged) { if (branch.duration > 0) { @@ -44,7 +44,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target); @@ -64,7 +64,7 @@ void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch component->SetMaxArmor(component->GetMaxArmor() - this->m_armor); component->SetMaxImagination(component->GetMaxImagination() - this->m_imagination); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void BuffBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, LWOOBJID second) { diff --git a/dGame/dBehaviors/CarBoostBehavior.cpp b/dGame/dBehaviors/CarBoostBehavior.cpp index 1ab0af95..e2929863 100644 --- a/dGame/dBehaviors/CarBoostBehavior.cpp +++ b/dGame/dBehaviors/CarBoostBehavior.cpp @@ -11,7 +11,7 @@ void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { GameMessages::SendVehicleAddPassiveBoostAction(branch.target, UNASSIGNED_SYSTEM_ADDRESS); - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { return; @@ -22,7 +22,7 @@ void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitSt auto* possessableComponent = entity->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* characterComponent = possessor->GetComponent(); diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.cpp b/dGame/dBehaviors/ChangeOrientationBehavior.cpp index 36a2e6a8..445c76df 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.cpp +++ b/dGame/dBehaviors/ChangeOrientationBehavior.cpp @@ -5,14 +5,14 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { Entity* sourceEntity; - if (this->m_orientCaster) sourceEntity = EntityManager::Instance()->GetEntity(context->originator); - else sourceEntity = EntityManager::Instance()->GetEntity(branch.target); + if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator); + else sourceEntity = Game::entityManager->GetEntity(branch.target); if (!sourceEntity) return; if (this->m_toTarget) { Entity* destinationEntity; - if (this->m_orientCaster) destinationEntity = EntityManager::Instance()->GetEntity(branch.target); - else destinationEntity = EntityManager::Instance()->GetEntity(context->originator); + if (this->m_orientCaster) destinationEntity = Game::entityManager->GetEntity(branch.target); + else destinationEntity = Game::entityManager->GetEntity(context->originator); if (!destinationEntity) return; sourceEntity->SetRotation( @@ -23,7 +23,7 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector(); sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle)); } else return; - EntityManager::Instance()->SerializeEntity(sourceEntity); + Game::entityManager->SerializeEntity(sourceEntity); return; } diff --git a/dGame/dBehaviors/DamageAbsorptionBehavior.cpp b/dGame/dBehaviors/DamageAbsorptionBehavior.cpp index 48dbf705..f9936767 100644 --- a/dGame/dBehaviors/DamageAbsorptionBehavior.cpp +++ b/dGame/dBehaviors/DamageAbsorptionBehavior.cpp @@ -8,7 +8,7 @@ #include "DestroyableComponent.h" void DamageAbsorptionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); @@ -34,7 +34,7 @@ void DamageAbsorptionBehavior::Calculate(BehaviorContext* context, RakNet::BitSt } void DamageAbsorptionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(second); + auto* target = Game::entityManager->GetEntity(second); if (target == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second); diff --git a/dGame/dBehaviors/DamageReductionBehavior.cpp b/dGame/dBehaviors/DamageReductionBehavior.cpp index 2b18b7c2..7645ec7b 100644 --- a/dGame/dBehaviors/DamageReductionBehavior.cpp +++ b/dGame/dBehaviors/DamageReductionBehavior.cpp @@ -8,7 +8,7 @@ #include "DestroyableComponent.h" void DamageReductionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", branch.target); @@ -32,7 +32,7 @@ void DamageReductionBehavior::Calculate(BehaviorContext* context, RakNet::BitStr } void DamageReductionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(second); + auto* target = Game::entityManager->GetEntity(second); if (target == nullptr) { Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", second); diff --git a/dGame/dBehaviors/DarkInspirationBehavior.cpp b/dGame/dBehaviors/DarkInspirationBehavior.cpp index ea80cbba..4e9890e3 100644 --- a/dGame/dBehaviors/DarkInspirationBehavior.cpp +++ b/dGame/dBehaviors/DarkInspirationBehavior.cpp @@ -7,7 +7,7 @@ #include "BehaviorContext.h" void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target); @@ -26,7 +26,7 @@ void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream } void DarkInspirationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/FallSpeedBehavior.cpp b/dGame/dBehaviors/FallSpeedBehavior.cpp index 158c87f6..dfbdec2a 100644 --- a/dGame/dBehaviors/FallSpeedBehavior.cpp +++ b/dGame/dBehaviors/FallSpeedBehavior.cpp @@ -8,13 +8,13 @@ void FallSpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { // make sure required parameter has non-default value if (m_PercentSlowed == 0.0f) return; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->SetGravityScale(m_PercentSlowed); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); if (branch.duration > 0.0f) { context->RegisterTimerBehavior(this, branch); @@ -36,13 +36,13 @@ void FallSpeedBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext b } void FallSpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->SetGravityScale(1); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); } void FallSpeedBehavior::Load(){ diff --git a/dGame/dBehaviors/ForceMovementBehavior.cpp b/dGame/dBehaviors/ForceMovementBehavior.cpp index 52359cf7..97208236 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.cpp +++ b/dGame/dBehaviors/ForceMovementBehavior.cpp @@ -42,7 +42,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea return; } - auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster); + auto* casterEntity = Game::entityManager->GetEntity(context->caster); if (casterEntity != nullptr) { auto* controllablePhysicsComponent = casterEntity->GetComponent(); if (controllablePhysicsComponent != nullptr) { @@ -51,7 +51,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25); } - EntityManager::Instance()->SerializeEntity(casterEntity); + Game::entityManager->SerializeEntity(casterEntity); } } @@ -72,7 +72,7 @@ void ForceMovementBehavior::Load() { } void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster); + auto* casterEntity = Game::entityManager->GetEntity(context->caster); if (casterEntity != nullptr) { auto* controllablePhysicsComponent = casterEntity->GetComponent(); if (controllablePhysicsComponent != nullptr) { @@ -80,7 +80,7 @@ void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::Bi controllablePhysicsComponent->SetPosition(controllablePhysicsComponent->GetPosition() + controllablePhysicsComponent->GetVelocity() * m_Duration); controllablePhysicsComponent->SetVelocity({}); - EntityManager::Instance()->SerializeEntity(casterEntity); + Game::entityManager->SerializeEntity(casterEntity); } } diff --git a/dGame/dBehaviors/HealBehavior.cpp b/dGame/dBehaviors/HealBehavior.cpp index 66fe2c79..dae009d4 100644 --- a/dGame/dBehaviors/HealBehavior.cpp +++ b/dGame/dBehaviors/HealBehavior.cpp @@ -8,7 +8,7 @@ void HealBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) { Game::logger->Log("HealBehavior", "Failed to find entity for (%llu)!", branch.target); diff --git a/dGame/dBehaviors/ImaginationBehavior.cpp b/dGame/dBehaviors/ImaginationBehavior.cpp index 59b192b0..50f7e046 100644 --- a/dGame/dBehaviors/ImaginationBehavior.cpp +++ b/dGame/dBehaviors/ImaginationBehavior.cpp @@ -7,7 +7,7 @@ void ImaginationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) { return; diff --git a/dGame/dBehaviors/ImmunityBehavior.cpp b/dGame/dBehaviors/ImmunityBehavior.cpp index a5dd4c85..ba4a8b77 100644 --- a/dGame/dBehaviors/ImmunityBehavior.cpp +++ b/dGame/dBehaviors/ImmunityBehavior.cpp @@ -10,7 +10,7 @@ #include "eStateChangeType.h" void ImmunityBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); @@ -56,7 +56,7 @@ void ImmunityBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi } void ImmunityBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(second); + auto* target = Game::entityManager->GetEntity(second); if (!target) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second); diff --git a/dGame/dBehaviors/InterruptBehavior.cpp b/dGame/dBehaviors/InterruptBehavior.cpp index 9035c092..ffe3bb8b 100644 --- a/dGame/dBehaviors/InterruptBehavior.cpp +++ b/dGame/dBehaviors/InterruptBehavior.cpp @@ -42,7 +42,7 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (branch.target == context->originator) return; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) return; @@ -67,7 +67,7 @@ void InterruptBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* b if (branch.target == context->originator) return; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) return; diff --git a/dGame/dBehaviors/JetPackBehavior.cpp b/dGame/dBehaviors/JetPackBehavior.cpp index e7d76560..134dd0fb 100644 --- a/dGame/dBehaviors/JetPackBehavior.cpp +++ b/dGame/dBehaviors/JetPackBehavior.cpp @@ -6,7 +6,7 @@ #include "Character.h" void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); GameMessages::SendSetJetPackMode(entity, true, this->m_BypassChecks, this->m_EnableHover, this->m_effectId, this->m_Airspeed, this->m_MaxAirspeed, this->m_VerticalVelocity, this->m_WarningEffectID); @@ -20,7 +20,7 @@ void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_st } void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); GameMessages::SendSetJetPackMode(entity, false); diff --git a/dGame/dBehaviors/KnockbackBehavior.cpp b/dGame/dBehaviors/KnockbackBehavior.cpp index 1b878ed0..d67ebbc8 100644 --- a/dGame/dBehaviors/KnockbackBehavior.cpp +++ b/dGame/dBehaviors/KnockbackBehavior.cpp @@ -21,7 +21,7 @@ void KnockbackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS void KnockbackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { bool blocked = false; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target != nullptr) { auto* destroyableComponent = target->GetComponent(); diff --git a/dGame/dBehaviors/LootBuffBehavior.cpp b/dGame/dBehaviors/LootBuffBehavior.cpp index 6e5634fc..c7a6b36a 100644 --- a/dGame/dBehaviors/LootBuffBehavior.cpp +++ b/dGame/dBehaviors/LootBuffBehavior.cpp @@ -1,14 +1,14 @@ #include "LootBuffBehavior.h" void LootBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto target = EntityManager::Instance()->GetEntity(context->caster); + auto target = Game::entityManager->GetEntity(context->caster); if (!target) return; auto controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->AddPickupRadiusScale(m_Scale); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); if (branch.duration > 0) context->RegisterTimerBehavior(this, branch); @@ -19,14 +19,14 @@ void LootBuffBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi } void LootBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - auto target = EntityManager::Instance()->GetEntity(context->caster); + auto target = Game::entityManager->GetEntity(context->caster); if (!target) return; auto controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->RemovePickupRadiusScale(m_Scale); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); } void LootBuffBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { diff --git a/dGame/dBehaviors/OverTimeBehavior.cpp b/dGame/dBehaviors/OverTimeBehavior.cpp index 5afbbd26..49077f0f 100644 --- a/dGame/dBehaviors/OverTimeBehavior.cpp +++ b/dGame/dBehaviors/OverTimeBehavior.cpp @@ -14,13 +14,13 @@ void OverTimeBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto originator = context->originator; - auto* entity = EntityManager::Instance()->GetEntity(originator); + auto* entity = Game::entityManager->GetEntity(originator); if (entity == nullptr) return; for (size_t i = 0; i < m_NumIntervals; i++) { entity->AddCallbackTimer((i + 1) * m_Delay, [originator, branch, this]() { - auto* entity = EntityManager::Instance()->GetEntity(originator); + auto* entity = Game::entityManager->GetEntity(originator); if (entity == nullptr) return; diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.cpp b/dGame/dBehaviors/ProjectileAttackBehavior.cpp index f65421cb..eb435d7c 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.cpp +++ b/dGame/dBehaviors/ProjectileAttackBehavior.cpp @@ -16,7 +16,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea return; }; - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator); @@ -40,7 +40,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea }; } - auto* targetEntity = EntityManager::Instance()->GetEntity(target); + auto* targetEntity = Game::entityManager->GetEntity(target); for (auto i = 0u; i < this->m_projectileCount; ++i) { LWOOBJID projectileId{}; @@ -61,7 +61,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { bitStream->Write(branch.target); - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator); @@ -78,7 +78,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt } - auto* other = EntityManager::Instance()->GetEntity(branch.target); + auto* other = Game::entityManager->GetEntity(branch.target); if (other == nullptr) { Game::logger->Log("ProjectileAttackBehavior", "Invalid projectile target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/PropertyTeleportBehavior.cpp b/dGame/dBehaviors/PropertyTeleportBehavior.cpp index 447b085b..c49c821d 100644 --- a/dGame/dBehaviors/PropertyTeleportBehavior.cpp +++ b/dGame/dBehaviors/PropertyTeleportBehavior.cpp @@ -12,7 +12,7 @@ #include "dZoneManager.h" void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* caster = EntityManager::Instance()->GetEntity(context->caster); + auto* caster = Game::entityManager->GetEntity(context->caster); if (!caster) return; auto* character = caster->GetCharacter(); @@ -32,7 +32,7 @@ void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStrea ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, 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(); diff --git a/dGame/dBehaviors/PullToPointBehavior.cpp b/dGame/dBehaviors/PullToPointBehavior.cpp index 7427ccc4..e18443f7 100644 --- a/dGame/dBehaviors/PullToPointBehavior.cpp +++ b/dGame/dBehaviors/PullToPointBehavior.cpp @@ -6,9 +6,9 @@ #include "MovementAIComponent.h" void PullToPointBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (entity == nullptr || target == nullptr) { return; diff --git a/dGame/dBehaviors/RemoveBuffBehavior.cpp b/dGame/dBehaviors/RemoveBuffBehavior.cpp index be3066ac..c6d2c9c9 100644 --- a/dGame/dBehaviors/RemoveBuffBehavior.cpp +++ b/dGame/dBehaviors/RemoveBuffBehavior.cpp @@ -6,7 +6,7 @@ #include "BuffComponent.h" void RemoveBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(context->caster); + auto* entity = Game::entityManager->GetEntity(context->caster); if (!entity) return; auto* buffComponent = entity->GetComponent(); diff --git a/dGame/dBehaviors/RepairBehavior.cpp b/dGame/dBehaviors/RepairBehavior.cpp index ce2e5fd2..d2967921 100644 --- a/dGame/dBehaviors/RepairBehavior.cpp +++ b/dGame/dBehaviors/RepairBehavior.cpp @@ -8,7 +8,7 @@ #include "eReplicaComponentType.h" void RepairBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) { Game::logger->Log("RepairBehavior", "Failed to find entity for (%llu)!", branch.target); diff --git a/dGame/dBehaviors/SkillEventBehavior.cpp b/dGame/dBehaviors/SkillEventBehavior.cpp index 837d70c9..4205c28b 100644 --- a/dGame/dBehaviors/SkillEventBehavior.cpp +++ b/dGame/dBehaviors/SkillEventBehavior.cpp @@ -5,8 +5,8 @@ #include "CppScripts.h" void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); - auto* caster = EntityManager::Instance()->GetEntity(context->originator); + auto* target = Game::entityManager->GetEntity(branch.target); + auto* caster = Game::entityManager->GetEntity(context->originator); if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) { @@ -17,8 +17,8 @@ void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit void SkillEventBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); - auto* caster = EntityManager::Instance()->GetEntity(context->originator); + auto* target = Game::entityManager->GetEntity(branch.target); + auto* caster = Game::entityManager->GetEntity(context->originator); if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) { diff --git a/dGame/dBehaviors/SpawnBehavior.cpp b/dGame/dBehaviors/SpawnBehavior.cpp index 75c84f6c..2803251a 100644 --- a/dGame/dBehaviors/SpawnBehavior.cpp +++ b/dGame/dBehaviors/SpawnBehavior.cpp @@ -12,7 +12,7 @@ #include "eReplicaComponentType.h" void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* origin = EntityManager::Instance()->GetEntity(context->originator); + auto* origin = Game::entityManager->GetEntity(context->originator); if (origin == nullptr) { Game::logger->Log("SpawnBehavior", "Failed to find self entity (%llu)!", context->originator); @@ -21,7 +21,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea } if (branch.isProjectile) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target != nullptr) { origin = target; @@ -38,10 +38,10 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea info.spawnerNodeID = 0; info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance); - auto* entity = EntityManager::Instance()->CreateEntity( + auto* entity = Game::entityManager->CreateEntity( info, nullptr, - EntityManager::Instance()->GetEntity(context->originator) + Game::entityManager->GetEntity(context->originator) ); if (entity == nullptr) { @@ -59,7 +59,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea rebuildComponent->SetRepositionPlayer(false); } - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); if (branch.duration > 0) { context->RegisterTimerBehavior(this, branch, entity->GetObjectID()); @@ -79,7 +79,7 @@ void SpawnBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt } void SpawnBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, const LWOOBJID second) { - auto* entity = EntityManager::Instance()->GetEntity(second); + auto* entity = Game::entityManager->GetEntity(second); if (entity == nullptr) { Game::logger->Log("SpawnBehavior", "Failed to find spawned entity (%llu)!", second); diff --git a/dGame/dBehaviors/SpeedBehavior.cpp b/dGame/dBehaviors/SpeedBehavior.cpp index d326aa45..5dbad8ec 100644 --- a/dGame/dBehaviors/SpeedBehavior.cpp +++ b/dGame/dBehaviors/SpeedBehavior.cpp @@ -9,14 +9,14 @@ void SpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { if (m_AffectsCaster) branch.target = context->caster; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->AddSpeedboost(m_RunSpeed); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); if (branch.duration > 0.0f) { context->RegisterTimerBehavior(this, branch); @@ -38,14 +38,14 @@ void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch } void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->RemoveSpeedboost(m_RunSpeed); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); } void SpeedBehavior::Load() { diff --git a/dGame/dBehaviors/StunBehavior.cpp b/dGame/dBehaviors/StunBehavior.cpp index 4e34d3a2..8e160338 100644 --- a/dGame/dBehaviors/StunBehavior.cpp +++ b/dGame/dBehaviors/StunBehavior.cpp @@ -21,7 +21,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream return; }; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("StunBehavior", "Failed to find target (%llu)!", branch.target); @@ -44,7 +44,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { if (this->m_stunCaster || branch.target == context->originator) { - auto* self = EntityManager::Instance()->GetEntity(context->originator); + auto* self = Game::entityManager->GetEntity(context->originator); if (self == nullptr) { Game::logger->Log("StunBehavior", "Invalid self entity (%llu)!", context->originator); @@ -69,7 +69,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr bool blocked = false; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target != nullptr) { auto* destroyableComponent = target->GetComponent(); diff --git a/dGame/dBehaviors/SwitchBehavior.cpp b/dGame/dBehaviors/SwitchBehavior.cpp index bd261906..d65191d2 100644 --- a/dGame/dBehaviors/SwitchBehavior.cpp +++ b/dGame/dBehaviors/SwitchBehavior.cpp @@ -16,7 +16,7 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre }; } - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { return; @@ -41,7 +41,7 @@ void SwitchBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS auto state = true; if (this->m_imagination > 0 || !this->m_isEnemyFaction) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); state = entity != nullptr; diff --git a/dGame/dBehaviors/TacArcBehavior.cpp b/dGame/dBehaviors/TacArcBehavior.cpp index 91df3879..b9d871f4 100644 --- a/dGame/dBehaviors/TacArcBehavior.cpp +++ b/dGame/dBehaviors/TacArcBehavior.cpp @@ -76,7 +76,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre } void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* self = EntityManager::Instance()->GetEntity(context->originator); + auto* self = Game::entityManager->GetEntity(context->originator); if (self == nullptr) { Game::logger->Log("TacArcBehavior", "Invalid self for (%llu)!", context->originator); return; @@ -85,7 +85,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS const auto* destroyableComponent = self->GetComponent(); if ((this->m_usePickedTarget || context->clientInitalized) && branch.target > 0) { - const auto* target = EntityManager::Instance()->GetEntity(branch.target); + const auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { return; @@ -120,7 +120,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS // Find all valid targets, based on whether we target enemies or friends for (const auto& contextTarget : context->GetValidTargets()) { if (destroyableComponent != nullptr) { - const auto* targetEntity = EntityManager::Instance()->GetEntity(contextTarget); + const auto* targetEntity = Game::entityManager->GetEntity(contextTarget); if (m_targetEnemy && destroyableComponent->IsEnemy(targetEntity) || m_targetFriend && destroyableComponent->IsFriend(targetEntity)) { @@ -136,7 +136,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS break; } - auto* entity = EntityManager::Instance()->GetEntity(validTarget); + auto* entity = Game::entityManager->GetEntity(validTarget); if (entity == nullptr) { Game::logger->Log("TacArcBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator); diff --git a/dGame/dBehaviors/TauntBehavior.cpp b/dGame/dBehaviors/TauntBehavior.cpp index 7ed3b897..b86cd7b5 100644 --- a/dGame/dBehaviors/TauntBehavior.cpp +++ b/dGame/dBehaviors/TauntBehavior.cpp @@ -7,7 +7,7 @@ void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target); @@ -23,7 +23,7 @@ void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea } void TauntBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/VentureVisionBehavior.cpp b/dGame/dBehaviors/VentureVisionBehavior.cpp index 93feb8e9..397bdebf 100644 --- a/dGame/dBehaviors/VentureVisionBehavior.cpp +++ b/dGame/dBehaviors/VentureVisionBehavior.cpp @@ -5,7 +5,7 @@ void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target); + const auto targetEntity = Game::entityManager->GetEntity(branch.target); if (targetEntity) { auto characterComponent = targetEntity->GetComponent(); @@ -21,7 +21,7 @@ void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* } void VentureVisionBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target); + const auto targetEntity = Game::entityManager->GetEntity(branch.target); if (targetEntity) { auto characterComponent = targetEntity->GetComponent(); diff --git a/dGame/dBehaviors/VerifyBehavior.cpp b/dGame/dBehaviors/VerifyBehavior.cpp index 608e965b..6824a25f 100644 --- a/dGame/dBehaviors/VerifyBehavior.cpp +++ b/dGame/dBehaviors/VerifyBehavior.cpp @@ -8,14 +8,14 @@ void VerifyBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); auto success = true; if (entity == nullptr) { success = false; } else if (this->m_rangeCheck) { - auto* self = EntityManager::Instance()->GetEntity(context->originator); + auto* self = Game::entityManager->GetEntity(context->originator); if (self == nullptr) { Game::logger->Log("VerifyBehavior", "Invalid self for (%llu)", context->originator); diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index cccaad23..77f7a493 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -173,7 +173,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) { } if (m_SoftTimer <= 0.0f) { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); m_SoftTimer = 5.0f; } else { @@ -305,7 +305,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { } if (serilizationRequired) { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 6270, u"tether", "tether"); @@ -412,7 +412,7 @@ LWOOBJID BaseCombatAIComponent::FindTarget() { float biggestThreat = 0; for (const auto& entry : possibleTargets) { - auto* entity = EntityManager::Instance()->GetEntity(entry); + auto* entity = Game::entityManager->GetEntity(entry); if (entity == nullptr) { continue; @@ -458,7 +458,7 @@ LWOOBJID BaseCombatAIComponent::FindTarget() { std::vector deadThreats{}; for (const auto& threatTarget : m_ThreatEntries) { - auto* entity = EntityManager::Instance()->GetEntity(threatTarget.first); + auto* entity = Game::entityManager->GetEntity(threatTarget.first); if (entity == nullptr) { deadThreats.push_back(threatTarget.first); @@ -497,7 +497,7 @@ std::vector BaseCombatAIComponent::GetTargetWithinAggroRange() const { std::vector targets; for (auto id : m_Parent->GetTargetsInPhantom()) { - auto* other = EntityManager::Instance()->GetEntity(id); + auto* other = Game::entityManager->GetEntity(id); const auto distance = Vector3::DistanceSquared(m_Parent->GetPosition(), other->GetPosition()); @@ -535,11 +535,11 @@ void BaseCombatAIComponent::SetAiState(AiState newState) { if (newState == this->m_State) return; this->m_State = newState; m_DirtyStateOrTarget = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } bool BaseCombatAIComponent::IsEnemy(LWOOBJID target) const { - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("BaseCombatAIComponent", "Invalid entity for checking validity (%llu)!", target); @@ -588,11 +588,11 @@ void BaseCombatAIComponent::SetTarget(const LWOOBJID target) { if (this->m_Target == target) return; m_Target = target; m_DirtyStateOrTarget = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } Entity* BaseCombatAIComponent::GetTargetEntity() const { - return EntityManager::Instance()->GetEntity(m_Target); + return Game::entityManager->GetEntity(m_Target); } void BaseCombatAIComponent::Taunt(LWOOBJID offender, float threat) { diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index f6a53261..bbf928dc 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -36,7 +36,7 @@ Entity* BouncerComponent::GetParentEntity() const { void BouncerComponent::SetPetEnabled(bool value) { m_PetEnabled = value; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void BouncerComponent::SetPetBouncerEnabled(bool value) { @@ -44,7 +44,7 @@ void BouncerComponent::SetPetBouncerEnabled(bool value) { GameMessages::SendBouncerActiveStatus(m_Parent->GetObjectID(), value, UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); if (value) { m_Parent->TriggerEvent(eTriggerEventType::PET_ON_SWITCH, m_Parent); @@ -68,7 +68,7 @@ void BouncerComponent::LookupPetSwitch() { const auto& groups = m_Parent->GetGroups(); for (const auto& group : groups) { - const auto& entities = EntityManager::Instance()->GetEntitiesInGroup(group); + const auto& entities = Game::entityManager->GetEntitiesInGroup(group); for (auto* entity : entities) { auto* switchComponent = entity->GetComponent(); @@ -79,7 +79,7 @@ void BouncerComponent::LookupPetSwitch() { m_PetSwitchLoaded = true; m_PetEnabled = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); Game::logger->Log("BouncerComponent", "Loaded pet bouncer"); } diff --git a/dGame/dComponents/BuildBorderComponent.cpp b/dGame/dComponents/BuildBorderComponent.cpp index f9ead9e4..af31f939 100644 --- a/dGame/dComponents/BuildBorderComponent.cpp +++ b/dGame/dComponents/BuildBorderComponent.cpp @@ -17,7 +17,7 @@ BuildBorderComponent::~BuildBorderComponent() { void BuildBorderComponent::OnUse(Entity* originator) { if (originator->GetCharacter()) { - const auto& entities = EntityManager::Instance()->GetEntitiesInGroup("PropertyPlaque"); + const auto& entities = Game::entityManager->GetEntitiesInGroup("PropertyPlaque"); auto buildArea = m_Parent->GetObjectID(); diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index d1b44200..2d5d6209 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -300,7 +300,7 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) { auto candidateRadius = m_ActivePickupRadiusScales[i]; if (m_PickupRadius < candidateRadius) m_PickupRadius = candidateRadius; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ControllablePhysicsComponent::AddSpeedboost(float value) { @@ -327,7 +327,7 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) { m_SpeedBoost = m_ActiveSpeedBoosts.back(); } SetSpeedMultiplier(m_SpeedBoost / 500.0f); // 500 being the base speed - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bool specialAnims){ @@ -339,13 +339,13 @@ void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bo m_IsInBubble = true; m_DirtyBubble = true; m_SpecialAnims = specialAnims; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ControllablePhysicsComponent::DeactivateBubbleBuff(){ m_DirtyBubble = true; m_IsInBubble = false; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); }; void ControllablePhysicsComponent::SetStunImmunity( diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index db8a2013..11b5895a 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -253,7 +253,7 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void DestroyableComponent::SetArmor(int32_t value) { @@ -294,7 +294,7 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void DestroyableComponent::SetImagination(int32_t value) { @@ -333,7 +333,7 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void DestroyableComponent::SetDamageToAbsorb(int32_t value) { @@ -482,11 +482,11 @@ LWOOBJID DestroyableComponent::GetKillerID() const { } Entity* DestroyableComponent::GetKiller() const { - return EntityManager::Instance()->GetEntity(m_KillerID); + return Game::entityManager->GetEntity(m_KillerID); } bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions, const bool targetEnemy, const bool targetFriend) const { - auto* targetEntity = EntityManager::Instance()->GetEntity(target); + auto* targetEntity = Game::entityManager->GetEntity(target); if (targetEntity == nullptr) { Game::logger->Log("DestroyableComponent", "Invalid entity for checking validity (%llu)!", target); @@ -532,7 +532,7 @@ void DestroyableComponent::Heal(const uint32_t health) { SetHealth(current); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -550,7 +550,7 @@ void DestroyableComponent::Imagine(const int32_t deltaImagination) { SetImagination(current); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -564,7 +564,7 @@ void DestroyableComponent::Repair(const uint32_t armor) { SetArmor(current); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -626,7 +626,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 if (possessor) { auto possessableId = possessor->GetPossessable(); if (possessableId != LWOOBJID_EMPTY) { - auto possessable = EntityManager::Instance()->GetEntity(possessableId); + auto possessable = Game::entityManager->GetEntity(possessableId); if (possessable) { possessor->Dismount(possessable); } @@ -638,10 +638,10 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 } if (echo) { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } - auto* attacker = EntityManager::Instance()->GetEntity(source); + auto* attacker = Game::entityManager->GetEntity(source); m_Parent->OnHit(attacker); m_Parent->OnHitOrHealResult(attacker, sourceDamage); NotifySubscribers(attacker, sourceDamage); @@ -661,7 +661,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 } //check if hardcore mode is enabled - if (EntityManager::Instance()->GetHardcoreMode()) { + if (Game::entityManager->GetHardcoreMode()) { DoHardcoreModeDrops(source); } @@ -696,12 +696,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType SetArmor(0); SetHealth(0); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } m_KillerID = source; - auto* owner = EntityManager::Instance()->GetEntity(source); + auto* owner = Game::entityManager->GetEntity(source); if (owner != nullptr) { owner = owner->GetOwner(); // If the owner is overwritten, we collect that here @@ -721,7 +721,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType if (missions != nullptr) { if (team != nullptr) { for (const auto memberId : team->members) { - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr) continue; @@ -761,12 +761,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType if (team->lootOption == 0) { // Round robin specificOwner = TeamManager::Instance()->GetNextLootOwner(team); - auto* member = EntityManager::Instance()->GetEntity(specificOwner); + auto* member = Game::entityManager->GetEntity(specificOwner); if (member) LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); } else { for (const auto memberId : team->members) { // Free for all - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr) continue; @@ -797,12 +797,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } } - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerDied(zoneControl, m_Parent); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -965,7 +965,7 @@ void DestroyableComponent::FixStats() { destroyableComponent->SetImagination(currentImagination); // Serialize the entity - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void DestroyableComponent::AddOnHitCallback(const std::function& callback) { @@ -979,12 +979,12 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ auto* character = m_Parent->GetComponent(); auto uscore = character->GetUScore(); - auto uscoreToLose = uscore * (EntityManager::Instance()->GetHardcoreLoseUscoreOnDeathPercent() / 100); + auto uscoreToLose = uscore * (Game::entityManager->GetHardcoreLoseUscoreOnDeathPercent() / 100); character->SetUScore(uscore - uscoreToLose); GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::MISSION); - if (EntityManager::Instance()->GetHardcoreDropinventoryOnDeath()) { + if (Game::entityManager->GetHardcoreDropinventoryOnDeath()) { //drop all items from inventory: auto* inventory = m_Parent->GetComponent(); if (inventory) { @@ -1001,7 +1001,7 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount()); item.second->SetCount(0, false, false); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } @@ -1021,25 +1021,25 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ // Reload the player since we can't normally reduce uscore from the server and we want the UI to update // do this last so we don't get killed.... again - EntityManager::Instance()->DestructEntity(m_Parent); - EntityManager::Instance()->ConstructEntity(m_Parent); + Game::entityManager->DestructEntity(m_Parent); + Game::entityManager->ConstructEntity(m_Parent); return; } //award the player some u-score: - auto* player = EntityManager::Instance()->GetEntity(source); + auto* player = Game::entityManager->GetEntity(source); if (player && player->IsPlayer()) { auto* playerStats = player->GetComponent(); if (playerStats) { //get the maximum health from this enemy: auto maxHealth = GetMaxHealth(); - int uscore = maxHealth * EntityManager::Instance()->GetHardcoreUscoreEnemiesMultiplier(); + int uscore = maxHealth * Game::entityManager->GetHardcoreUscoreEnemiesMultiplier(); playerStats->SetUScore(playerStats->GetUScore() + uscore); GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::MISSION); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index b0471736..be1edb27 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -826,7 +826,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { if (character != nullptr && !skipChecks) { // Hacky proximity rocket if (item->GetLot() == 6416) { - const auto rocketLauchPads = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::ROCKET_LAUNCH); + const auto rocketLauchPads = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::ROCKET_LAUNCH); const auto position = m_Parent->GetPosition(); @@ -887,7 +887,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { EquipScripts(item); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void InventoryComponent::UnEquipItem(Item* item) { @@ -917,7 +917,7 @@ void InventoryComponent::UnEquipItem(Item* item) { UnequipScripts(item); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Trigger property event if (PropertyManagementComponent::Instance() != nullptr && item->GetCount() > 0 && Inventory::FindInventoryTypeForLot(item->GetLot()) == MODELS) { @@ -968,7 +968,7 @@ void InventoryComponent::HandlePossession(Item* item) { if (possessorComponent->GetIsDismounting()) return; // Check to see if we are already mounting something - auto* currentlyPossessedEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* currentlyPossessedEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); auto currentlyPossessedItem = possessorComponent->GetMountItemID(); if (currentlyPossessedItem) { @@ -991,7 +991,7 @@ void InventoryComponent::HandlePossession(Item* item) { info.rot = startRotation; info.spawnerID = m_Parent->GetObjectID(); - auto* mount = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); + auto* mount = Game::entityManager->CreateEntity(info, nullptr, m_Parent); // Check to see if the mount is a vehicle, if so, flip it auto* vehicleComponent = mount->GetComponent(); @@ -1016,9 +1016,9 @@ void InventoryComponent::HandlePossession(Item* item) { GameMessages::SendSetJetPackMode(m_Parent, false); // Make it go to the client - EntityManager::Instance()->ConstructEntity(mount); + Game::entityManager->ConstructEntity(mount); // Update the possessor - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // have to unlock the input so it vehicle can be driven if (vehicleComponent) GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress()); @@ -1080,7 +1080,7 @@ void InventoryComponent::PopEquippedItems() { destroyableComponent->SetHealth(static_cast(destroyableComponent->GetMaxHealth())); destroyableComponent->SetArmor(static_cast(destroyableComponent->GetMaxArmor())); destroyableComponent->SetImagination(static_cast(destroyableComponent->GetMaxImagination())); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } m_Dirty = true; @@ -1256,7 +1256,7 @@ void InventoryComponent::SpawnPet(Item* item) { info.rot = NiQuaternion::IDENTITY; info.spawnerID = m_Parent->GetObjectID(); - auto* pet = EntityManager::Instance()->CreateEntity(info); + auto* pet = Game::entityManager->CreateEntity(info); auto* petComponent = pet->GetComponent(); @@ -1264,7 +1264,7 @@ void InventoryComponent::SpawnPet(Item* item) { petComponent->Activate(item); } - EntityManager::Instance()->ConstructEntity(pet); + Game::entityManager->ConstructEntity(pet); } void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) { @@ -1373,7 +1373,7 @@ void InventoryComponent::SetNPCItems(const std::vector& items) { UpdateSlot(info.equipLocation, { id, static_cast(item), 1, slot++ }, true); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } InventoryComponent::~InventoryComponent() { diff --git a/dGame/dComponents/LUPExhibitComponent.cpp b/dGame/dComponents/LUPExhibitComponent.cpp index 7b8c85ba..deb3cc8c 100644 --- a/dGame/dComponents/LUPExhibitComponent.cpp +++ b/dGame/dComponents/LUPExhibitComponent.cpp @@ -35,7 +35,7 @@ void LUPExhibitComponent::NextExhibit() { m_Exhibit = m_Exhibits[m_ExhibitIndex]; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void LUPExhibitComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags) { diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 7acec5f7..0743e8f6 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -149,7 +149,7 @@ nextAction: SetVelocity(velocity); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } const MovementAIInfo& MovementAIComponent::GetInfo() const { @@ -221,7 +221,7 @@ bool MovementAIComponent::Warp(const NiPoint3& point) { SetPosition(destination); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return true; } @@ -253,7 +253,7 @@ void MovementAIComponent::Stop() { m_CurrentSpeed = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovementAIComponent::PullToPoint(const NiPoint3& point) { diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 2666c60c..3b3acb72 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -133,7 +133,7 @@ void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) { subComponent->mState = value; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) { @@ -194,7 +194,7 @@ void MovingPlatformComponent::StartPathing() { //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::ContinuePathing() { @@ -242,7 +242,7 @@ void MovingPlatformComponent::ContinuePathing() { subComponent->mCurrentWaypointIndex = pathSize; switch (behavior) { case PathBehavior::Once: - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return; case PathBehavior::Bounce: @@ -304,7 +304,7 @@ void MovingPlatformComponent::ContinuePathing() { ContinuePathing(); }); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::StopPathing() { @@ -318,7 +318,7 @@ void MovingPlatformComponent::StopPathing() { subComponent->mDesiredWaypointIndex = -1; subComponent->mShouldStopAtDesiredWaypoint = false; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); } @@ -341,7 +341,7 @@ void MovingPlatformComponent::WarpToWaypoint(size_t index) { m_Parent->SetPosition(waypoint.position); m_Parent->SetRotation(waypoint.rotation); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } size_t MovingPlatformComponent::GetLastWaypointIndex() const { diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index c37ce6a0..762c4f85 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -154,7 +154,7 @@ void PetComponent::OnUse(Entity* originator) { } if (m_Tamer != LWOOBJID_EMPTY) { - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer != nullptr) { return; @@ -344,7 +344,7 @@ void PetComponent::Update(float deltaTime) { if (m_Timer <= 0) { Wander(); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } else { m_Timer = 5; @@ -369,7 +369,7 @@ void PetComponent::Update(float deltaTime) { } if (m_TresureTime > 0) { - auto* tresure = EntityManager::Instance()->GetEntity(m_Interaction); + auto* tresure = Game::entityManager->GetEntity(m_Interaction); if (tresure == nullptr) { m_TresureTime = 0; @@ -476,7 +476,7 @@ skipTresure: void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -498,7 +498,7 @@ void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) { destroyableComponent->SetImagination(imagination); - EntityManager::Instance()->SerializeEntity(tamer); + Game::entityManager->SerializeEntity(tamer); if (clientFailed) { if (imagination < cached->second.imaginationCost) { @@ -516,7 +516,7 @@ void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) { void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -539,11 +539,11 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { info.rot = NiQuaternion::IDENTITY; info.spawnerID = tamer->GetObjectID(); - auto* modelEntity = EntityManager::Instance()->CreateEntity(info); + auto* modelEntity = Game::entityManager->CreateEntity(info); m_ModelId = modelEntity->GetObjectID(); - EntityManager::Instance()->ConstructEntity(modelEntity); + Game::entityManager->ConstructEntity(modelEntity); GameMessages::SendNotifyTamingModelLoadedOnServer(m_Tamer, tamer->GetSystemAddress()); @@ -639,7 +639,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { return; } - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -661,7 +661,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { //Save our pet's new name to the db: SetPetNameForModeration(GeneralUtils::UTF16ToWTF8(name)); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); std::u16string u16name = GeneralUtils::UTF8ToUTF16(m_Name); std::u16string u16ownerName = GeneralUtils::UTF8ToUTF16(m_OwnerName); @@ -684,7 +684,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { GameMessages::SendTerminateInteraction(m_Tamer, eTerminateType::FROM_INTERACTION, m_Parent->GetObjectID()); - auto* modelEntity = EntityManager::Instance()->GetEntity(m_ModelId); + auto* modelEntity = Game::entityManager->GetEntity(m_ModelId); if (modelEntity != nullptr) { modelEntity->Smash(m_Tamer); @@ -703,7 +703,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -733,7 +733,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Notify the end of a pet taming minigame for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { @@ -754,7 +754,7 @@ void PetComponent::StartTimer() { void PetComponent::ClientFailTamingMinigame() { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -784,7 +784,7 @@ void PetComponent::ClientFailTamingMinigame() { m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Notify the end of a pet taming minigame for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { @@ -887,7 +887,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { m_Timer = 3; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); owner->GetCharacter()->SetPlayerFlag(ePlayerFlag::FIRST_MANUAL_PET_HIBERNATE, true); @@ -1004,7 +1004,7 @@ LWOOBJID PetComponent::GetOwnerId() const { } Entity* PetComponent::GetOwner() const { - return EntityManager::Instance()->GetEntity(m_Owner); + return Game::entityManager->GetEntity(m_Owner); } LWOOBJID PetComponent::GetDatabaseId() const { @@ -1046,7 +1046,7 @@ PetComponent* PetComponent::GetTamingPet(LWOOBJID tamer) { return nullptr; } - auto* entity = EntityManager::Instance()->GetEntity(pair->second); + auto* entity = Game::entityManager->GetEntity(pair->second); if (entity == nullptr) { currentActivities.erase(tamer); @@ -1064,7 +1064,7 @@ PetComponent* PetComponent::GetActivePet(LWOOBJID owner) { return nullptr; } - auto* entity = EntityManager::Instance()->GetEntity(pair->second); + auto* entity = Game::entityManager->GetEntity(pair->second); if (entity == nullptr) { activePets.erase(owner); diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index e6272aa4..640281f8 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -362,7 +362,7 @@ void PhantomPhysicsComponent::Update(float deltaTime) { //If we are a respawn volume, inform the client: if (m_IsRespawnVolume) { - auto entity = EntityManager::Instance()->GetEntity(en->GetObjectID()); + auto entity = Game::entityManager->GetEntity(en->GetObjectID()); if (entity) { GameMessages::SendPlayerReachedRespawnCheckpoint(entity, m_RespawnPos, m_RespawnRot); @@ -403,8 +403,8 @@ void PhantomPhysicsComponent::SpawnVertices() { info.spawnerID = m_Parent->GetObjectID(); info.spawnerNodeID = 0; - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); - EntityManager::Instance()->ConstructEntity(newEntity); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); + Game::entityManager->ConstructEntity(newEntity); } } diff --git a/dGame/dComponents/PossessorComponent.cpp b/dGame/dComponents/PossessorComponent.cpp index 387b3479..8019f91c 100644 --- a/dGame/dComponents/PossessorComponent.cpp +++ b/dGame/dComponents/PossessorComponent.cpp @@ -13,7 +13,7 @@ PossessorComponent::PossessorComponent(Entity* parent) : Component(parent) { PossessorComponent::~PossessorComponent() { if (m_Possessable != LWOOBJID_EMPTY) { - auto* mount = EntityManager::Instance()->GetEntity(m_Possessable); + auto* mount = Game::entityManager->GetEntity(m_Possessable); if (mount) { auto* possessable = mount->GetComponent(); if (possessable) { @@ -58,8 +58,8 @@ void PossessorComponent::Mount(Entity* mount) { GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress()); GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStateChangeType::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); - EntityManager::Instance()->SerializeEntity(m_Parent); - EntityManager::Instance()->SerializeEntity(mount); + Game::entityManager->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(mount); } void PossessorComponent::Dismount(Entity* mount, bool forceDismount) { @@ -73,8 +73,8 @@ void PossessorComponent::Dismount(Entity* mount, bool forceDismount) { possessableComponent->SetPossessor(LWOOBJID_EMPTY); if (forceDismount) possessableComponent->ForceDepossess(); } - EntityManager::Instance()->SerializeEntity(m_Parent); - EntityManager::Instance()->SerializeEntity(mount); + Game::entityManager->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(mount); auto characterComponent = m_Parent->GetComponent(); if (characterComponent) characterComponent->SetIsRacing(false); diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index c87d0744..25d7fb80 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -90,7 +90,7 @@ LWOOBJID PropertyManagementComponent::GetOwnerId() const { } Entity* PropertyManagementComponent::GetOwner() const { - return EntityManager::Instance()->GetEntity(owner); + return Game::entityManager->GetEntity(owner); } void PropertyManagementComponent::SetOwner(Entity* value) { @@ -185,7 +185,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { return false; } - auto* entity = EntityManager::Instance()->GetEntity(playerId); + auto* entity = Game::entityManager->GetEntity(playerId); auto* user = entity->GetParentUser(); @@ -256,7 +256,7 @@ void PropertyManagementComponent::OnStartBuilding() { LWOMAPID zoneId = 1100; - const auto entrance = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE); + const auto entrance = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE); originalPrivacyOption = privacyOption; @@ -339,9 +339,9 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N info.settings.push_back(setting->Copy()); } - Entity* newEntity = EntityManager::Instance()->CreateEntity(info); + Entity* newEntity = Game::entityManager->CreateEntity(info); if (newEntity != nullptr) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); // Make sure the propMgmt doesn't delete our model after the server dies // Trying to do this after the entity is constructed. Shouldn't really change anything but @@ -371,7 +371,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N info.respawnTime = 10; info.emulated = true; - info.emulator = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID(); info.spawnerID = persistentId; GeneralUtils::SetBit(info.spawnerID, eObjectBits::CLIENT); @@ -401,7 +401,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity); }); // Progress place model missions auto missionComponent = entity->GetComponent(); @@ -441,7 +441,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet Game::logger->Log("PropertyManagementComponent", "Failed to find spawner"); } - auto* model = EntityManager::Instance()->GetEntity(id); + auto* model = Game::entityManager->GetEntity(id); if (model == nullptr) { Game::logger->Log("PropertyManagementComponent", "Failed to find model entity"); @@ -449,7 +449,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet return; } - EntityManager::Instance()->DestructEntity(model); + Game::entityManager->DestructEntity(model); Game::logger->Log("PropertyManagementComponent", "Deleting model LOT %i", model->GetLOT()); @@ -520,13 +520,13 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet item->Equip(); GameMessages::SendUGCEquipPostDeleteBasedOnEditMode(entity->GetObjectID(), entity->GetSystemAddress(), item->GetId(), item->GetCount()); - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelPickedUp(entity); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPickedUp(entity); break; } case 1: // Return to inv { - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelRemoved(entity); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRemoved(entity); break; } @@ -613,7 +613,7 @@ void PropertyManagementComponent::Load() { info.respawnTime = 10; //info.emulated = true; - //info.emulator = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + //info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID(); info.spawnerID = id; @@ -698,7 +698,7 @@ void PropertyManagementComponent::Save() { modelIds.push_back(id); - auto* entity = EntityManager::Instance()->GetEntity(pair.first); + auto* entity = Game::entityManager->GetEntity(pair.first); if (entity == nullptr) { continue; diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index c16e99fb..8dd23e53 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -108,7 +108,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, auto* path = dZoneManager::Instance()->GetZone()->GetPath( GeneralUtils::UTF16ToWTF8(m_PathName)); - auto spawnPointEntities = EntityManager::Instance()->GetEntitiesByLOT(4843); + auto spawnPointEntities = Game::entityManager->GetEntitiesByLOT(4843); auto startPosition = NiPoint3::ZERO; auto startRotation = NiQuaternion::IDENTITY; const std::string placementAsString = std::to_string(positionNumber); @@ -135,7 +135,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, info.spawnerID = m_Parent->GetObjectID(); auto* carEntity = - EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); + Game::entityManager->CreateEntity(info, nullptr, m_Parent); // Make the vehicle a child of the racing controller. m_Parent->AddChild(carEntity); @@ -206,9 +206,9 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Construct and serialize everything when done. - EntityManager::Instance()->ConstructEntity(carEntity); - EntityManager::Instance()->SerializeEntity(player); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->ConstructEntity(carEntity); + Game::entityManager->SerializeEntity(player); + Game::entityManager->SerializeEntity(m_Parent); GameMessages::SendRacingSetPlayerResetInfo( m_Parent->GetObjectID(), 0, 0, player->GetObjectID(), startPosition, 1, @@ -219,7 +219,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Reset the player to the start position during downtime, in case something // went wrong. m_Parent->AddCallbackTimer(1, [this, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -268,7 +268,7 @@ void RacingControlComponent::OnRacingClientReady(Entity* player) { racingPlayer.vehicleID, UNASSIGNED_SYSTEM_ADDRESS); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void RacingControlComponent::OnRequestDie(Entity* player) { @@ -281,7 +281,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) { } auto* vehicle = - EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); + Game::entityManager->GetEntity(racingPlayer.vehicleID); if (!vehicle) return; @@ -318,7 +318,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) { auto* destroyableComponent = vehicle->GetComponent(); // Reset imagination to half its current value, rounded up to the nearest value divisible by 10, as it was done in live. if (destroyableComponent) destroyableComponent->SetImagination(respawnImagination); - EntityManager::Instance()->SerializeEntity(vehicle); + Game::entityManager->SerializeEntity(vehicle); }); auto* characterComponent = player->GetComponent(); @@ -347,7 +347,7 @@ void RacingControlComponent::OnRacingPlayerInfoResetFinished(Entity* player) { } auto* vehicle = - EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); + Game::entityManager->GetEntity(racingPlayer.vehicleID); if (vehicle == nullptr) { return; @@ -402,7 +402,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu } } } else if ((id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") && button == m_ActivityExitConfirm) { - auto* vehicle = EntityManager::Instance()->GetEntity(data->vehicleID); + auto* vehicle = Game::entityManager->GetEntity(data->vehicleID); if (vehicle == nullptr) { return; @@ -503,7 +503,7 @@ void RacingControlComponent::Update(float deltaTime) { // Check if any players has disconnected before loading in for (size_t i = 0; i < m_LobbyPlayers.size(); i++) { auto* playerEntity = - EntityManager::Instance()->GetEntity(m_LobbyPlayers[i]); + Game::entityManager->GetEntity(m_LobbyPlayers[i]); if (playerEntity == nullptr) { --m_LoadedPlayers; @@ -525,7 +525,7 @@ void RacingControlComponent::Update(float deltaTime) { if (m_EmptyTimer >= 30) { for (const auto player : m_LobbyPlayers) { auto* playerEntity = - EntityManager::Instance()->GetEntity(player); + Game::entityManager->GetEntity(player); if (playerEntity == nullptr) { continue; @@ -550,7 +550,7 @@ void RacingControlComponent::Update(float deltaTime) { "Loading player now!"); auto* player = - EntityManager::Instance()->GetEntity(m_LobbyPlayers[positionNumber]); + Game::entityManager->GetEntity(m_LobbyPlayers[positionNumber]); if (player == nullptr) { return; @@ -574,7 +574,7 @@ void RacingControlComponent::Update(float deltaTime) { if (!m_Started) { // Check if anyone has disconnected during this period for (size_t i = 0; i < m_RacingPlayers.size(); i++) { - auto* playerEntity = EntityManager::Instance()->GetEntity( + auto* playerEntity = Game::entityManager->GetEntity( m_RacingPlayers[i].playerID); if (playerEntity == nullptr) { @@ -590,7 +590,7 @@ void RacingControlComponent::Update(float deltaTime) { if (m_LoadedPlayers < 2 && !(m_LoadedPlayers == 1 && m_SoloRacing)) { for (const auto player : m_LobbyPlayers) { auto* playerEntity = - EntityManager::Instance()->GetEntity(player); + Game::entityManager->GetEntity(player); if (playerEntity == nullptr) { continue; @@ -623,9 +623,9 @@ void RacingControlComponent::Update(float deltaTime) { for (const auto& player : m_RacingPlayers) { auto* vehicle = - EntityManager::Instance()->GetEntity(player.vehicleID); + Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicle != nullptr && playerEntity != nullptr) { GameMessages::SendTeleport( @@ -643,8 +643,8 @@ void RacingControlComponent::Update(float deltaTime) { destroyableComponent->SetImagination(0); } - EntityManager::Instance()->SerializeEntity(vehicle); - EntityManager::Instance()->SerializeEntity( + Game::entityManager->SerializeEntity(vehicle); + Game::entityManager->SerializeEntity( playerEntity); } } @@ -670,9 +670,9 @@ void RacingControlComponent::Update(float deltaTime) { // Reset players to their start location, without smashing them for (auto& player : m_RacingPlayers) { auto* vehicleEntity = - EntityManager::Instance()->GetEntity(player.vehicleID); + Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicleEntity == nullptr || playerEntity == nullptr) { continue; @@ -689,9 +689,9 @@ void RacingControlComponent::Update(float deltaTime) { // Activate the players movement for (auto& player : m_RacingPlayers) { auto* vehicleEntity = - EntityManager::Instance()->GetEntity(player.vehicleID); + Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicleEntity == nullptr || playerEntity == nullptr) { continue; @@ -709,7 +709,7 @@ void RacingControlComponent::Update(float deltaTime) { Game::logger->Log("RacingControlComponent", "Starting race"); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); m_StartTime = std::time(nullptr); } @@ -727,9 +727,9 @@ void RacingControlComponent::Update(float deltaTime) { GeneralUtils::UTF16ToWTF8(m_PathName)); for (auto& player : m_RacingPlayers) { - auto* vehicle = EntityManager::Instance()->GetEntity(player.vehicleID); + auto* vehicle = Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicle == nullptr || playerEntity == nullptr) { continue; diff --git a/dGame/dComponents/RailActivatorComponent.cpp b/dGame/dComponents/RailActivatorComponent.cpp index 8e13c37f..c7d58999 100644 --- a/dGame/dComponents/RailActivatorComponent.cpp +++ b/dGame/dComponents/RailActivatorComponent.cpp @@ -68,7 +68,7 @@ void RailActivatorComponent::OnUse(Entity* originator) { const auto originatorID = originator->GetObjectID(); m_Parent->AddCallbackTimer(animationLength, [originatorID, this]() { - auto* originator = EntityManager::Instance()->GetEntity(originatorID); + auto* originator = Game::entityManager->GetEntity(originatorID); if (originator == nullptr) { return; diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 39c8fe8d..13854bd6 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -120,7 +120,7 @@ void RebuildComponent::Update(float deltaTime) { else { m_SoftTimer = 5.0f; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); }*/ switch (m_State) { @@ -139,7 +139,7 @@ void RebuildComponent::Update(float deltaTime) { if (m_TimerIncomplete >= m_TimeBeforeSmash - 4.0f) { m_ShowResetEffect = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } if (m_TimerIncomplete >= m_TimeBeforeSmash) { @@ -163,7 +163,7 @@ void RebuildComponent::Update(float deltaTime) { if (!m_ShowResetEffect) { m_ShowResetEffect = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } @@ -206,7 +206,7 @@ void RebuildComponent::Update(float deltaTime) { ++m_DrainedImagination; --newImagination; destComp->SetImagination(newImagination); - EntityManager::Instance()->SerializeEntity(builder); + Game::entityManager->SerializeEntity(builder); } @@ -225,7 +225,7 @@ void RebuildComponent::Update(float deltaTime) { if (m_TimerIncomplete >= m_TimeBeforeSmash - 4.0f) { m_ShowResetEffect = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } if (m_TimerIncomplete >= m_TimeBeforeSmash) { @@ -263,20 +263,20 @@ void RebuildComponent::SpawnActivator() { info.spawnerID = m_Parent->GetObjectID(); info.pos = m_ActivatorPosition == NiPoint3::ZERO ? m_Parent->GetPosition() : m_ActivatorPosition; - m_Activator = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); + m_Activator = Game::entityManager->CreateEntity(info, nullptr, m_Parent); if (m_Activator) { m_ActivatorId = m_Activator->GetObjectID(); - EntityManager::Instance()->ConstructEntity(m_Activator); + Game::entityManager->ConstructEntity(m_Activator); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } void RebuildComponent::DespawnActivator() { if (m_Activator) { - EntityManager::Instance()->DestructEntity(m_Activator); + Game::entityManager->DestructEntity(m_Activator); m_Activator->ScheduleKillAfterUpdate(); @@ -287,7 +287,7 @@ void RebuildComponent::DespawnActivator() { } Entity* RebuildComponent::GetActivator() { - return EntityManager::Instance()->GetEntity(m_ActivatorId); + return Game::entityManager->GetEntity(m_ActivatorId); } NiPoint3 RebuildComponent::GetActivatorPosition() { @@ -335,7 +335,7 @@ eRebuildState RebuildComponent::GetState() { } Entity* RebuildComponent::GetBuilder() const { - auto* builder = EntityManager::Instance()->GetEntity(m_Builder); + auto* builder = Game::entityManager->GetEntity(m_Builder); return builder; } @@ -403,14 +403,14 @@ void RebuildComponent::StartRebuild(Entity* user) { auto* character = user->GetComponent(); character->SetCurrentActivity(eGameActivity::QUICKBUILDING); - EntityManager::Instance()->SerializeEntity(user); + Game::entityManager->SerializeEntity(user); GameMessages::SendRebuildNotifyState(m_Parent, m_State, eRebuildState::BUILDING, user->GetObjectID()); GameMessages::SendEnableRebuild(m_Parent, true, false, false, eQuickBuildFailReason::NOT_GIVEN, 0.0f, user->GetObjectID()); m_State = eRebuildState::BUILDING; m_StateDirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); auto* movingPlatform = m_Parent->GetComponent(); if (movingPlatform != nullptr) { @@ -443,7 +443,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { return; } - EntityManager::Instance()->SerializeEntity(user); + Game::entityManager->SerializeEntity(user); GameMessages::SendRebuildNotifyState(m_Parent, m_State, eRebuildState::COMPLETED, user->GetObjectID()); GameMessages::SendPlayFXEffect(m_Parent, 507, u"create", "BrickFadeUpVisCompleteEffect", LWOOBJID_EMPTY, 0.4f, 1.0f, true); @@ -456,7 +456,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { m_Timer = 0.0f; m_DrainedImagination = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Removes extra item requirements, isn't live accurate. // In live, all items were removed at the start of the quickbuild, then returned if it was cancelled. @@ -476,7 +476,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { auto* team = TeamManager::Instance()->GetTeam(builder->GetObjectID()); if (team) { for (const auto memberId : team->members) { // progress missions for all team members - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member) { auto* missionComponent = member->GetComponent(); if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId); @@ -541,7 +541,7 @@ void RebuildComponent::ResetRebuild(bool failed) { m_ShowResetEffect = false; m_DrainedImagination = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Notify scripts and possible subscribers for (auto* script : CppScripts::GetEntityScripts(m_Parent)) @@ -581,7 +581,7 @@ void RebuildComponent::CancelRebuild(Entity* entity, eQuickBuildFailReason failR for (const auto& cb : m_RebuildStateCallbacks) cb(m_State); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } if (entity == nullptr) { @@ -591,7 +591,7 @@ void RebuildComponent::CancelRebuild(Entity* entity, eQuickBuildFailReason failR CharacterComponent* characterComponent = entity->GetComponent(); if (characterComponent) { characterComponent->SetCurrentActivity(eGameActivity::NONE); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } } diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 3cac9e42..10908d9e 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -81,7 +81,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId, GameMessages::SendChangeObjectWorldState(rocket->GetId(), eObjectWorldState::ATTACHED, UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->SerializeEntity(originator); + Game::entityManager->SerializeEntity(originator); } void RocketLaunchpadControlComponent::OnUse(Entity* originator) { diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 555332f4..2bf788c3 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -137,7 +137,7 @@ void ScriptedActivityComponent::PlayerJoin(Entity* player) { instance->AddParticipant(player); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ScriptedActivityComponent::PlayerJoinLobby(Entity* player) { @@ -445,7 +445,7 @@ void ScriptedActivityComponent::RemoveActivityPlayerData(LWOOBJID playerID) { m_ActivityPlayers[i] = nullptr; m_ActivityPlayers.erase(m_ActivityPlayers.begin() + i); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return; } @@ -458,7 +458,7 @@ ActivityPlayer* ScriptedActivityComponent::AddActivityPlayerData(LWOOBJID player return data; m_ActivityPlayers.push_back(new ActivityPlayer{ playerID, {} }); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return GetActivityPlayerData(playerID); } @@ -480,7 +480,7 @@ void ScriptedActivityComponent::SetActivityValue(LWOOBJID playerID, uint32_t ind data->values[std::min(index, (uint32_t)9)] = value; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ScriptedActivityComponent::PlayerRemove(LWOOBJID playerID) { @@ -535,7 +535,7 @@ void ActivityInstance::StartZone() { const auto objid = player->GetObjectID(); ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, m_ActivityInfo.instanceMapID, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { - auto* player = EntityManager::Instance()->GetEntity(objid); + auto* player = Game::entityManager->GetEntity(objid); if (player == nullptr) return; @@ -585,7 +585,7 @@ std::vector ActivityInstance::GetParticipants() const { entities.reserve(m_Participants.size()); for (const auto& id : m_Participants) { - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity != nullptr) entities.push_back(entity); } @@ -617,5 +617,5 @@ void ActivityInstance::SetScore(uint32_t score) { } Entity* LobbyPlayer::GetEntity() const { - return EntityManager::Instance()->GetEntity(entityID); + return Game::entityManager->GetEntity(entityID); } diff --git a/dGame/dComponents/ShootingGalleryComponent.cpp b/dGame/dComponents/ShootingGalleryComponent.cpp index d5e12b28..ed91ac96 100644 --- a/dGame/dComponents/ShootingGalleryComponent.cpp +++ b/dGame/dComponents/ShootingGalleryComponent.cpp @@ -14,7 +14,7 @@ void ShootingGalleryComponent::SetStaticParams(const StaticShootingGalleryParams void ShootingGalleryComponent::SetDynamicParams(const DynamicShootingGalleryParams& params) { m_DynamicParams = params; m_Dirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate, uint32_t& flags) const { diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index c2f07425..5c1d221a 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -292,7 +292,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c start.optionalOriginatorID = context->originator; start.optionalTargetID = target; - auto* originator = EntityManager::Instance()->GetEntity(context->originator); + auto* originator = Game::entityManager->GetEntity(context->originator); if (originator != nullptr) { start.originatorRot = originator->GetRotation(); @@ -338,7 +338,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) { entry.time += deltaTime; - auto* origin = EntityManager::Instance()->GetEntity(entry.context->originator); + auto* origin = Game::entityManager->GetEntity(entry.context->originator); if (origin == nullptr) { continue; @@ -349,7 +349,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) { const auto position = entry.startPosition + (entry.velocity * entry.time); for (const auto& targetId : targets) { - auto* target = EntityManager::Instance()->GetEntity(targetId); + auto* target = Game::entityManager->GetEntity(targetId); const auto targetPosition = target->GetPosition(); @@ -397,7 +397,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) { void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) const { - auto* other = EntityManager::Instance()->GetEntity(entry.branchContext.target); + auto* other = Game::entityManager->GetEntity(entry.branchContext.target); if (other == nullptr) { if (entry.branchContext.target != LWOOBJID_EMPTY) { diff --git a/dGame/dComponents/SoundTriggerComponent.cpp b/dGame/dComponents/SoundTriggerComponent.cpp index be62beee..21d30948 100644 --- a/dGame/dComponents/SoundTriggerComponent.cpp +++ b/dGame/dComponents/SoundTriggerComponent.cpp @@ -76,7 +76,7 @@ void SoundTriggerComponent::ActivateMusicCue(const std::string& name) { -1.0f }); dirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } @@ -88,6 +88,6 @@ void SoundTriggerComponent::DeactivateMusicCue(const std::string& name) { if (musicCue != this->musicCues.end()) { this->musicCues.erase(musicCue); dirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index b393bbef..eee54342 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -49,7 +49,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { const auto grpName = m_Parent->GetVarAsString(u"grp_name"); if (!grpName.empty()) { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(grpName); + const auto entities = Game::entityManager->GetEntitiesInGroup(grpName); for (auto* entity : entities) { entity->OnFireEventServerSide(entity, "OnActivated"); @@ -63,7 +63,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { RenderComponent::PlayAnimation(m_Parent, u"engaged"); m_PetBouncer->SetPetBouncerEnabled(true); } else { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } @@ -85,7 +85,7 @@ void SwitchComponent::Update(float deltaTime) { const auto grpName = m_Parent->GetVarAsString(u"grp_name"); if (!grpName.empty()) { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(grpName); + const auto entities = Game::entityManager->GetEntitiesInGroup(grpName); for (auto* entity : entities) { entity->OnFireEventServerSide(entity, "OnDectivated"); @@ -95,7 +95,7 @@ void SwitchComponent::Update(float deltaTime) { if (m_PetBouncer != nullptr) { m_PetBouncer->SetPetBouncerEnabled(false); } else { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index 7adf47a8..963bfe8f 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -170,10 +170,10 @@ std::vector TriggerComponent::GatherTargets(LUTriggers::Command* comman else if (command->target == "targetTeam" && optionalTarget) { auto* team = TeamManager::Instance()->GetTeam(optionalTarget->GetObjectID()); for (const auto memberId : team->members) { - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member) entities.push_back(member); } - } else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); + } else if (command->target == "objGroup") entities = Game::entityManager->GetEntitiesInGroup(command->targetName); else if (command->target == "allPlayers") { for (auto* player : Player::GetAllPlayers()) { entities.push_back(player); @@ -249,7 +249,7 @@ void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vectorSetDirection(direction); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -274,7 +274,7 @@ void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args) NiPoint3 direction = delta / length; phantomPhysicsComponent->SetDirection(direction); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void TriggerComponent::HandleSetTimer(Entity* targetEntity, std::vector argArray){ @@ -395,7 +395,7 @@ void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::v phantomPhysicsComponent->SetMax(max); } - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); } void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) { @@ -405,7 +405,7 @@ void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::s return; } phantomPhysicsComponent->SetPhysicsEffectActive(args == "On"); - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); } void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){ diff --git a/dGame/dComponents/VehiclePhysicsComponent.cpp b/dGame/dComponents/VehiclePhysicsComponent.cpp index 58bf7ebb..684b135b 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.cpp +++ b/dGame/dComponents/VehiclePhysicsComponent.cpp @@ -135,7 +135,7 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI void VehiclePhysicsComponent::Update(float deltaTime) { if (m_SoftUpdate > 5) { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); m_SoftUpdate = 0; } else { m_SoftUpdate += deltaTime; diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index be751598..ddb7d6f3 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -42,7 +42,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System CBITSTREAM; // Get the entity - Entity* entity = EntityManager::Instance()->GetEntity(objectID); + Entity* entity = Game::entityManager->GetEntity(objectID); User* usr = UserManager::Instance()->GetUser(sysAddr); @@ -122,9 +122,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System auto* destroyable = entity->GetComponent(); destroyable->SetImagination(destroyable->GetImagination()); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); - std::vector racingControllers = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL); + std::vector racingControllers = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL); for (Entity* racingController : racingControllers) { auto* racingComponent = racingController->GetComponent(); if (racingComponent != nullptr) { @@ -132,12 +132,12 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System } } - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerLoaded(zoneControl, player); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -248,7 +248,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System dest->SetHealth(4); dest->SetArmor(0); dest->SetImagination(6); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); }*/ break; } @@ -560,7 +560,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System break; case eGameMessageType::ZONE_PROPERTY_MODEL_ROTATED: - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity()); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity()); break; case eGameMessageType::UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK: diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 0c3207d6..8f7b96e1 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1101,7 +1101,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, if (object.type != "Powerup") { for (const auto memberId : team->members) { - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr) continue; @@ -1705,11 +1705,11 @@ void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, stringValue.push_back(character); } - auto* assosiate = EntityManager::Instance()->GetEntity(objectID); + auto* assosiate = Game::entityManager->GetEntity(objectID); Game::logger->Log("Activity State Change", "%s [%i, %i] from %i to %i", GeneralUtils::UTF16ToWTF8(stringValue).c_str(), value1, value2, entity->GetLOT(), assosiate != nullptr ? assosiate->GetLOT() : 0); - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY); for (Entity* scriptEntity : scriptedActs) { scriptEntity->OnActivityStateChangeRequest(objectID, value1, value2, stringValue); } @@ -2238,7 +2238,7 @@ void GameMessages::HandleQueryPropertyData(RakNet::BitStream* inStream, Entity* Game::logger->Log("HandleQueryPropertyData", "Entity (%i) requesting data", entity->GetLOT()); /* - auto entites = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_VENDOR); + auto entites = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_VENDOR); entity = entites[0]; */ @@ -2250,7 +2250,7 @@ void GameMessages::HandleQueryPropertyData(RakNet::BitStream* inStream, Entity* } /* - entites = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_MANAGEMENT); + entites = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_MANAGEMENT); entity = entites[0]; */ @@ -2285,7 +2285,7 @@ void GameMessages::HandleSetBuildMode(RakNet::BitStream* inStream, Entity* entit if (inStream->ReadBit()) inStream->Read(startPosition); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (startPosition == NiPoint3::ZERO) { startPosition = player->GetPosition(); @@ -2333,7 +2333,7 @@ void GameMessages::HandleStartBuildingWithItem(RakNet::BitStream* inStream, Enti auto* user = UserManager::Instance()->GetUser(sysAddr); - auto* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + auto* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); SendStartArrangingWithItem( player, @@ -2367,7 +2367,7 @@ void GameMessages::HandlePropertyEditorEnd(RakNet::BitStream* inStream, Entity* void GameMessages::HandlePropertyContentsFromClient(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); SendGetModelsOnProperty(player->GetObjectID(), PropertyManagementComponent::Instance()->GetModels(), UNASSIGNED_SYSTEM_ADDRESS); } @@ -2730,9 +2730,9 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent info.settings.push_back(propertyObjectID); info.settings.push_back(userModelID); - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); //Make sure the propMgmt doesn't delete our model after the server dies //Trying to do this after the entity is constructed. Shouldn't really change anything but @@ -2928,7 +2928,7 @@ void GameMessages::HandleCinematicUpdate(RakNet::BitStream* inStream, Entity* en inStream->Read(waypoint); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); for (Entity* scriptEntity : scriptedActs) { scriptEntity->OnCinematicUpdate(scriptEntity, entity, event, pathName, pathTime, overallTime, waypoint); } @@ -3308,7 +3308,7 @@ void GameMessages::HandleClientTradeRequest(RakNet::BitStream* inStream, Entity* inStream->Read(i64Invitee); - auto* invitee = EntityManager::Instance()->GetEntity(i64Invitee); + auto* invitee = Game::entityManager->GetEntity(i64Invitee); if (invitee != nullptr && invitee->IsPlayer()) { character = invitee->GetCharacter(); @@ -3895,7 +3895,7 @@ void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* racingControlComponent->HandleMessageBoxResponse(userEntity, iButton, GeneralUtils::UTF16ToWTF8(identifier)); } - for (auto* shootingGallery : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { + for (auto* shootingGallery : Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { shootingGallery->OnMessageBoxResponse(userEntity, iButton, identifier, userData); } } @@ -4056,7 +4056,7 @@ void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* e // If we aren't possessing somethings, the don't do anything if (objectId != LWOOBJID_EMPTY) { auto* possessorComponent = entity->GetComponent(); - auto* mount = EntityManager::Instance()->GetEntity(objectId); + auto* mount = Game::entityManager->GetEntity(objectId); // make sure we have the things we need and they aren't null if (possessorComponent && mount) { if (!possessorComponent->GetIsDismounting()) return; @@ -4081,7 +4081,7 @@ void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* e if (possessableComponent) possessableComponent->Dismount(); // Update the entity that was possessing - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); // We aren't mounted so remove the stun GameMessages::SendSetStunned(entity->GetObjectID(), eStateChangeType::POP, UNASSIGNED_SYSTEM_ADDRESS, LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); @@ -4091,11 +4091,11 @@ void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* e void GameMessages::HandleAcknowledgePossession(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); LWOOBJID objectId{}; inStream->Read(objectId); - auto* mount = EntityManager::Instance()->GetEntity(objectId); - if (mount) EntityManager::Instance()->SerializeEntity(mount); + auto* mount = Game::entityManager->GetEntity(objectId); + if (mount) Game::entityManager->SerializeEntity(mount); } //Racing @@ -4131,7 +4131,7 @@ void GameMessages::HandleRacingClientReady(RakNet::BitStream* inStream, Entity* inStream->Read(playerID); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -4195,7 +4195,7 @@ void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, auto* possessableComponent = entity->GetComponent(); if (possessableComponent != nullptr) { - entity = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + entity = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (entity == nullptr) { return; @@ -4222,7 +4222,7 @@ void GameMessages::HandleRacingPlayerInfoResetFinished(RakNet::BitStream* inStre inStream->Read(playerID); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -4286,7 +4286,7 @@ void GameMessages::HandleVehicleNotifyHitImaginationServer(RakNet::BitStream* in if (inStream->ReadBit()) inStream->Read(pickupSpawnerIndex); if (inStream->ReadBit()) inStream->Read(vehiclePosition); - auto* pickup = EntityManager::Instance()->GetEntity(pickupObjID); + auto* pickup = Game::entityManager->GetEntity(pickupObjID); if (pickup == nullptr) { return; @@ -4295,7 +4295,7 @@ void GameMessages::HandleVehicleNotifyHitImaginationServer(RakNet::BitStream* in auto* possessableComponent = entity->GetComponent(); if (possessableComponent != nullptr) { - entity = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + entity = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (entity == nullptr) { return; @@ -4686,7 +4686,7 @@ void GameMessages::HandleToggleGhostReferenceOverride(RakNet::BitStream* inStrea if (player != nullptr) { player->SetGhostOverride(bOverride); - EntityManager::Instance()->UpdateGhosting(player); + Game::entityManager->UpdateGhosting(player); } } @@ -4701,7 +4701,7 @@ void GameMessages::HandleSetGhostReferencePosition(RakNet::BitStream* inStream, if (player != nullptr) { player->SetGhostOverridePoint(position); - EntityManager::Instance()->UpdateGhosting(player); + Game::entityManager->UpdateGhosting(player); } } @@ -4719,7 +4719,7 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!player) return; auto* propertyVendorComponent = static_cast(entity->GetComponent(eReplicaComponentType::PROPERTY_VENDOR)); @@ -4822,7 +4822,7 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!player) return; Character* character = player->GetCharacter(); if (!character) return; @@ -4853,7 +4853,7 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit //inv->RemoveItem(count, -1, iObjID); inv->MoveItemToInventory(item, eInventoryType::VENDOR_BUYBACK, count, true, false, true); character->SetCoins(std::floor(character->GetCoins() + (static_cast(itemComp.baseValue * sellScalar) * count)), eLootSourceType::VENDOR); - //EntityManager::Instance()->SerializeEntity(player); // so inventory updates + //Game::entityManager->SerializeEntity(player); // so inventory updates GameMessages::SendVendorTransactionResult(entity, sysAddr); } @@ -4872,7 +4872,7 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!player) return; Character* character = player->GetCharacter(); if (!character) return; @@ -4912,7 +4912,7 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* //inv->RemoveItem(count, -1, iObjID); inv->MoveItemToInventory(item, Inventory::FindInventoryTypeForLot(item->GetLot()), count, true, false); character->SetCoins(character->GetCoins() - cost, eLootSourceType::VENDOR); - //EntityManager::Instance()->SerializeEntity(player); // so inventory updates + //Game::entityManager->SerializeEntity(player); // so inventory updates GameMessages::SendVendorTransactionResult(entity, sysAddr); } @@ -4959,7 +4959,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity if (param3IsDefault) inStream->Read(param3); inStream->Read(senderID); - auto* sender = EntityManager::Instance()->GetEntity(senderID); + auto* sender = Game::entityManager->GetEntity(senderID); auto* player = Player::GetPlayer(sysAddr); if (!player) { @@ -5033,7 +5033,7 @@ void GameMessages::HandleRebuildCancel(RakNet::BitStream* inStream, Entity* enti RebuildComponent* rebComp = static_cast(entity->GetComponent(eReplicaComponentType::QUICK_BUILD)); if (!rebComp) return; - rebComp->CancelRebuild(EntityManager::Instance()->GetEntity(userID), eQuickBuildFailReason::CANCELED_EARLY); + rebComp->CancelRebuild(Game::entityManager->GetEntity(userID), eQuickBuildFailReason::CANCELED_EARLY); } void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -5049,7 +5049,7 @@ void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, inStream->Read(objectID); inStream->Read(secondary); - Entity* interactedObject = EntityManager::Instance()->GetEntity(objectID); + Entity* interactedObject = Game::entityManager->GetEntity(objectID); if (interactedObject == nullptr) { Game::logger->Log("GameMessages", "Object %llu tried to interact, but doesn't exist!", objectID); @@ -5102,7 +5102,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (!missionComponent) return; if (targetID != LWOOBJID_EMPTY) { - auto* targetEntity = EntityManager::Instance()->GetEntity(targetID); + auto* targetEntity = Game::entityManager->GetEntity(targetID); Game::logger->LogDebug("GameMessages", "Emote target found (%d)", targetEntity != nullptr); @@ -5112,7 +5112,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) } } else { Game::logger->LogDebug("GameMessages", "Target ID is empty, using backup"); - const auto scriptedEntities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + const auto scriptedEntities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); const auto& referencePoint = entity->GetPosition(); @@ -5140,7 +5140,7 @@ void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream* inStream, E User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; InventoryComponent* inv = static_cast(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; @@ -5198,7 +5198,7 @@ void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* e Game::logger->Log("GameMessages", "Unable to get mission %i for entity %llu to update reward in RespondToMission", missionID, playerID); } - Entity* offerer = EntityManager::Instance()->GetEntity(receiverID); + Entity* offerer = Game::entityManager->GetEntity(receiverID); if (offerer == nullptr) { Game::logger->Log("GameMessages", "Unable to get receiver entity %llu for RespondToMission", receiverID); @@ -5206,7 +5206,7 @@ void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* e } for (CppScripts::Script* script : CppScripts::GetEntityScripts(offerer)) { - script->OnRespondToMission(offerer, missionID, EntityManager::Instance()->GetEntity(playerID), reward); + script->OnRespondToMission(offerer, missionID, Game::entityManager->GetEntity(playerID), reward); } } @@ -5221,7 +5221,7 @@ void GameMessages::HandleMissionDialogOK(RakNet::BitStream* inStream, Entity* en inStream->Read(iMissionState); inStream->Read(missionID); inStream->Read(responder); - player = EntityManager::Instance()->GetEntity(responder); + player = Game::entityManager->GetEntity(responder); for (CppScripts::Script* script : CppScripts::GetEntityScripts(entity)) { script->OnMissionDialogueOK(entity, player, missionID, iMissionState); @@ -5250,7 +5250,7 @@ void GameMessages::HandleRequestLinkedMission(RakNet::BitStream* inStream, Entit inStream->Read(missionId); inStream->Read(bMissionOffered); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); auto* missionOfferComponent = static_cast(entity->GetComponent(eReplicaComponentType::MISSION_OFFER)); @@ -5263,7 +5263,7 @@ void GameMessages::HandleHasBeenCollected(RakNet::BitStream* inStream, Entity* e LWOOBJID playerID; inStream->Read(playerID); - Entity* player = EntityManager::Instance()->GetEntity(playerID); + Entity* player = Game::entityManager->GetEntity(playerID); if (!player || !entity || entity->GetCollectibleID() == 0) return; MissionComponent* missionComponent = static_cast(player->GetComponent(eReplicaComponentType::MISSION)); @@ -5377,7 +5377,7 @@ void GameMessages::HandleEquipItem(RakNet::BitStream* inStream, Entity* entity) item->Equip(); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleUnequipItem(RakNet::BitStream* inStream, Entity* entity) { @@ -5397,7 +5397,7 @@ void GameMessages::HandleUnequipItem(RakNet::BitStream* inStream, Entity* entity item->UnEquip(); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -5482,7 +5482,7 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, En } item->SetCount(item->GetCount() - iStackCount, true); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); auto* missionComponent = entity->GetComponent(); @@ -5516,7 +5516,7 @@ void GameMessages::HandleMoveItemInInventory(RakNet::BitStream* inStream, Entity } inv->MoveStack(item, static_cast(destInvType), slot); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleMoveItemBetweenInventoryTypes(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -5562,7 +5562,7 @@ void GameMessages::HandleMoveItemBetweenInventoryTypes(RakNet::BitStream* inStre } inv->MoveItemToInventory(item, inventoryTypeB, stackCount, showFlyingLoot); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleBuildModeSet(RakNet::BitStream* inStream, Entity* entity) { @@ -5581,7 +5581,7 @@ void GameMessages::HandleBuildModeSet(RakNet::BitStream* inStream, Entity* entit void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; InventoryComponent* inv = static_cast(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; @@ -5592,7 +5592,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* GameMessages::SendModularBuildEnd(character); // i dont know if this does anything but DLUv2 did it //inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap - //EntityManager::Instance()->SerializeEntity(entity); + //Game::entityManager->SerializeEntity(entity); uint8_t count; // 3 for rockets, 7 for cars @@ -5669,7 +5669,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; InventoryComponent* inv = static_cast(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; @@ -5722,9 +5722,9 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti */ if (PropertyManagementComponent::Instance() != nullptr) { - const auto& buildAreas = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::BUILD_BORDER); + const auto& buildAreas = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::BUILD_BORDER); - const auto& entities = EntityManager::Instance()->GetEntitiesInGroup("PropertyPlaque"); + const auto& entities = Game::entityManager->GetEntitiesInGroup("PropertyPlaque"); Entity* buildArea; @@ -5780,7 +5780,7 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti void GameMessages::HandleModularBuildMoveAndEquip(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; Game::logger->Log("GameMessages", "Build and move"); @@ -5813,7 +5813,7 @@ void GameMessages::HandlePickupItem(RakNet::BitStream* inStream, Entity* entity) if (team != nullptr) { for (const auto memberId : team->members) { - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr || memberId == playerID) continue; @@ -5825,12 +5825,12 @@ void GameMessages::HandlePickupItem(RakNet::BitStream* inStream, Entity* entity) void GameMessages::HandleResurrect(RakNet::BitStream* inStream, Entity* entity) { bool immediate = inStream->ReadBit(); - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerResurrected(zoneControl, entity); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -5850,7 +5850,7 @@ void GameMessages::HandlePopEquippedItemsState(RakNet::BitStream* inStream, Enti InventoryComponent* inv = static_cast(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; inv->PopEquippedItems(); - EntityManager::Instance()->SerializeEntity(entity); // so it updates on client side + Game::entityManager->SerializeEntity(entity); // so it updates on client side } @@ -5916,7 +5916,7 @@ void GameMessages::HandleMatchRequest(RakNet::BitStream* inStream, Entity* entit inStream->Read(type); inStream->Read(value); - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); if (type == 0) { // join if (value != 0) { for (Entity* scriptedAct : scriptedActs) { @@ -6049,7 +6049,7 @@ void GameMessages::HandleReportBug(RakNet::BitStream* inStream, Entity* entity) void GameMessages::HandleClientRailMovementReady(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); + const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (const auto* possibleRail : possibleRails) { const auto* rail = possibleRail->GetComponent(); if (rail != nullptr) { @@ -6061,7 +6061,7 @@ GameMessages::HandleClientRailMovementReady(RakNet::BitStream* inStream, Entity* void GameMessages::HandleCancelRailMovement(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { const auto immediate = inStream->ReadBit(); - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); + const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (const auto* possibleRail : possibleRails) { auto* rail = possibleRail->GetComponent(); if (rail != nullptr) { @@ -6085,7 +6085,7 @@ void GameMessages::HandlePlayerRailArrivedNotification(RakNet::BitStream* inStre int32_t waypointNumber; inStream->Read(waypointNumber); - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); + const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (auto* possibleRail : possibleRails) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(possibleRail)) { script->OnPlayerRailArrived(possibleRail, entity, pathName, waypointNumber); @@ -6178,7 +6178,7 @@ void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const S void GameMessages::HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity) { LWOOBJID player_id; inStream->Read(player_id); - auto target = EntityManager::Instance()->GetEntity(player_id); + auto target = Game::entityManager->GetEntity(player_id); entity->TriggerEvent(eTriggerEventType::ZONE_SUMMARY_DISMISSED, target); }; @@ -6218,7 +6218,7 @@ void GameMessages::HandleRequestActivityExit(RakNet::BitStream* inStream, Entity LWOOBJID player_id = LWOOBJID_EMPTY; inStream->Read(player_id); - auto player = EntityManager::Instance()->GetEntity(player_id); + auto player = Game::entityManager->GetEntity(player_id); if (!entity || !player) return; entity->RequestActivityExit(entity, player_id, canceled); } diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 83ac8869..64f1dfbd 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -100,7 +100,7 @@ Item::Item( Game::logger->Log("Item", "Move and equipped (%i) from (%i)", this->lot, this->inventory->GetType()); - EntityManager::Instance()->SerializeEntity(inventory->GetComponent()->GetParent()); + Game::entityManager->SerializeEntity(inventory->GetComponent()->GetParent()); } } diff --git a/dGame/dInventory/ItemSetPassiveAbility.cpp b/dGame/dInventory/ItemSetPassiveAbility.cpp index bf7c19cb..3030904d 100644 --- a/dGame/dInventory/ItemSetPassiveAbility.cpp +++ b/dGame/dInventory/ItemSetPassiveAbility.cpp @@ -44,7 +44,7 @@ void ItemSetPassiveAbility::Activate(Entity* target) { return; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); const auto id = static_cast(m_ItemSet->GetID()); const auto parentID = m_Parent->GetObjectID(); @@ -203,7 +203,7 @@ void ItemSetPassiveAbility::OnEnemySmshed(Entity* target) { return; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); const auto id = static_cast(m_ItemSet->GetID()); const auto parentID = m_Parent->GetObjectID(); diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 32a930e4..bd5c67e9 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -547,7 +547,7 @@ void Mission::YieldRewards() { destroyableComponent->SetMaxImagination(destroyableComponent->GetMaxImagination() + static_cast(info->reward_maximagination), true); } - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); if (info->reward_emote > 0) { character->UnlockEmote(info->reward_emote); diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index 344427c6..95e97a53 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -230,7 +230,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - entity = EntityManager::Instance()->GetEntity(associate); + entity = Game::entityManager->GetEntity(associate); if (entity == nullptr) { if (associate != LWOOBJID_EMPTY) { Game::logger->Log("MissionTask", "Failed to find associated entity (%llu)!", associate); @@ -272,7 +272,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& { if (!InParameters(value)) break; - entity = EntityManager::Instance()->GetEntity(associate); + entity = Game::entityManager->GetEntity(associate); if (entity == nullptr) { Game::logger->Log("MissionTask", "Failed to find associated entity (%llu)!", associate); @@ -302,7 +302,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& case eMissionTaskType::PERFORM_ACTIVITY: { - auto* minigameManager = EntityManager::Instance()->GetEntity(associate); + auto* minigameManager = Game::entityManager->GetEntity(associate); if (minigameManager == nullptr) break; @@ -346,7 +346,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& { if (!InAllTargets(value)) break; - entity = EntityManager::Instance()->GetEntity(associate); + entity = Game::entityManager->GetEntity(associate); if (entity == nullptr) { Game::logger->Log("MissionTask", "Failed to find associated entity (%llu)!", associate); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 47e0f0e4..e0a69e02 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -184,7 +184,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()) << "!"; @@ -289,7 +289,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit 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; @@ -372,7 +372,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(); std::string lowerName = args[0]; if (lowerName.empty()) return; @@ -399,12 +399,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 @@ -415,13 +415,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit RenderComponent::PlayAnimation(entity, anim); auto* possessorComponent = entity->GetComponent(); 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)); } @@ -450,7 +450,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; @@ -478,7 +478,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(); if (possessControllablePhysicsComponent) { @@ -488,7 +488,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } if (chatCommand == "freecam" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { @@ -937,13 +937,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto* possessorComponent = entity->GetComponent(); if (possessorComponent) { - auto* possassableEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* possassableEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (possassableEntity != nullptr) { auto* vehiclePhysicsComponent = possassableEntity->GetComponent(); if (vehiclePhysicsComponent) { vehiclePhysicsComponent->SetPosition(pos); - EntityManager::Instance()->SerializeEntity(possassableEntity); + Game::entityManager->SerializeEntity(possassableEntity); } else GameMessages::SendTeleport(possassableEntity->GetObjectID(), pos, NiQuaternion(), sysAddr); } } @@ -952,7 +952,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()); @@ -966,7 +966,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); } } @@ -1180,7 +1180,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) { @@ -1204,7 +1204,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) { @@ -1216,7 +1216,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) { @@ -1260,14 +1260,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; } - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); } if (chatCommand == "spawngroup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { @@ -1310,13 +1310,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--; } } @@ -1545,7 +1545,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit 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(); @@ -1609,7 +1609,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; @@ -1638,7 +1638,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto* possessorComponent = entity->GetComponent(); 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); @@ -1660,7 +1660,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(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (phys) @@ -1669,7 +1669,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(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR)); if (phys) { @@ -1765,7 +1765,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(); if (!scriptedActivityComponent) continue; @@ -1862,7 +1862,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) { @@ -1894,7 +1894,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - EntityManager::Instance()->SerializeEntity(closest); + Game::entityManager->SerializeEntity(closest); auto* table = CDClientManager::Instance().GetTable(); @@ -1934,7 +1934,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") { diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 703f7d30..86fa9503 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -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(u"hasCustomText", true), new LDFData(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,10 +155,10 @@ 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); auto* inventoryComponent = entity->GetComponent(); @@ -175,7 +175,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 +535,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(15, 60); diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 313be6b0..8bebda93 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -82,7 +82,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac CINSTREAM_SKIP_HEADER; - Entity* entity = EntityManager::Instance()->GetEntity(user->GetLastUsedChar()->GetObjectID()); + Entity* entity = Game::entityManager->GetEntity(user->GetLastUsedChar()->GetObjectID()); if (!entity) return; ControllablePhysicsComponent* comp = static_cast(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); @@ -95,7 +95,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac comp->SetVelocity(zeroVel); comp->SetAngularVelocity(zeroVel); comp->SetIsOnGround(true); //probably8 - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); return; } */ @@ -166,7 +166,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac bool updateChar = true; if (possessorComponent != nullptr) { - auto* possassableEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* possassableEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (possassableEntity != nullptr) { auto* possessableComponent = possassableEntity->GetComponent(); @@ -199,7 +199,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac controllablePhysicsComponent->SetAngularVelocity(angVelocity); controllablePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag); } - EntityManager::Instance()->SerializeEntity(possassableEntity); + Game::entityManager->SerializeEntity(possassableEntity); } } @@ -227,9 +227,9 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac auto* player = static_cast(entity); player->SetGhostReferencePoint(position); - EntityManager::Instance()->QueueGhostUpdate(player->GetObjectID()); + Game::entityManager->QueueGhostUpdate(player->GetObjectID()); - if (updateChar) EntityManager::Instance()->SerializeEntity(entity); + if (updateChar) Game::entityManager->SerializeEntity(entity); //TODO: add moving platform stuffs /*bool movingPlatformFlag; @@ -267,7 +267,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac continue; } - EntityManager::Instance()->SerializeEntity(entity, player); + Game::entityManager->SerializeEntity(entity, player); } */ } diff --git a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp index a51af03a..ada8223a 100644 --- a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp @@ -61,13 +61,13 @@ void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { } // There is suppose to be a 0.1 second delay here but that may be admitted? - auto* controller = EntityManager::Instance()->GetZoneControlEntity(); + auto* controller = Game::entityManager->GetZoneControlEntity(); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SetColGroup", 10, 0, 0, "", UNASSIGNED_SYSTEM_ADDRESS); self->SetPosition({ 10000, 0, 10000 }); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); controller->OnFireEventServerSide(self, "ClearProperty"); } @@ -97,7 +97,7 @@ void BossSpiderQueenEnemyServer::WithdrawSpider(Entity* self, const bool withdra rot = controllable->GetRotation(); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); auto* baseCombatAi = self->GetComponent(); @@ -113,7 +113,7 @@ void BossSpiderQueenEnemyServer::WithdrawSpider(Entity* self, const bool withdra //TODO: Set faction to -1 and set immunity destroyable->SetFaction(-1); destroyable->SetIsImmune(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); self->AddTimer("WithdrawComplete", withdrawTime + 1.0f); waitForIdle = true; @@ -146,7 +146,7 @@ void BossSpiderQueenEnemyServer::WithdrawSpider(Entity* self, const bool withdra //Reset the current wave death counter m_DeathCounter = 0; - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); // Prepare a timer for post leap attack self->AddTimer("AdvanceAttack", attackPause); @@ -179,7 +179,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { std::vector spiderEggs{}; - auto spooders = EntityManager::Instance()->GetEntitiesInGroup("EGG"); + auto spooders = Game::entityManager->GetEntitiesInGroup("EGG"); for (auto spodder : spooders) { spiderEggs.push_back(spodder->GetObjectID()); } @@ -201,7 +201,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { } if (randomEgg) { - auto* eggEntity = EntityManager::Instance()->GetEntity(randomEgg); + auto* eggEntity = Game::entityManager->GetEntity(randomEgg); if (eggEntity == nullptr) { continue; @@ -234,7 +234,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { // We have successfully readied a full wave // initiate hatching! for (auto egg : hatchList) { - auto* eggEntity = EntityManager::Instance()->GetEntity(egg); + auto* eggEntity = Game::entityManager->GetEntity(egg); if (eggEntity == nullptr) { continue; @@ -304,7 +304,7 @@ void BossSpiderQueenEnemyServer::RunRainOfFire(Entity* self) { void BossSpiderQueenEnemyServer::RainOfFireManager(Entity* self) { if (!impactList.empty()) { - auto* entity = EntityManager::Instance()->GetEntity(impactList[0]); + auto* entity = Game::entityManager->GetEntity(impactList[0]); impactList.erase(impactList.begin()); @@ -408,7 +408,7 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim controllable->SetStatic(false); controllable->SetRotation(rot); controllable->SetStatic(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); //Play the Spider Boss' mountain idle anim auto time = PlayAnimAndReturnTime(self, spiderWithdrawIdle); @@ -419,7 +419,7 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim rot = controllable->GetRotation(); //If there are still baby spiders, don't do anyhting either - const auto spiders = EntityManager::Instance()->GetEntitiesInGroup("BabySpider"); + const auto spiders = Game::entityManager->GetEntitiesInGroup("BabySpider"); if (spiders.size() > 0) self->AddTimer("checkForSpiders", time); else @@ -491,7 +491,7 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim }*/ auto landingTarget = self->GetI64(u"LandingTarget"); - auto landingEntity = EntityManager::Instance()->GetEntity(landingTarget); + auto landingEntity = Game::entityManager->GetEntity(landingTarget); auto* skillComponent = self->GetComponent(); @@ -547,10 +547,10 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim destroyable->SetIsImmune(false); destroyable->SetFaction(4); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else if (timerName == "Clear") { - EntityManager::Instance()->FireEventServerSide(self, "ClearProperty"); + Game::entityManager->FireEventServerSide(self, "ClearProperty"); self->CancelAllTimers(); } else if (timerName == "UnlockSpecials") { //We no longer need to lock specials @@ -605,7 +605,7 @@ void BossSpiderQueenEnemyServer::OnUpdate(Entity* self) { controllable->SetRotation(NiQuaternion::IDENTITY); controllable->SetStatic(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } //---------------------------------------------- diff --git a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp index ff30f8e8..9895395c 100644 --- a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp +++ b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp @@ -28,7 +28,7 @@ void AmDarklingDragon::OnDie(Entity* self, Entity* killer) { auto golemId = self->GetVar(u"Golem"); - auto* golem = EntityManager::Instance()->GetEntity(golemId); + auto* golem = Game::entityManager->GetEntity(golemId); if (golem != nullptr) { golem->Smash(self->GetObjectID()); @@ -109,9 +109,9 @@ void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t new LDFData(u"Dragon", self->GetObjectID()) }; - auto* golemObject = EntityManager::Instance()->CreateEntity(info); + auto* golemObject = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(golemObject); + Game::entityManager->ConstructEntity(golemObject); } } } diff --git a/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp b/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp index 9214667e..84eb70e7 100644 --- a/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp +++ b/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp @@ -3,7 +3,7 @@ void FvMaelstromCavalry::OnStartup(Entity* self) { for (const auto& group : self->GetGroups()) { - const auto& objects = EntityManager::Instance()->GetEntitiesInGroup(group); + const auto& objects = Game::entityManager->GetEntitiesInGroup(group); for (auto* obj : objects) { if (obj->GetLOT() != 8551) continue; @@ -22,7 +22,7 @@ void FvMaelstromCavalry::OnDie(Entity* self, Entity* killer) { return; } - const auto& triggers = EntityManager::Instance()->GetEntitiesInGroup("HorsemenTrigger"); + const auto& triggers = Game::entityManager->GetEntitiesInGroup("HorsemenTrigger"); for (auto* trigger : triggers) { trigger->OnFireEventServerSide(self, "HorsemenDeath"); diff --git a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp index 664d8b67..ff7e7a51 100644 --- a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp +++ b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp @@ -35,13 +35,13 @@ void FvMaelstromDragon::OnDie(Entity* self, Entity* killer) { info.rot = rotation; info.spawnerID = self->GetObjectID(); - auto* chest = EntityManager::Instance()->CreateEntity(info); + auto* chest = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(chest); + Game::entityManager->ConstructEntity(chest); auto golemId = self->GetVar(u"Golem"); - auto* golem = EntityManager::Instance()->GetEntity(golemId); + auto* golem = Game::entityManager->GetEntity(golemId); if (golem != nullptr) { golem->Smash(self->GetObjectID()); @@ -125,9 +125,9 @@ void FvMaelstromDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_ new LDFData(u"Dragon", self->GetObjectID()) }; - auto* golemObject = EntityManager::Instance()->CreateEntity(info); + auto* golemObject = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(golemObject); + Game::entityManager->ConstructEntity(golemObject); } } } diff --git a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp index 19a6490a..07221248 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp @@ -15,7 +15,7 @@ void BaseEnemyApe::OnStartup(Entity* self) { } void BaseEnemyApe::OnDie(Entity* self, Entity* killer) { - auto* anchor = EntityManager::Instance()->GetEntity(self->GetVar(u"QB")); + auto* anchor = Game::entityManager->GetEntity(self->GetVar(u"QB")); if (anchor != nullptr && !anchor->GetIsDead()) { anchor->Smash(self->GetObjectID(), eKillType::SILENT); } @@ -56,7 +56,7 @@ void BaseEnemyApe::OnTimerDone(Entity* self, std::string timerName) { if (destroyableComponent != nullptr) { destroyableComponent->SetArmor(destroyableComponent->GetMaxArmor() / timesStunned); } - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_COMBAT, eAnimationFlags::IDLE_NONE, UNASSIGNED_SYSTEM_ADDRESS); self->SetVar(u"timesStunned", timesStunned + 1); StunApe(self, false); @@ -92,14 +92,14 @@ void BaseEnemyApe::OnTimerDone(Entity* self, std::string timerName) { new LDFData(u"ape", self->GetObjectID()) }; - auto* anchor = EntityManager::Instance()->CreateEntity(entityInfo); - EntityManager::Instance()->ConstructEntity(anchor); + auto* anchor = Game::entityManager->CreateEntity(entityInfo); + Game::entityManager->ConstructEntity(anchor); self->SetVar(u"QB", anchor->GetObjectID()); } else if (timerName == "anchorDamageTimer") { // Attacks the ape with some god skill - const auto* player = EntityManager::Instance()->GetEntity(self->GetVar(u"smasher")); + const auto* player = Game::entityManager->GetEntity(self->GetVar(u"smasher")); if (player == nullptr) { return; } diff --git a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp index ce42585c..c652dab0 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp @@ -38,8 +38,8 @@ void BaseEnemyMech::OnDie(Entity* self, Entity* killer) { info.spawnerID = self->GetObjectID(); info.settings = cfg; - Entity* turret = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* turret = Game::entityManager->CreateEntity(info, nullptr); if (turret) { - EntityManager::Instance()->ConstructEntity(turret); + Game::entityManager->ConstructEntity(turret); } } diff --git a/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp b/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp index 40cc88f4..aa4a56a7 100644 --- a/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp +++ b/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp @@ -15,7 +15,7 @@ void GfApeSmashingQB::OnTimerDone(Entity* self, std::string timerName) { } void GfApeSmashingQB::OnRebuildComplete(Entity* self, Entity* target) { - auto* ape = EntityManager::Instance()->GetEntity(self->GetVar(u"ape")); + auto* ape = Game::entityManager->GetEntity(self->GetVar(u"ape")); if (ape != nullptr) { ape->OnFireEventServerSide(target, "rebuildDone"); RenderComponent::PlayAnimation(self, u"smash", 1.7f); diff --git a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp index 19788677..87416b4d 100644 --- a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp +++ b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp @@ -29,7 +29,7 @@ void TreasureChestDragonServer::OnUse(Entity* self, Entity* user) { rating = team->members.size(); for (const auto member : team->members) { - auto* memberObject = EntityManager::Instance()->GetEntity(member); + auto* memberObject = Game::entityManager->GetEntity(member); if (memberObject == nullptr) continue; diff --git a/dScripts/02_server/Equipment/BootyDigServer.cpp b/dScripts/02_server/Equipment/BootyDigServer.cpp index 190c232b..d27d1faa 100644 --- a/dScripts/02_server/Equipment/BootyDigServer.cpp +++ b/dScripts/02_server/Equipment/BootyDigServer.cpp @@ -7,14 +7,14 @@ #include "Loot.h" void BootyDigServer::OnStartup(Entity* self) { - auto* zoneControlObject = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControlObject = Game::entityManager->GetZoneControlEntity(); if (zoneControlObject != nullptr) { zoneControlObject->OnFireEventServerSide(self, "CheckForPropertyOwner"); } } void BootyDigServer::OnPlayerLoaded(Entity* self, Entity* player) { - auto* zoneControlObject = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControlObject = Game::entityManager->GetZoneControlEntity(); if (zoneControlObject != nullptr) { zoneControlObject->OnFireEventServerSide(self, "CheckForPropertyOwner"); } diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp index 4de8a998..689eaac3 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp @@ -18,7 +18,7 @@ void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* se if (sender == nullptr) return; if (args == "attemptCollection") { - Entity* player = EntityManager::Instance()->GetEntity(self->GetSpawnerID()); + Entity* player = Game::entityManager->GetEntity(self->GetSpawnerID()); if (!player) return; auto missionComponent = player->GetComponent(); diff --git a/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp b/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp index 13c9c04b..4d7e8a64 100644 --- a/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp +++ b/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp @@ -8,7 +8,7 @@ void AgCagedBricksServer::OnUse(Entity* self, Entity* user) { //Tell the client to spawn the baby spiderling: - auto spooders = EntityManager::Instance()->GetEntitiesInGroup("cagedSpider"); + auto spooders = Game::entityManager->GetEntitiesInGroup("cagedSpider"); for (auto spodder : spooders) { GameMessages::SendFireEventClientSide(spodder->GetObjectID(), user->GetSystemAddress(), u"toggle", LWOOBJID_EMPTY, 0, 0, user->GetObjectID()); } diff --git a/dScripts/02_server/Map/AG/AgMonumentBirds.cpp b/dScripts/02_server/Map/AG/AgMonumentBirds.cpp index 9d4a3349..c9df4dc1 100644 --- a/dScripts/02_server/Map/AG/AgMonumentBirds.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentBirds.cpp @@ -28,7 +28,7 @@ void AgMonumentBirds::OnProximityUpdate(Entity* self, Entity* entering, std::str void AgMonumentBirds::OnTimerDone(Entity* self, std::string timerName) { if (timerName != "killBird") return; - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(u"PlayerID")); + auto* player = Game::entityManager->GetEntity(self->GetVar(u"PlayerID")); if (player == nullptr) return; diff --git a/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp b/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp index b2062935..34c5c9a6 100644 --- a/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp @@ -2,14 +2,14 @@ #include "EntityManager.h" void AgMonumentLaserServer::OnStartup(Entity* self) { - auto lasers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); + auto lasers = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); for (auto laser : lasers) { if (laser) laser->SetBoolean(u"active", true); } } void AgMonumentLaserServer::OnDie(Entity* self, Entity* killer) { - auto lasers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); + auto lasers = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); for (auto laser : lasers) { if (laser) laser->SetBoolean(u"active", false); } diff --git a/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp b/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp index 2e744434..1f0db946 100644 --- a/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp @@ -2,7 +2,7 @@ #include "EntityManager.h" void AgMonumentRaceCancel::OnCollisionPhantom(Entity* self, Entity* target) { - auto managers = EntityManager::Instance()->GetEntitiesInGroup("race_manager"); + auto managers = Game::entityManager->GetEntitiesInGroup("race_manager"); if (!managers.empty()) { managers[0]->OnFireEventServerSide(target, "course_cancel"); } diff --git a/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp b/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp index 0dd91bf2..6d305d4b 100644 --- a/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp @@ -8,7 +8,7 @@ void AgMonumentRaceGoal::OnStartup(Entity* self) { void AgMonumentRaceGoal::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { if (name == "RaceGoal" && entering && entering->IsPlayer() && status == "ENTER") { - auto managers = EntityManager::Instance()->GetEntitiesInGroup("race_manager"); + auto managers = Game::entityManager->GetEntitiesInGroup("race_manager"); if (managers.empty() || !managers.at(0)) return; managers.at(0)->OnFireEventServerSide(entering, "course_finish"); } diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index d2cc647e..199e4c64 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -40,7 +40,7 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 scriptedActivityComponent->RemoveActivityPlayerData(sender->GetObjectID()); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else if (identifier == u"player_dialog_start_course" && button == 1) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"start_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); @@ -54,7 +54,7 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 data->values[1] = *(float*)&startTime; - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else if (identifier == u"FootRaceCancel") { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stop_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); @@ -95,7 +95,7 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std "performact_time"); } - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), 0, (uint32_t)finish); diff --git a/dScripts/02_server/Map/AG/NpcWispServer.cpp b/dScripts/02_server/Map/AG/NpcWispServer.cpp index 84196c8c..e3b5398d 100644 --- a/dScripts/02_server/Map/AG/NpcWispServer.cpp +++ b/dScripts/02_server/Map/AG/NpcWispServer.cpp @@ -35,7 +35,7 @@ void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missio : std::vector{ "MaelstromSamples", "MaelstromSamples2ndary1", "MaelstromSamples2ndary2" }; for (const auto& group : groups) { - auto samples = EntityManager::Instance()->GetEntitiesInGroup(group); + auto samples = Game::entityManager->GetEntitiesInGroup(group); for (auto* sample : samples) { GameMessages::SendNotifyClientObject(sample->GetObjectID(), u"SetVisibility", visible, 0, target->GetObjectID(), "", target->GetSystemAddress()); diff --git a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp index 2711b179..2091041b 100644 --- a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp +++ b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp @@ -63,7 +63,7 @@ void ZoneAgSpiderQueen::OnTimerDone(Entity* self, std::string timerName) { return; if (timerName == "killSpider") { - auto spawnTargets = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(LandTargetGroup)); + auto spawnTargets = Game::entityManager->GetEntitiesInGroup(self->GetVar(LandTargetGroup)); for (auto* spawnTarget : spawnTargets) { EntityInfo info{}; @@ -75,8 +75,8 @@ void ZoneAgSpiderQueen::OnTimerDone(Entity* self, std::string timerName) { new LDFData(u"parent_tag", self->GetObjectID()) }; - auto* chest = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(chest); + auto* chest = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(chest); } } diff --git a/dScripts/02_server/Map/AM/AmBlueX.cpp b/dScripts/02_server/Map/AM/AmBlueX.cpp index 8e32694c..180d4c54 100644 --- a/dScripts/02_server/Map/AM/AmBlueX.cpp +++ b/dScripts/02_server/Map/AM/AmBlueX.cpp @@ -27,16 +27,16 @@ void AmBlueX::OnSkillEventFired(Entity* self, Entity* caster, const std::string& info.rot = self->GetRotation(); info.spawnerID = self->GetObjectID(); - auto* fxObject = EntityManager::Instance()->CreateEntity(info, nullptr, self); - EntityManager::Instance()->ConstructEntity(fxObject); + auto* fxObject = Game::entityManager->CreateEntity(info, nullptr, self); + Game::entityManager->ConstructEntity(fxObject); auto fxObjectID = fxObject->GetObjectID(); auto playerID = caster->GetObjectID(); // Add a callback for the bomb to explode self->AddCallbackTimer(m_BombTime, [this, self, fxObjectID, playerID]() { - auto* fxObject = EntityManager::Instance()->GetEntity(fxObjectID); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* fxObject = Game::entityManager->GetEntity(fxObjectID); + auto* player = Game::entityManager->GetEntity(playerID); auto* skillComponent = self->GetComponent(); if (skillComponent == nullptr) diff --git a/dScripts/02_server/Map/AM/AmBridge.cpp b/dScripts/02_server/Map/AM/AmBridge.cpp index 719ca058..2fce627d 100644 --- a/dScripts/02_server/Map/AM/AmBridge.cpp +++ b/dScripts/02_server/Map/AM/AmBridge.cpp @@ -6,7 +6,7 @@ void AmBridge::OnStartup(Entity* self) { } void AmBridge::OnRebuildComplete(Entity* self, Entity* target) { - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console" + GeneralUtils::UTF16ToWTF8(self->GetVar(u"bridge"))); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console" + GeneralUtils::UTF16ToWTF8(self->GetVar(u"bridge"))); if (consoles.empty()) { return; diff --git a/dScripts/02_server/Map/AM/AmDrawBridge.cpp b/dScripts/02_server/Map/AM/AmDrawBridge.cpp index 3c4dcce6..e6b80764 100644 --- a/dScripts/02_server/Map/AM/AmDrawBridge.cpp +++ b/dScripts/02_server/Map/AM/AmDrawBridge.cpp @@ -68,7 +68,7 @@ void AmDrawBridge::OnTimerDone(Entity* self, std::string timerName) { simplePhysicsComponent->SetAngularVelocity(NiPoint3::ZERO); - EntityManager::Instance()->SerializeEntity(bridge); + Game::entityManager->SerializeEntity(bridge); } } @@ -103,7 +103,7 @@ void AmDrawBridge::MoveBridgeDown(Entity* self, Entity* bridge, bool down) { simplePhysicsComponent->SetAngularVelocity(forwardVect); - EntityManager::Instance()->SerializeEntity(bridge); + Game::entityManager->SerializeEntity(bridge); self->AddTimer("rotateBridgeDown", travelTime); } @@ -118,5 +118,5 @@ void AmDrawBridge::NotifyDie(Entity* self, Entity* other) { Entity* AmDrawBridge::GetBridge(Entity* self) { const auto bridgeID = self->GetVar(u"BridgeID"); - return EntityManager::Instance()->GetEntity(bridgeID); + return Game::entityManager->GetEntity(bridgeID); } diff --git a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp index 5d1b7d08..e39233eb 100644 --- a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp @@ -49,7 +49,7 @@ void AmShieldGenerator::OnProximityUpdate(Entity* self, Entity* entering, std::s void AmShieldGenerator::OnDie(Entity* self, Entity* killer) { self->CancelAllTimers(); - auto* child = EntityManager::Instance()->GetEntity(self->GetVar(u"Child")); + auto* child = Game::entityManager->GetEntity(self->GetVar(u"Child")); if (child != nullptr) { child->Kill(); @@ -69,7 +69,7 @@ void AmShieldGenerator::OnTimerDone(Entity* self, std::string timerName) { auto enemiesInProximity = self->GetVar>(u"Enemies"); for (const auto enemyID : enemiesInProximity) { - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr) { EnemyEnteredShield(self, enemy); @@ -94,7 +94,7 @@ void AmShieldGenerator::StartShield(Entity* self) { info.rot = myRot; info.spawnerID = self->GetObjectID(); - auto* child = EntityManager::Instance()->CreateEntity(info); + auto* child = Game::entityManager->CreateEntity(info); self->SetVar(u"Child", child->GetObjectID()); @@ -111,7 +111,7 @@ void AmShieldGenerator::BuffPlayers(Entity* self) { auto entitiesInProximity = self->GetVar>(u"Players"); for (const auto playerID : entitiesInProximity) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp index 381c13bc..506f5580 100644 --- a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp @@ -69,7 +69,7 @@ void AmShieldGeneratorQuickbuild::OnProximityUpdate(Entity* self, Entity* enteri void AmShieldGeneratorQuickbuild::OnDie(Entity* self, Entity* killer) { self->CancelAllTimers(); - auto* child = EntityManager::Instance()->GetEntity(self->GetVar(u"Child")); + auto* child = Game::entityManager->GetEntity(self->GetVar(u"Child")); if (child != nullptr) { child->Kill(); @@ -89,7 +89,7 @@ void AmShieldGeneratorQuickbuild::OnTimerDone(Entity* self, std::string timerNam auto enemiesInProximity = self->GetVar>(u"Enemies"); for (const auto enemyID : enemiesInProximity) { - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr) { EnemyEnteredShield(self, enemy); @@ -106,7 +106,7 @@ void AmShieldGeneratorQuickbuild::OnRebuildComplete(Entity* self, Entity* target auto enemiesInProximity = self->GetVar>(u"Enemies"); for (const auto enemyID : enemiesInProximity) { - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr) { enemy->Smash(); @@ -116,7 +116,7 @@ void AmShieldGeneratorQuickbuild::OnRebuildComplete(Entity* self, Entity* target auto entitiesInProximity = self->GetVar>(u"Players"); for (const auto playerID : entitiesInProximity) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { continue; @@ -146,7 +146,7 @@ void AmShieldGeneratorQuickbuild::StartShield(Entity* self) { info.rot = myRot; info.spawnerID = self->GetObjectID(); - auto* child = EntityManager::Instance()->CreateEntity(info); + auto* child = Game::entityManager->CreateEntity(info); self->SetVar(u"Child", child->GetObjectID()); @@ -163,7 +163,7 @@ void AmShieldGeneratorQuickbuild::BuffPlayers(Entity* self) { auto entitiesInProximity = self->GetVar>(u"Players"); for (const auto playerID : entitiesInProximity) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp index e35c700d..576688e7 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp @@ -44,7 +44,7 @@ Entity* AmSkullkinDrill::GetStandObj(Entity* self) { groupName.push_back(myGroup[0][myGroup[0].size() - 1]); - const auto standObjs = EntityManager::Instance()->GetEntitiesInGroup(groupName); + const auto standObjs = Game::entityManager->GetEntitiesInGroup(groupName); if (standObjs.empty()) { return nullptr; @@ -105,16 +105,16 @@ void AmSkullkinDrill::OnWaypointReached(Entity* self, uint32_t waypointIndex) { info.scale = 3; // Needs the scale, otherwise attacks fail info.spawnerID = self->GetObjectID(); - auto* child = EntityManager::Instance()->CreateEntity(info); + auto* child = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(child); + Game::entityManager->ConstructEntity(child); self->SetVar(u"ChildSmash", child->GetObjectID()); child->AddDieCallback([this, self]() { const auto& userID = self->GetVar(u"activaterID"); - auto* player = EntityManager::Instance()->GetEntity(userID); + auto* player = Game::entityManager->GetEntity(userID); if (player == nullptr) { return; @@ -180,7 +180,7 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) { const auto playerID = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { PlayAnim(self, player, "spinjitzu-staff-end"); @@ -199,7 +199,7 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) { } void AmSkullkinDrill::PlayCinematic(Entity* self) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(u"userID")); + auto* player = Game::entityManager->GetEntity(self->GetVar(u"userID")); if (player == nullptr) { return; @@ -235,7 +235,7 @@ void AmSkullkinDrill::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t const auto activaterID = self->GetVar(u"activaterID"); - auto* activator = EntityManager::Instance()->GetEntity(activaterID); + auto* activator = Game::entityManager->GetEntity(activaterID); // TODO: Missions if (activator != nullptr) { @@ -263,7 +263,7 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "killDrill") { const auto childID = self->GetVar(u"ChildSmash"); - auto* child = EntityManager::Instance()->GetEntity(childID); + auto* child = Game::entityManager->GetEntity(childID); if (child != nullptr) { child->Smash(self->GetObjectID(), eKillType::SILENT); @@ -301,7 +301,7 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { const auto playerID = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp index f7825f8f..0c0f7515 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp @@ -64,9 +64,9 @@ void AmSkullkinTower::SpawnLegs(Entity* self, const std::string& loc) { info.rot = NiQuaternion::LookAt(info.pos, self->GetPosition()); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); OnChildLoaded(self, entity); } @@ -81,7 +81,7 @@ void AmSkullkinTower::OnChildLoaded(Entity* self, Entity* child) { const auto selfID = self->GetObjectID(); child->AddDieCallback([this, selfID, child]() { - auto* self = EntityManager::Instance()->GetEntity(selfID); + auto* self = Game::entityManager->GetEntity(selfID); auto* destroyableComponent = child->GetComponent(); if (destroyableComponent == nullptr || self == nullptr) { @@ -157,7 +157,7 @@ void AmSkullkinTower::OnChildRemoved(Entity* self, Entity* child) { const auto& players = self->GetVar>(u"Players"); for (const auto& playerID : players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { continue; @@ -233,9 +233,9 @@ void AmSkullkinTower::OnTimerDone(Entity* self, std::string timerName) { for (size_t i = 0; i < 2; i++) { info.pos.x += i * 2; // Just to set the apart a bit - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); } self->AddTimer("killTower", 0.7f); diff --git a/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp b/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp index cfc58fa0..ddaafc65 100644 --- a/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp +++ b/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp @@ -22,13 +22,13 @@ void EnemyRoninSpawner::OnTimerDone(Entity* self, std::string timerName) { info.rot = self->GetRotation(); info.spawnerID = self->GetObjectID(); - auto* spawnedEntity = EntityManager::Instance()->CreateEntity(info); + auto* spawnedEntity = Game::entityManager->CreateEntity(info); if (spawnedEntity == nullptr) { return; } - EntityManager::Instance()->ConstructEntity(spawnedEntity); + Game::entityManager->ConstructEntity(spawnedEntity); spawnedEntity->AddCallbackTimer(60, [spawnedEntity]() { spawnedEntity->Smash(spawnedEntity->GetObjectID()); diff --git a/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp b/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp index e87d9629..04bf94c5 100644 --- a/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp +++ b/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp @@ -33,7 +33,7 @@ FvHorsemenTrigger::OnFireEventServerSide(Entity* self, Entity* sender, std::stri if (args == "HorsemenDeath") { for (const auto& playerId : self->GetVar>(u"players")) { - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) { continue; diff --git a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp index 7d86cc73..ec86b0fa 100644 --- a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp +++ b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp @@ -23,7 +23,7 @@ void ImgBrickConsoleQB::OnUse(Entity* self, Entity* user) { if (rebuildComponent->GetState() == eRebuildState::COMPLETED) { if (!self->GetNetworkVar(u"used")) { - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console"); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console"); auto bothBuilt = false; @@ -59,7 +59,7 @@ void ImgBrickConsoleQB::OnUse(Entity* self, Entity* user) { onFX = 2779; } - const auto& facility = EntityManager::Instance()->GetEntitiesInGroup("FacilityPipes"); + const auto& facility = Game::entityManager->GetEntitiesInGroup("FacilityPipes"); if (!facility.empty()) { GameMessages::SendStopFXEffect(facility[0], true, location + "PipeEnergy"); @@ -106,13 +106,13 @@ void ImgBrickConsoleQB::SpawnBrick(Entity* self) { } void ImgBrickConsoleQB::SmashCanister(Entity* self) { - const auto brick = EntityManager::Instance()->GetEntitiesInGroup("Imagination"); + const auto brick = Game::entityManager->GetEntitiesInGroup("Imagination"); if (!brick.empty()) { GameMessages::SendPlayFXEffect(brick[0]->GetObjectID(), 122, u"create", "bluebrick"); GameMessages::SendPlayFXEffect(brick[0]->GetObjectID(), 1034, u"cast", "imaginationexplosion"); } - const auto canisters = EntityManager::Instance()->GetEntitiesInGroup("Canister"); + const auto canisters = Game::entityManager->GetEntitiesInGroup("Canister"); for (auto* canister : canisters) { canister->Smash(canister->GetObjectID(), eKillType::VIOLENT); } @@ -135,14 +135,14 @@ void ImgBrickConsoleQB::OnRebuildComplete(Entity* self, Entity* target) { energyFX = 2778; } - const auto& facility = EntityManager::Instance()->GetEntitiesInGroup("FacilityPipes"); + const auto& facility = Game::entityManager->GetEntitiesInGroup("FacilityPipes"); if (!facility.empty()) { GameMessages::SendStopFXEffect(facility[0], true, location + "PipeOff"); GameMessages::SendPlayFXEffect(facility[0]->GetObjectID(), energyFX, u"create", location + "PipeEnergy"); } - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console"); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console"); for (auto* console : consoles) { auto* consoleRebuildComponent = console->GetComponent(); @@ -179,7 +179,7 @@ void ImgBrickConsoleQB::OnDie(Entity* self, Entity* killer) { offFX = 2777; } - const auto& facility = EntityManager::Instance()->GetEntitiesInGroup("FacilityPipes"); + const auto& facility = Game::entityManager->GetEntitiesInGroup("FacilityPipes"); if (!facility.empty()) { GameMessages::SendStopFXEffect(facility[0], true, location + "PipeEnergy"); @@ -233,7 +233,7 @@ void ImgBrickConsoleQB::OnTimerDone(Entity* self, std::string timerName) { self->Smash(self->GetObjectID(), eKillType::SILENT); } } else if (timerName == "Die") { - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console"); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console"); for (auto* console : consoles) { console->Smash(console->GetObjectID(), eKillType::VIOLENT); diff --git a/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp b/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp index 155be92b..c607c0fc 100644 --- a/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp +++ b/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp @@ -29,7 +29,7 @@ void RaceMaelstromGeiser::OnProximityUpdate(Entity* self, Entity* entering, std: Entity* player; if (possessableComponent != nullptr) { - player = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + player = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (player == nullptr) { return; @@ -43,7 +43,7 @@ void RaceMaelstromGeiser::OnProximityUpdate(Entity* self, Entity* entering, std: return; } - vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) { return; diff --git a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp index c366d0fb..242bfe4f 100644 --- a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp +++ b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp @@ -40,7 +40,7 @@ void GfCaptainsCannon::OnUse(Entity* self, Entity* user) { void GfCaptainsCannon::OnTimerDone(Entity* self, std::string timerName) { const auto playerId = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) { self->SetVar(u"bIsInUse", false); @@ -56,7 +56,7 @@ void GfCaptainsCannon::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("cinematicTimer", cinematicTime); - const auto sharkObjects = EntityManager::Instance()->GetEntitiesInGroup("SharkCannon"); + const auto sharkObjects = Game::entityManager->GetEntitiesInGroup("SharkCannon"); for (auto* shark : sharkObjects) { if (shark->GetLOT() != m_SharkItemID) continue; diff --git a/dScripts/02_server/Map/GF/GfTikiTorch.cpp b/dScripts/02_server/Map/GF/GfTikiTorch.cpp index 5d944f0f..e61abd76 100644 --- a/dScripts/02_server/Map/GF/GfTikiTorch.cpp +++ b/dScripts/02_server/Map/GF/GfTikiTorch.cpp @@ -32,7 +32,7 @@ void GfTikiTorch::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "Relight") { LightTorch(self); } else if (timerName == "InteractionCooldown") { - Entity* player = EntityManager::Instance()->GetEntity(self->GetI64(u"userID")); + Entity* player = Game::entityManager->GetEntity(self->GetI64(u"userID")); if (player != nullptr && player->GetCharacter()) { GameMessages::SendTerminateInteraction(player->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID()); diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index 5f8795a3..29df4bf5 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -33,7 +33,7 @@ void MastTeleport::OnRebuildComplete(Entity* self, Entity* target) { void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { const auto playerId = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; @@ -88,6 +88,6 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { ); auto* destroyableComponent = player->GetComponent(); if (destroyableComponent) destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true, true, true, true, true, false, false, true, true); - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(player); } } diff --git a/dScripts/02_server/Map/General/ForceVolumeServer.cpp b/dScripts/02_server/Map/General/ForceVolumeServer.cpp index ed9024c1..7febe87e 100644 --- a/dScripts/02_server/Map/General/ForceVolumeServer.cpp +++ b/dScripts/02_server/Map/General/ForceVolumeServer.cpp @@ -18,5 +18,5 @@ void ForceVolumeServer::OnStartup(Entity* self) { phantomPhysicsComponent->SetDirection({ forceX, forceY, forceZ }); phantomPhysicsComponent->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } diff --git a/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp b/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp index 8a9230d9..f7f6a117 100644 --- a/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp +++ b/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp @@ -10,13 +10,13 @@ void NjIceRailActivator::OnPlayerRailArrived(Entity* self, Entity* sender, const if (breakPoint == waypoint) { const auto& blockGroup = self->GetVar(BlockGroupVariable); - for (auto* block : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(blockGroup))) { + for (auto* block : Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(blockGroup))) { RenderComponent::PlayAnimation(block, u"explode"); const auto blockID = block->GetObjectID(); self->AddCallbackTimer(1.0f, [self, blockID]() { - auto* block = EntityManager::Instance()->GetEntity(blockID); + auto* block = Game::entityManager->GetEntity(blockID); if (block != nullptr) { block->Kill(self); diff --git a/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp b/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp index 2c435705..f47f7e7b 100644 --- a/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp +++ b/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp @@ -42,7 +42,7 @@ void NjRailPostServer::OnRebuildNotifyState(Entity* self, eRebuildState state) { Entity* NjRailPostServer::GetRelatedRail(Entity* self) { const auto& railGroup = self->GetVar(RailGroupVariable); if (!railGroup.empty()) { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(railGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(railGroup))) { return entity; } } diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index 8c819a8d..e1bedc5e 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -95,7 +95,7 @@ void PetDigServer::OnDie(Entity* self, Entity* killer) { // TODO: Reset other pets // Handles smashing leftovers (edge case for the AG X) - auto* xObject = EntityManager::Instance()->GetEntity(self->GetVar(u"X")); + auto* xObject = Game::entityManager->GetEntity(self->GetVar(u"X")); if (xObject != nullptr) { xObject->Smash(xObject->GetObjectID(), eKillType::VIOLENT); } @@ -106,7 +106,7 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe if (playerID == LWOOBJID_EMPTY || playerID != owner->GetObjectID()) return; - auto* playerEntity = EntityManager::Instance()->GetEntity(playerID); + auto* playerEntity = Game::entityManager->GetEntity(playerID); if (!playerEntity || !playerEntity->GetParentUser() || !playerEntity->GetParentUser()->GetLastUsedChar()) return; @@ -134,7 +134,7 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe player->SetPlayerFlag(playerFlag, true); } - auto* xObject = EntityManager::Instance()->GetEntity(self->GetVar(u"X")); + auto* xObject = Game::entityManager->GetEntity(self->GetVar(u"X")); if (xObject != nullptr) { xObject->Smash(xObject->GetObjectID(), eKillType::VIOLENT); } @@ -211,8 +211,8 @@ void PetDigServer::SpawnPet(Entity* self, const Entity* owner, const DigInfo dig new LDFData(u"spawnTimer", 1.0) }; - auto* spawnedPet = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(spawnedPet); + auto* spawnedPet = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(spawnedPet); } Entity* PetDigServer::GetClosestTresure(NiPoint3 position) { @@ -220,7 +220,7 @@ Entity* PetDigServer::GetClosestTresure(NiPoint3 position) { Entity* closest = nullptr; for (const auto tresureId : treasures) { - auto* tresure = EntityManager::Instance()->GetEntity(tresureId); + auto* tresure = Game::entityManager->GetEntity(tresureId); if (tresure == nullptr) continue; diff --git a/dScripts/02_server/Map/General/PropertyDevice.cpp b/dScripts/02_server/Map/General/PropertyDevice.cpp index 0ad9f5c9..61ebe96e 100644 --- a/dScripts/02_server/Map/General/PropertyDevice.cpp +++ b/dScripts/02_server/Map/General/PropertyDevice.cpp @@ -5,7 +5,7 @@ #include "eMissionState.h" void PropertyDevice::OnStartup(Entity* self) { - auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControl = Game::entityManager->GetZoneControlEntity(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "CheckForPropertyOwner"); } diff --git a/dScripts/02_server/Map/General/QbSpawner.cpp b/dScripts/02_server/Map/General/QbSpawner.cpp index d5c9d001..6776c8ea 100644 --- a/dScripts/02_server/Map/General/QbSpawner.cpp +++ b/dScripts/02_server/Map/General/QbSpawner.cpp @@ -41,7 +41,7 @@ void QbSpawner::OnTimerDone(Entity* self, std::string timerName) { auto gateObjID = self->GetVar(u"gateObj"); if (!gateObjID) return; - auto* gate = EntityManager::Instance()->GetEntity(gateObjID); + auto* gate = Game::entityManager->GetEntity(gateObjID); if (!gate) return; auto oPos = gate->GetPosition(); @@ -75,12 +75,12 @@ void QbSpawner::OnTimerDone(Entity* self, std::string timerName) { new LDFData(u"mobTableLoc", i) }; - auto* child = EntityManager::Instance()->CreateEntity(info, nullptr, self); - EntityManager::Instance()->ConstructEntity(child); + auto* child = Game::entityManager->CreateEntity(info, nullptr, self); + Game::entityManager->ConstructEntity(child); OnChildLoaded(self, child); } else { - auto* mob = EntityManager::Instance()->GetEntity(mobTable[i]); + auto* mob = Game::entityManager->GetEntity(mobTable[i]); AggroTargetObject(self, mob); } } @@ -100,7 +100,7 @@ void QbSpawner::OnChildLoaded(Entity* self, Entity* child) { const auto selfID = self->GetObjectID(); child->AddDieCallback([this, selfID, child]() { - auto* self = EntityManager::Instance()->GetEntity(selfID); + auto* self = Game::entityManager->GetEntity(selfID); OnChildRemoved(self, child); } ); @@ -120,7 +120,7 @@ void QbSpawner::AggroTargetObject(Entity* self, Entity* enemy) { auto gateObjID = self->GetVar(u"gateObj"); if (gateObjID) { - auto* gate = EntityManager::Instance()->GetEntity(gateObjID); + auto* gate = Game::entityManager->GetEntity(gateObjID); if (gate) { auto* movementAIComponent = enemy->GetComponent(); if (movementAIComponent) movementAIComponent->SetDestination(gate->GetPosition()); diff --git a/dScripts/02_server/Map/General/WishingWellServer.cpp b/dScripts/02_server/Map/General/WishingWellServer.cpp index 58ce1c72..51f742ec 100644 --- a/dScripts/02_server/Map/General/WishingWellServer.cpp +++ b/dScripts/02_server/Map/General/WishingWellServer.cpp @@ -33,7 +33,7 @@ void WishingWellServer::OnUse(Entity* self, Entity* user) { const auto userID = user->GetObjectID(); self->AddCallbackTimer(10, [self, userID]() { - auto* user = EntityManager::Instance()->GetEntity(userID); + auto* user = Game::entityManager->GetEntity(userID); if (user == nullptr) return; diff --git a/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp b/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp index a338d9c9..554eabac 100644 --- a/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp +++ b/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp @@ -40,8 +40,8 @@ void NsConcertChoiceBuildManager::SpawnCrate(Entity* self) { new LDFData(u"crateTime", crate.time), }; - auto* spawnedCrate = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(spawnedCrate); + auto* spawnedCrate = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(spawnedCrate); spawnedCrate->AddDieCallback([self]() { self->CancelAllTimers(); // Don't switch if the crate was smashed @@ -56,7 +56,7 @@ void NsConcertChoiceBuildManager::SpawnCrate(Entity* self) { self->AddCallbackTimer(crate.time, [self]() { auto crateID = self->GetVar(u"currentCrate"); if (crateID != LWOOBJID_EMPTY) { - EntityManager::Instance()->DestroyEntity(crateID); + Game::entityManager->DestroyEntity(crateID); self->SetVar(u"currentCrate", LWOOBJID_EMPTY); } diff --git a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp index 99bc0de5..6ae4c767 100644 --- a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp +++ b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp @@ -57,7 +57,7 @@ void NtAssemblyTubeServer::RunAssemblyTube(Entity* self, Entity* player) { const auto animTime = 3; self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -73,7 +73,7 @@ void NtAssemblyTubeServer::TeleportPlayer(Entity* self, Entity* player) { auto* destination = self; if (!destinationGroup.empty()) { - const auto& groupObjs = EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); + const auto& groupObjs = Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); if (!groupObjs.empty()) { destination = groupObjs[0]; @@ -92,7 +92,7 @@ void NtAssemblyTubeServer::TeleportPlayer(Entity* self, Entity* player) { const auto playerID = player->GetObjectID(); self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp index c9cd8f0a..5be5a9b3 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp @@ -4,7 +4,7 @@ void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { @@ -16,7 +16,7 @@ void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) { void NtCombatChallengeDummy::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp index c117c63a..de27e106 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp @@ -5,7 +5,7 @@ void NtCombatChallengeExplodingDummy::OnDie(Entity* self, Entity* killer) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { @@ -17,7 +17,7 @@ void NtCombatChallengeExplodingDummy::OnDie(Entity* self, Entity* killer) { void NtCombatChallengeExplodingDummy::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp index d27ac1f6..2c2f84c2 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp @@ -19,7 +19,7 @@ void NtCombatChallengeServer::OnDie(Entity* self, Entity* killer) { void NtCombatChallengeServer::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -69,7 +69,7 @@ void NtCombatChallengeServer::OnMessageBoxResponse(Entity* self, Entity* sender, void NtCombatChallengeServer::SpawnTargetDummy(Entity* self) { const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -91,11 +91,11 @@ void NtCombatChallengeServer::SpawnTargetDummy(Entity* self) { info.rot = self->GetRotation(); info.settings = { new LDFData(u"custom_script_server", "scripts\\02_server\\Map\\NT\\L_NT_COMBAT_CHALLENGE_DUMMY.lua") }; - auto* dummy = EntityManager::Instance()->CreateEntity(info); + auto* dummy = Game::entityManager->CreateEntity(info); dummy->SetVar(u"challengeObjectID", self->GetObjectID()); - EntityManager::Instance()->ConstructEntity(dummy); + Game::entityManager->ConstructEntity(dummy); self->SetVar(u"currentDummy", dummy->GetObjectID()); } @@ -111,7 +111,7 @@ void NtCombatChallengeServer::OnChildLoaded(Entity* self, Entity* child) { const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -121,7 +121,7 @@ void NtCombatChallengeServer::OnChildLoaded(Entity* self, Entity* child) { self->SetVar(u"currentTargetID", child->GetObjectID()); - EntityManager::Instance()->SerializeEntity(child); + Game::entityManager->SerializeEntity(child); child->GetGroups().push_back("targets_" + std::to_string(self->GetObjectID())); } @@ -130,7 +130,7 @@ void NtCombatChallengeServer::ResetGame(Entity* self) { const auto totalDmg = self->GetVar(u"totalDmg"); const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { auto* missionComponent = player->GetComponent(); @@ -150,7 +150,7 @@ void NtCombatChallengeServer::ResetGame(Entity* self) { self->SetNetworkVar(u"totalDmg", false); self->SetNetworkVar(u"update_time", 0); - const auto& targetObjs = EntityManager::Instance()->GetEntitiesInGroup("targets_" + std::to_string(self->GetObjectID())); + const auto& targetObjs = Game::entityManager->GetEntitiesInGroup("targets_" + std::to_string(self->GetObjectID())); for (auto* target : targetObjs) { target->Smash(self->GetObjectID()); @@ -158,7 +158,7 @@ void NtCombatChallengeServer::ResetGame(Entity* self) { const auto currentID = self->GetVar(u"currentDummy"); - auto* current = EntityManager::Instance()->GetEntity(currentID); + auto* current = Game::entityManager->GetEntity(currentID); if (current != nullptr) { current->Smash(self->GetObjectID()); diff --git a/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp b/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp index d98a7403..961e93cd 100644 --- a/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp +++ b/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp @@ -40,7 +40,7 @@ void NtImagBeamBuffer::OnTimerDone(Entity* self, std::string timerName) { } for (const auto entityID : m_EntitiesInProximity) { - auto* entity = EntityManager::Instance()->GetEntity(entityID); + auto* entity = Game::entityManager->GetEntity(entityID); if (entity == nullptr) { continue; diff --git a/dScripts/02_server/Map/NT/NtOverbuildServer.cpp b/dScripts/02_server/Map/NT/NtOverbuildServer.cpp index f8520d87..e75d8add 100644 --- a/dScripts/02_server/Map/NT/NtOverbuildServer.cpp +++ b/dScripts/02_server/Map/NT/NtOverbuildServer.cpp @@ -21,7 +21,7 @@ void NtOverbuildServer::SetVariables(Entity* self) { // Find the second object Dr. Overbuild interacts with LWOOBJID otherConvoObjectID = LWOOBJID_EMPTY; - for (auto* otherConvoObject : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(self->GetVar(m_OtherEntitiesGroupVariable)))) { + for (auto* otherConvoObject : Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(self->GetVar(m_OtherEntitiesGroupVariable)))) { otherConvoObjectID = otherConvoObject->GetObjectID(); break; } diff --git a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp index dcae84d2..0fe97a26 100644 --- a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp @@ -25,7 +25,7 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { } self->AddCallbackTimer(2, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -55,7 +55,7 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { GameMessages::SendPlayFXEffect(self, 6432, u"create", "console_sparks", LWOOBJID_EMPTY, 1.0, 1.0, true); self->AddCallbackTimer(2, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp index 687a3477..67ff4bec 100644 --- a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp @@ -33,7 +33,7 @@ void NtParadoxTeleServer::OnProximityUpdate(Entity* self, Entity* entering, std: if (animTime == 0.0f) animTime = 2.0f; self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -55,7 +55,7 @@ void NtParadoxTeleServer::TeleportPlayer(Entity* self, Entity* player) { auto* destination = self; if (!destinationGroup.empty()) { - const auto& groupObjs = EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); + const auto& groupObjs = Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); if (!groupObjs.empty()) { destination = groupObjs[0]; @@ -81,7 +81,7 @@ void NtParadoxTeleServer::TeleportPlayer(Entity* self, Entity* player) { const auto playerID = player->GetObjectID(); self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp index 257bf6da..cac0c75f 100644 --- a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp +++ b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp @@ -25,7 +25,7 @@ void NtSentinelWalkwayServer::OnStartup(Entity* self) { phantomPhysicsComponent->SetDirection(forward); phantomPhysicsComponent->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); self->SetProximityRadius(3, "speedboost"); } diff --git a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp index 976cc24f..7e38ac12 100644 --- a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp +++ b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp @@ -44,7 +44,7 @@ void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { }); self->AddCallbackTimer(1.5f, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -57,7 +57,7 @@ void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { void NtVentureCannonServer::EnterCannonEnded(Entity* self, Entity* player) { const auto playerID = player->GetObjectID(); - const auto& cannonEffectGroup = EntityManager::Instance()->GetEntitiesInGroup("cannonEffect"); + const auto& cannonEffectGroup = Game::entityManager->GetEntitiesInGroup("cannonEffect"); if (!cannonEffectGroup.empty()) { auto* cannonEffect = cannonEffectGroup[0]; @@ -83,7 +83,7 @@ void NtVentureCannonServer::EnterCannonEnded(Entity* self, Entity* player) { ); self->AddCallbackTimer(1.5f, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -112,7 +112,7 @@ void NtVentureCannonServer::FirePlayer(Entity* self, Entity* player) { auto* destination = self; if (!destinationGroup.empty()) { - const auto& groupObjs = EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); + const auto& groupObjs = Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); if (!groupObjs.empty()) { destination = groupObjs[0]; diff --git a/dScripts/02_server/Map/PR/HydrantBroken.cpp b/dScripts/02_server/Map/PR/HydrantBroken.cpp index 1409c9fb..2694b425 100644 --- a/dScripts/02_server/Map/PR/HydrantBroken.cpp +++ b/dScripts/02_server/Map/PR/HydrantBroken.cpp @@ -7,7 +7,7 @@ void HydrantBroken::OnStartup(Entity* self) { const auto hydrant = "hydrant" + self->GetVar(u"hydrant"); - const auto bouncers = EntityManager::Instance()->GetEntitiesInGroup(hydrant); + const auto bouncers = Game::entityManager->GetEntitiesInGroup(hydrant); for (auto* bouncer : bouncers) { self->SetVar(u"bouncer", bouncer->GetObjectID()); @@ -22,7 +22,7 @@ void HydrantBroken::OnStartup(Entity* self) { void HydrantBroken::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "KillBroken") { - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"bouncer")); if (bouncer != nullptr) { GameMessages::SendBouncerActiveStatus(bouncer->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); diff --git a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp index 0d4f568e..641845a9 100644 --- a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp @@ -19,7 +19,7 @@ void EnemySpiderSpawner::OnFireEventServerSide(Entity* self, Entity* sender, std if (dest) { dest->SetFaction(-1); } - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); // Keep track of who prepped me self->SetI64(u"SpawnOwner", sender->GetObjectID()); @@ -48,9 +48,9 @@ void EnemySpiderSpawner::OnTimerDone(Entity* self, std::string timerName) { info.spawnerID = self->GetI64(u"SpawnOwner"); info.spawnerNodeID = 0; - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); newEntity->GetGroups().push_back("BabySpider"); /* diff --git a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp index 6bf91768..31086cf4 100644 --- a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp @@ -128,13 +128,13 @@ void ZoneAgProperty::KillSpots(Entity* self) { } for (const auto& groupName : self->GetVar>(ROFTargetsGroup)) { - for (auto* spot : EntityManager::Instance()->GetEntitiesInGroup(groupName)) { + for (auto* spot : Game::entityManager->GetEntitiesInGroup(groupName)) { spot->Kill(); } } DeactivateSpawner(self->GetVar(LandTargetSpawner)); - for (auto* landTarget : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(LandTargetSpawner))) { + for (auto* landTarget : Game::entityManager->GetEntitiesInGroup(self->GetVar(LandTargetSpawner))) { landTarget->Kill(); } } @@ -197,20 +197,20 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { if (zoneId != 1150) return; - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GuardGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(GuardGroup)); if (entities.empty()) return; auto* entity = entities[0]; - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), u"GuardChat", 0, 0, entity->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"GuardChat", 0, 0, entity->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); LoadProperty(self); self->AddTimer("KillGuard", 5); } else if (timerName == "KillGuard") { KillGuard(self); } else if (timerName == "tornadoOff") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { auto* renderComponent = entity->GetComponent(); if (renderComponent != nullptr) { renderComponent->StopEffect("TornadoDebris", false); @@ -222,7 +222,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { self->AddTimer("ShowVendor", 1.2f); self->AddTimer("ShowClearEffects", 2); } else if (timerName == "ShowClearEffects") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { auto* renderComponent = entity->GetComponent(); if (renderComponent != nullptr) { renderComponent->PlayEffect(-1, u"beamOn", "beam"); @@ -236,7 +236,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SkyOff", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); } else if (timerName == "killSpider") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(EnemiesGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(EnemiesGroup))) { entity->Kill(); } @@ -257,7 +257,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { DeactivateSpawner(self->GetVar(SpiderScreamSpawner)); DestroySpawner(self->GetVar(SpiderScreamSpawner)); - for (auto* player : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER)) { + for (auto* player : Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER)) { GameMessages::SendStop2DAmbientSound(player, true, GUIDMaelstrom); GameMessages::SendPlay2DAmbientSound(player, GUIDPeaceful); } @@ -274,7 +274,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { } else if (timerName == "pollTornadoFX") { StartTornadoFx(self); } else if (timerName == "killFXObject") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { auto* renderComponent = entity->GetComponent(); if (renderComponent != nullptr) { renderComponent->StopEffect("beam"); @@ -385,7 +385,7 @@ void ZoneAgProperty::RemovePlayerRef(Entity* self) { void ZoneAgProperty::BaseOnFireEventServerSide(Entity* self, Entity* sender, std::string args) { if (args == "propertyRented") { const auto playerId = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; @@ -409,7 +409,7 @@ void ZoneAgProperty::BaseOnFireEventServerSide(Entity* self, Entity* sender, std sender->SetNetworkVar(u"PropertyOwnerID", std::to_string(self->GetVar(u"PropertyOwner"))); } else if (args == "ClearProperty") { const auto playerId = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; diff --git a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp index 282dce6c..50fea9a0 100644 --- a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp +++ b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp @@ -5,14 +5,14 @@ #include "Entity.h" void PropertyBankInteract::OnStartup(Entity* self) { - auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControl = Game::entityManager->GetZoneControlEntity(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "CheckForPropertyOwner"); } } void PropertyBankInteract::OnPlayerLoaded(Entity* self, Entity* player) { - auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControl = Game::entityManager->GetZoneControlEntity(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "CheckForPropertyOwner"); } diff --git a/dScripts/02_server/Map/VE/VeBricksampleServer.cpp b/dScripts/02_server/Map/VE/VeBricksampleServer.cpp index 0ead6a87..7535d261 100644 --- a/dScripts/02_server/Map/VE/VeBricksampleServer.cpp +++ b/dScripts/02_server/Map/VE/VeBricksampleServer.cpp @@ -14,7 +14,7 @@ void VeBricksampleServer::OnUse(Entity* self, Entity* user) { if (loot && inventoryComponent != nullptr && inventoryComponent->GetLotCount(loot) == 0) { inventoryComponent->AddItem(loot, 1, eLootSourceType::ACTIVITY); - for (auto* brickEntity : EntityManager::Instance()->GetEntitiesInGroup("Bricks")) { + for (auto* brickEntity : Game::entityManager->GetEntitiesInGroup("Bricks")) { GameMessages::SendNotifyClientObject(brickEntity->GetObjectID(), u"Pickedup"); } } diff --git a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp index c69f9cc2..4e8cb4e9 100644 --- a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp +++ b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp @@ -21,7 +21,7 @@ void VeEpsilonServer::OnMissionDialogueOK(Entity* self, Entity* target, int miss // Notify the client that all objects have updated self->AddCallbackTimer(3.0f, [this]() { - for (const auto* console : EntityManager::Instance()->GetEntitiesInGroup(m_ConsoleGroup)) { + for (const auto* console : Game::entityManager->GetEntitiesInGroup(m_ConsoleGroup)) { GameMessages::SendNotifyClientObject(console->GetObjectID(), u""); } }); diff --git a/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp b/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp index 270e7f40..8bed629c 100644 --- a/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp +++ b/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp @@ -19,7 +19,7 @@ void CatapultBaseServer::OnNotifyObject(Entity* self, Entity* sender, const std: void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "PlatAnim") { // get the arm asset - const auto arm = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"ArmGroup")); + const auto arm = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"ArmGroup")); // tell the arm to the play the platform animation, which is just the arm laying there but with bouncer for (auto* obj : arm) { @@ -34,7 +34,7 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("bounce", 3); } else if (timerName == "launchAnim") { // get the arm asset - auto* arm = EntityManager::Instance()->GetEntity(self->GetVar(u"Arm")); + auto* arm = Game::entityManager->GetEntity(self->GetVar(u"Arm")); if (arm == nullptr) return; // tell the arm to player the launcher animation @@ -42,7 +42,7 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("resetArm", animTime); RenderComponent::PlayAnimation(arm, u"launch"); } else if (timerName == "bounce") { - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"Bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"Bouncer")); if (bouncer == nullptr) return; // bounce all players @@ -50,13 +50,13 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { // add a delay to play the animation self->AddTimer("launchAnim", .3); } else if (timerName == "resetArm") { - auto* arm = EntityManager::Instance()->GetEntity(self->GetVar(u"Arm")); + auto* arm = Game::entityManager->GetEntity(self->GetVar(u"Arm")); if (arm == nullptr) return; // set the arm back to natural state RenderComponent::PlayAnimation(arm, u"idle"); - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"Bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"Bouncer")); if (bouncer == nullptr) return; // kill the bouncer diff --git a/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp b/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp index 89faf001..98b8a29d 100644 --- a/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp +++ b/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp @@ -7,7 +7,7 @@ void CatapultBouncerServer::OnRebuildComplete(Entity* self, Entity* target) { self->SetNetworkVar(u"Built", true); - const auto base = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"BaseGroup")); + const auto base = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"BaseGroup")); for (auto* obj : base) { obj->NotifyObject(self, "BouncerBuilt"); diff --git a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp index d04fc03d..ecd6a9e2 100644 --- a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp +++ b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp @@ -36,13 +36,13 @@ void CavePrisonCage::Setup(Entity* self, Spawner* spawner) { info.spawnerID = self->GetObjectID(); // Spawn the villager inside the jail - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); // Save the villeger ID self->SetVar(u"villager", entity->GetObjectID()); // Construct the entity - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); } void CavePrisonCage::OnRebuildNotifyState(Entity* self, eRebuildState state) { @@ -77,7 +77,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { rebuildComponent->AddRebuildCompleteCallback([this, self](Entity* user) { // The counterweight is a simple mover, which is not implemented, so we'll just set it's position - auto* counterweight = EntityManager::Instance()->GetEntity(self->GetVar(u"Counterweight")); + auto* counterweight = Game::entityManager->GetEntity(self->GetVar(u"Counterweight")); if (counterweight == nullptr) { return; @@ -87,7 +87,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { counterweight->SetPosition(counterweight->GetPosition() + NiPoint3(0, -2, 0)); // Serialize the counterweight - EntityManager::Instance()->SerializeEntity(counterweight); + Game::entityManager->SerializeEntity(counterweight); // notifyPlatformAtLastWaypoint @@ -95,7 +95,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { self->SetVar(u"Builder", user->GetObjectID()); // Get the button and make sure it still exists - auto* button = EntityManager::Instance()->GetEntity(self->GetVar(u"Button")); + auto* button = Game::entityManager->GetEntity(self->GetVar(u"Button")); if (button == nullptr) { return; @@ -117,7 +117,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { } void CavePrisonCage::GetButton(Entity* self) { - const auto buttons = EntityManager::Instance()->GetEntitiesInGroup("PrisonButton_0" + std::to_string(self->GetVarAs(u"myNumber"))); + const auto buttons = Game::entityManager->GetEntitiesInGroup("PrisonButton_0" + std::to_string(self->GetVarAs(u"myNumber"))); if (buttons.size() == 0) { // Try again in 0.5 seconds @@ -146,7 +146,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { RenderComponent::PlayAnimation(self, u"idle-up"); // Get the villeger - auto* villager = EntityManager::Instance()->GetEntity(self->GetVar(u"villager")); + auto* villager = Game::entityManager->GetEntity(self->GetVar(u"villager")); if (villager == nullptr) { return; @@ -155,7 +155,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendNotifyClientObject(villager->GetObjectID(), u"TimeToChat", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); // Get the builder and make sure it still exists - auto* builder = EntityManager::Instance()->GetEntity(self->GetVar(u"Builder")); + auto* builder = Game::entityManager->GetEntity(self->GetVar(u"Builder")); if (builder == nullptr) { return; @@ -170,7 +170,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("VillagerEscape", 5.0f); } else if (timerName == "VillagerEscape") { // Get the villeger and make sure it still exists - auto* villager = EntityManager::Instance()->GetEntity(self->GetVar(u"villager")); + auto* villager = Game::entityManager->GetEntity(self->GetVar(u"villager")); if (villager == nullptr) { return; @@ -183,7 +183,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("SmashCounterweight", 2.0f); } else if (timerName == "SmashCounterweight") { // Get the counterweight and make sure it still exists - auto* counterweight = EntityManager::Instance()->GetEntity(self->GetVar(u"Counterweight")); + auto* counterweight = Game::entityManager->GetEntity(self->GetVar(u"Counterweight")); if (counterweight == nullptr) { return; @@ -193,7 +193,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { counterweight->Smash(); // Get the button and make sure it still exists - auto* button = EntityManager::Instance()->GetEntity(self->GetVar(u"Button")); + auto* button = Game::entityManager->GetEntity(self->GetVar(u"Button")); if (button == nullptr) { return; diff --git a/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp b/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp index 0e2e4005..7f4d471c 100644 --- a/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp +++ b/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp @@ -28,13 +28,13 @@ void EnemySkeletonSpawner::OnTimerDone(Entity* self, std::string timerName) { info.rot = self->GetRotation(); info.spawnerID = self->GetObjectID(); - auto* spawnedEntity = EntityManager::Instance()->CreateEntity(info); + auto* spawnedEntity = Game::entityManager->CreateEntity(info); if (spawnedEntity == nullptr) { return; } - EntityManager::Instance()->ConstructEntity(spawnedEntity); + Game::entityManager->ConstructEntity(spawnedEntity); spawnedEntity->AddCallbackTimer(60, [spawnedEntity]() { spawnedEntity->Smash(spawnedEntity->GetObjectID()); diff --git a/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp b/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp index 4ec11e56..f9bd6b98 100644 --- a/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp +++ b/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp @@ -9,7 +9,7 @@ void MonCoreSmashableDoors::OnDie(Entity* self, Entity* killer) { auto triggerGroup = "CoreNookTrig0" + myNum; // Get the trigger - auto triggers = EntityManager::Instance()->GetEntitiesInGroup(triggerGroup); + auto triggers = Game::entityManager->GetEntitiesInGroup(triggerGroup); if (triggers.empty()) { return; diff --git a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp index 30bba804..37a5754c 100644 --- a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp +++ b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp @@ -12,7 +12,7 @@ void NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(Entity* self, Entity* targ // Wait for an animation to complete and flag that the player has learned spinjitzu self->AddCallbackTimer(5.0f, [targetID, element]() { - auto* target = EntityManager::Instance()->GetEntity(targetID); + auto* target = Game::entityManager->GetEntity(targetID); if (target != nullptr) { auto* character = target->GetCharacter(); if (character != nullptr) { diff --git a/dScripts/02_server/Map/njhub/NjWuNPC.cpp b/dScripts/02_server/Map/njhub/NjWuNPC.cpp index f4969074..1a5d30fd 100644 --- a/dScripts/02_server/Map/njhub/NjWuNPC.cpp +++ b/dScripts/02_server/Map/njhub/NjWuNPC.cpp @@ -28,7 +28,7 @@ void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, e character->SetPlayerFlag(ePlayerFlag::NJ_WU_SHOW_DAILY_CHEST, false); // Hide the chest - for (auto* chest : EntityManager::Instance()->GetEntitiesInGroup(m_DragonChestGroup)) { + for (auto* chest : Game::entityManager->GetEntitiesInGroup(m_DragonChestGroup)) { GameMessages::SendNotifyClientObject(chest->GetObjectID(), m_ShowChestNotification, 0, -1, target->GetObjectID(), "", target->GetSystemAddress()); } @@ -41,19 +41,19 @@ void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, e character->SetPlayerFlag(ePlayerFlag::NJ_WU_SHOW_DAILY_CHEST, true); // Show the chest - for (auto* chest : EntityManager::Instance()->GetEntitiesInGroup(m_DragonChestGroup)) { + for (auto* chest : Game::entityManager->GetEntitiesInGroup(m_DragonChestGroup)) { GameMessages::SendNotifyClientObject(chest->GetObjectID(), m_ShowChestNotification, 1, -1, target->GetObjectID(), "", target->GetSystemAddress()); } auto playerID = target->GetObjectID(); self->AddCallbackTimer(5.0f, [this, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return; // Stop the dragon effects - for (auto* dragon : EntityManager::Instance()->GetEntitiesInGroup(m_DragonStatueGroup)) { + for (auto* dragon : Game::entityManager->GetEntitiesInGroup(m_DragonStatueGroup)) { GameMessages::SendStopFXEffect(dragon, true, "on"); } }); diff --git a/dScripts/02_server/Map/njhub/RainOfArrows.cpp b/dScripts/02_server/Map/njhub/RainOfArrows.cpp index b7c4c074..8a8f9c50 100644 --- a/dScripts/02_server/Map/njhub/RainOfArrows.cpp +++ b/dScripts/02_server/Map/njhub/RainOfArrows.cpp @@ -18,9 +18,9 @@ void RainOfArrows::OnRebuildComplete(Entity* self, Entity* target) { info.rot = myRot; info.spawnerID = self->GetObjectID(); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); self->SetVar(u"ChildFX", entity->GetObjectID()); self->SetVar(u"playerID", target->GetObjectID()); @@ -30,11 +30,11 @@ void RainOfArrows::OnRebuildComplete(Entity* self, Entity* target) { } void RainOfArrows::OnTimerDone(Entity* self, std::string timerName) { - auto* child = EntityManager::Instance()->GetEntity( + auto* child = Game::entityManager->GetEntity( self->GetVar(u"ChildFX") ); - auto* player = EntityManager::Instance()->GetEntity( + auto* player = Game::entityManager->GetEntity( self->GetVar(u"playerID") ); diff --git a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp index 9f129ce3..459d3e25 100644 --- a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp +++ b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp @@ -122,7 +122,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string if (timerName == WaitingForPlayersTimer) { StartFight(self); } else if (timerName == SpawnNextWaveTimer) { - auto* frakjaw = EntityManager::Instance()->GetEntity(self->GetVar(LedgeFrakjawVariable)); + auto* frakjaw = Game::entityManager->GetEntity(self->GetVar(LedgeFrakjawVariable)); if (frakjaw != nullptr) { SummonWave(self, frakjaw); } @@ -145,7 +145,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string } } } else if (timerName + TimerSplitChar == UnstunTimer) { - auto* entity = EntityManager::Instance()->GetEntity(objectID); + auto* entity = Game::entityManager->GetEntity(objectID); if (entity != nullptr) { auto* combatAI = entity->GetComponent(); if (combatAI != nullptr) { @@ -164,7 +164,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string } } else if (timerName == LowerFrakjawCamTimer) { // Destroy the frakjaw on the ledge - auto* ledgeFrakjaw = EntityManager::Instance()->GetEntity(self->GetVar(LedgeFrakjawVariable)); + auto* ledgeFrakjaw = Game::entityManager->GetEntity(self->GetVar(LedgeFrakjawVariable)); if (ledgeFrakjaw != nullptr) { ledgeFrakjaw->Kill(); } @@ -188,7 +188,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string spawner->Activate(); } } else if (timerName + TimerSplitChar == FrakjawSpawnInTimer) { - auto* lowerFrakjaw = EntityManager::Instance()->GetEntity(objectID); + auto* lowerFrakjaw = Game::entityManager->GetEntity(objectID); if (lowerFrakjaw != nullptr) { LowerFrakjawSummon(self, lowerFrakjaw); } @@ -250,7 +250,7 @@ void NjMonastryBossInstance::HandleCounterWeightSpawned(Entity* self, Entity* co counterWeight->Kill(); } - auto* frakjaw = EntityManager::Instance()->GetEntity(self->GetVar(LedgeFrakjawVariable)); + auto* frakjaw = Game::entityManager->GetEntity(self->GetVar(LedgeFrakjawVariable)); if (frakjaw == nullptr) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"LedgeFrakjawDead", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); @@ -342,7 +342,7 @@ void NjMonastryBossInstance::HandleLowerFrakjawHit(Entity* self, Entity* lowerFr std::vector newTrashMobs = {}; for (const auto& trashMobID : trashMobsAlive) { - auto* trashMob = EntityManager::Instance()->GetEntity(trashMobID); + auto* trashMob = Game::entityManager->GetEntity(trashMobID); if (trashMob != nullptr) { newTrashMobs.push_back(trashMobID); @@ -393,7 +393,7 @@ void NjMonastryBossInstance::HandleWaveEnemyDied(Entity* self, Entity* waveEnemy } void NjMonastryBossInstance::TeleportPlayer(Entity* player, uint32_t position) { - for (const auto* spawnPoint : EntityManager::Instance()->GetEntitiesInGroup("SpawnPoint" + std::to_string(position))) { + for (const auto* spawnPoint : Game::entityManager->GetEntitiesInGroup("SpawnPoint" + std::to_string(position))) { GameMessages::SendTeleport(player->GetObjectID(), spawnPoint->GetPosition(), spawnPoint->GetRotation(), player->GetSystemAddress(), true); } @@ -433,7 +433,7 @@ void NjMonastryBossInstance::RemovePoison(Entity* self) { const auto& totalPlayer = self->GetVar>(TotalPlayersLoadedVariable); for (const auto& playerID : totalPlayer) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { auto* buffComponent = player->GetComponent(); @@ -505,7 +505,7 @@ void NjMonastryBossInstance::FightOver(Entity* self) { GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, TreasureChestSpawning, UNASSIGNED_SYSTEM_ADDRESS); - auto treasureChests = EntityManager::Instance()->GetEntitiesInGroup(ChestSpawnpointGroup); + auto treasureChests = Game::entityManager->GetEntitiesInGroup(ChestSpawnpointGroup); for (auto* treasureChest : treasureChests) { auto info = EntityInfo{}; @@ -518,7 +518,7 @@ void NjMonastryBossInstance::FightOver(Entity* self) { }; // Finally spawn a treasure chest at the correct spawn point - auto* chestObject = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(chestObject); + auto* chestObject = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(chestObject); } } diff --git a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp index 7df8fc12..83f8b30d 100644 --- a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp +++ b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp @@ -21,7 +21,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) { uint32_t activityRating = 0; if (team != nullptr) { for (const auto& teamMemberID : team->members) { - auto* teamMember = EntityManager::Instance()->GetEntity(teamMemberID); + auto* teamMember = Game::entityManager->GetEntity(teamMemberID); if (teamMember != nullptr) { activityRating = CalculateActivityRating(self, teamMemberID); diff --git a/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp b/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp index 4d3482c4..2ce44bd1 100644 --- a/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp +++ b/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp @@ -53,7 +53,7 @@ void AgSurvivalBuffStation::OnTimerDone(Entity* self, std::string timerName) { } auto team = self->GetVar>(u"BuilderTeam"); for (auto memberID : team) { - auto member = EntityManager::Instance()->GetEntity(memberID); + auto member = Game::entityManager->GetEntity(memberID); if (member != nullptr && !member->GetIsDead()) { GameMessages::SendDropClientLoot(member, self->GetObjectID(), powerupToDrop, 0, self->GetPosition()); } else { diff --git a/dScripts/02_server/Objects/StinkyFishTarget.cpp b/dScripts/02_server/Objects/StinkyFishTarget.cpp index 459e0bbe..9840235d 100644 --- a/dScripts/02_server/Objects/StinkyFishTarget.cpp +++ b/dScripts/02_server/Objects/StinkyFishTarget.cpp @@ -25,8 +25,8 @@ void StinkyFishTarget::OnSkillEventFired(Entity* self, Entity* caster, const std new LDFData(u"no_timed_spawn", true) }; - auto* fish = EntityManager::Instance()->CreateEntity(entityInfo); - EntityManager::Instance()->ConstructEntity(fish); + auto* fish = Game::entityManager->CreateEntity(entityInfo); + Game::entityManager->ConstructEntity(fish); self->SetVar(u"fish", fish->GetObjectID()); self->AddTimer("smash", 5.0f); @@ -35,7 +35,7 @@ void StinkyFishTarget::OnSkillEventFired(Entity* self, Entity* caster, const std void StinkyFishTarget::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "smash") { const auto playerID = self->GetVar(u"player"); - auto* fish = EntityManager::Instance()->GetEntity(self->GetVar(u"fish")); + auto* fish = Game::entityManager->GetEntity(self->GetVar(u"fish")); if (fish) { fish->Smash(playerID); diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 078a7a02..d15ad851 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -20,7 +20,7 @@ void ActivityManager::UpdatePlayer(Entity* self, LWOOBJID playerID, const bool r if (remove) { sac->PlayerRemove(playerID); } else { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { sac->PlayerJoin(player); SetActivityScore(self, playerID, 0); @@ -63,7 +63,7 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const if (quit) { UpdatePlayer(self, playerID, true); } else { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return; @@ -96,7 +96,7 @@ bool ActivityManager::TakeActivityCost(const Entity* self, const LWOOBJID player if (sac == nullptr) return false; - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return false; diff --git a/dScripts/BaseConsoleTeleportServer.cpp b/dScripts/BaseConsoleTeleportServer.cpp index e04500b5..27d2bcfc 100644 --- a/dScripts/BaseConsoleTeleportServer.cpp +++ b/dScripts/BaseConsoleTeleportServer.cpp @@ -45,7 +45,7 @@ void BaseConsoleTeleportServer::BaseOnMessageBoxResponse(Entity* self, Entity* s const auto playerID = player->GetObjectID(); self->AddCallbackTimer(animTime, [playerID, self]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index 72cce09f..579ae87a 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -49,7 +49,7 @@ void BasePropertyServer::SetGameVariables(Entity* self) { } void BasePropertyServer::CheckForOwner(Entity* self) { - if (EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(PropertyPlaqueGroup)).empty()) { + if (Game::entityManager->GetEntitiesInGroup(self->GetVar(PropertyPlaqueGroup)).empty()) { self->AddTimer(RunPlayerLoadedAgainTimer, 0.5f); return; } @@ -87,9 +87,9 @@ void BasePropertyServer::BasePlayerLoaded(Entity* self, Entity* player) { self->SetNetworkVar(PropertyOwnerIDVariable, propertyOwner); if (rented) { - auto plaques = EntityManager::Instance()->GetEntitiesInGroup("PropertyVendor"); + auto plaques = Game::entityManager->GetEntitiesInGroup("PropertyVendor"); for (auto* plaque : plaques) { - EntityManager::Instance()->DestructEntity(plaque); + Game::entityManager->DestructEntity(plaque); } const auto& mapID = dZoneManager::Instance()->GetZone()->GetZoneID(); @@ -164,9 +164,9 @@ void BasePropertyServer::BaseZonePropertyRented(Entity* self, Entity* player) co self->AddTimer(BoundsVisOnTimer, 2); self->SetVar(PropertyOwnerVariable, player->GetObjectID()); - auto plaques = EntityManager::Instance()->GetEntitiesInGroup("PropertyVendor"); + auto plaques = Game::entityManager->GetEntitiesInGroup("PropertyVendor"); for (auto* plaque : plaques) { - EntityManager::Instance()->DestructEntity(plaque); + Game::entityManager->DestructEntity(plaque); } auto brickLinkMissionID = self->GetVar(brickLinkMissionIDFlag); @@ -234,7 +234,7 @@ void BasePropertyServer::StartMaelstrom(Entity* self, Entity* player) { } void BasePropertyServer::StartTornadoFx(Entity* self) const { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); if (entities.empty()) { self->AddTimer("pollTornadoFX", 0.1f); return; @@ -259,7 +259,7 @@ void BasePropertyServer::BasePlayerExit(Entity* self, Entity* player) { } void BasePropertyServer::KillGuard(Entity* self) { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GuardGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(GuardGroup)); if (entities.empty()) return; @@ -328,12 +328,12 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam if (dZoneManager::Instance()->GetZoneID().GetMapID() == 1150) return; - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GuardGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(GuardGroup)); if (entities.empty()) return; auto* guard = entities[0]; - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"GuardChat", 0, 0, guard->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); @@ -341,7 +341,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam } else if (timerName == KillGuardTimer) { KillGuard(self); } else if (timerName == TornadoOffTimer) { - auto fxManagers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + auto fxManagers = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); for (auto* fxManager : fxManagers) { auto* renderComponent = fxManager->GetComponent(); @@ -354,7 +354,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam self->AddTimer(ShowClearEffectsTimer, 2); } else if (timerName == ShowClearEffectsTimer) { - auto fxManagers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + auto fxManagers = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); for (auto* fxManager : fxManagers) { auto* renderComponent = fxManager->GetComponent(); @@ -370,7 +370,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam GameMessages::SendNotifyClientObject(controller->GetObjectID(), u"SkyOff", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); } else if (timerName == KillStrombiesTimer) { - const auto enemies = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(EnemiesGroup)); + const auto enemies = Game::entityManager->GetEntitiesInGroup(self->GetVar(EnemiesGroup)); for (auto* enemy : enemies) { RequestDie(self, enemy); } @@ -378,7 +378,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam DestroySpawner(self->GetVar(SmashablesSpawner)); KillSpots(self); - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) return; @@ -393,7 +393,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam DestroySpawner(behaviorObjectSpawner); } - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(ImagOrbGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(ImagOrbGroup))) { entity->Smash(); } @@ -401,7 +401,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam self->AddTimer(ShowVendorTimer, 1.0f); } else if (timerName == ShowVendorTimer) { - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"vendorOn", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); @@ -416,7 +416,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam } else if (timerName == PollTornadoFXTimer) { StartTornadoFx(self); } else if (timerName == KillFXObjectTimer) { - const auto fxManagers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + const auto fxManagers = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); if (fxManagers.empty()) { self->AddTimer(KillFXObjectTimer, 1.0f); return; @@ -436,7 +436,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam void BasePropertyServer::HandleOrbsTimer(Entity* self) { self->SetVar(CollidedVariable, false); - auto orbs = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(ImagOrbGroup)); + auto orbs = Game::entityManager->GetEntitiesInGroup(self->GetVar(ImagOrbGroup)); if (orbs.empty()) { self->AddTimer(StartOrbTimer, 0.5f); return; @@ -455,12 +455,12 @@ void BasePropertyServer::HandleOrbsTimer(Entity* self) { } DestroySpawner(self->GetVar(GeneratorFXSpawner)); - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"PlayCinematic", 0, 0, LWOOBJID_EMPTY, "DestroyMaelstrom", UNASSIGNED_SYSTEM_ADDRESS); // Notifies the client that the property has been claimed with a flag, completes missions too - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { auto* character = player->GetCharacter(); if (character != nullptr) { @@ -476,7 +476,7 @@ void BasePropertyServer::HandleOrbsTimer(Entity* self) { } void BasePropertyServer::HandleGeneratorTimer(Entity* self) { - auto generators = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GeneratorGroup)); + auto generators = Game::entityManager->GetEntitiesInGroup(self->GetVar(GeneratorGroup)); if (generators.empty()) { self->AddTimer(StartGeneratorTimer, 0.5f); return; @@ -496,7 +496,7 @@ void BasePropertyServer::HandleGeneratorTimer(Entity* self) { } void BasePropertyServer::HandleQuickBuildTimer(Entity* self) { - auto claimMarkers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(ClaimMarkerGroup)); + auto claimMarkers = Game::entityManager->GetEntitiesInGroup(self->GetVar(ClaimMarkerGroup)); if (claimMarkers.empty()) { self->AddTimer(StartQuickbuildTimer, 0.5f); return; diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index 3d72628d..3e32c24b 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -212,7 +212,7 @@ void BaseSurvivalServer::OnActivityTimerDone(Entity* self, const std::string& na ActivityTimerStart(self, PlaySpawnSoundTimer, 3, 3); } else if (name == PlaySpawnSoundTimer) { for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { GameMessages::SendPlayNDAudioEmitter(player, player->GetSystemAddress(), spawnSoundGUID); } @@ -221,7 +221,7 @@ void BaseSurvivalServer::OnActivityTimerDone(Entity* self, const std::string& na } void BaseSurvivalServer::ResetStats(LWOOBJID playerID) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { // Boost all the player stats when loading in @@ -284,7 +284,7 @@ void BaseSurvivalServer::StartWaves(Entity* self) { state.waitingPlayers.clear(); for (const auto& playerID : state.players) { - const auto player = EntityManager::Instance()->GetEntity(playerID); + const auto player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { state.waitingPlayers.push_back(playerID); UpdatePlayer(self, playerID); @@ -311,7 +311,7 @@ bool BaseSurvivalServer::CheckAllPlayersDead() { auto deadPlayers = 0; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr || player->GetIsDead()) { deadPlayers++; } @@ -323,9 +323,9 @@ bool BaseSurvivalServer::CheckAllPlayersDead() { void BaseSurvivalServer::SetPlayerSpawnPoints() { auto spawnerIndex = 1; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { - auto possibleSpawners = EntityManager::Instance()->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); + auto possibleSpawners = Game::entityManager->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); if (!possibleSpawners.empty()) { auto* spawner = possibleSpawners.at(0); GameMessages::SendTeleport(playerID, spawner->GetPosition(), spawner->GetRotation(), player->GetSystemAddress(), true); @@ -348,7 +348,7 @@ void BaseSurvivalServer::GameOver(Entity* self) { SpawnerReset(spawnerNetworks.rewardNetworks); for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) continue; diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 00340bd0..fcaa548e 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -195,7 +195,7 @@ void BaseWavesServer::OnActivityTimerDone(Entity* self, const std::string& name) ActivityTimerStart(self, PlaySpawnSoundTimer, 3, 3); } else if (name == PlaySpawnSoundTimer) { for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { GameMessages::SendPlayNDAudioEmitter(player, player->GetSystemAddress(), spawnSoundGUID); } @@ -216,7 +216,7 @@ void BaseWavesServer::OnActivityTimerDone(Entity* self, const std::string& name) } else if (name == GameOverWinTimer) { GameOver(self, true); } else if (name == CinematicDoneTimer) { - for (auto* boss : EntityManager::Instance()->GetEntitiesInGroup("boss")) { + for (auto* boss : Game::entityManager->GetEntitiesInGroup("boss")) { boss->OnFireEventServerSide(self, "startAI"); } } @@ -224,7 +224,7 @@ void BaseWavesServer::OnActivityTimerDone(Entity* self, const std::string& name) // Done void BaseWavesServer::ResetStats(LWOOBJID playerID) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { // Boost all the player stats when loading in @@ -284,7 +284,7 @@ void BaseWavesServer::StartWaves(Entity* self) { state.waitingPlayers.clear(); for (const auto& playerID : state.players) { - const auto player = EntityManager::Instance()->GetEntity(playerID); + const auto player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { state.waitingPlayers.push_back(playerID); @@ -309,7 +309,7 @@ bool BaseWavesServer::CheckAllPlayersDead() { auto deadPlayers = 0; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr || player->GetIsDead()) { deadPlayers++; } @@ -322,9 +322,9 @@ bool BaseWavesServer::CheckAllPlayersDead() { void BaseWavesServer::SetPlayerSpawnPoints(const LWOOBJID& specificPlayerID) { auto spawnerIndex = 1; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr && (specificPlayerID == LWOOBJID_EMPTY || playerID == specificPlayerID)) { - auto possibleSpawners = EntityManager::Instance()->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); + auto possibleSpawners = Game::entityManager->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); if (!possibleSpawners.empty()) { auto* spawner = possibleSpawners.at(0); GameMessages::SendTeleport(playerID, spawner->GetPosition(), spawner->GetRotation(), player->GetSystemAddress(), true); @@ -353,7 +353,7 @@ void BaseWavesServer::GameOver(Entity* self, bool won) { ClearSpawners(); for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) continue; @@ -429,7 +429,7 @@ void BaseWavesServer::SpawnWave(Entity* self) { } for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player && player->GetIsDead()) { player->Resurrect(); } @@ -471,7 +471,7 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 state.currentSpawned--; - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr && enemy->IsPlayer() && IsPlayerInActivity(self, enemyID)) { SetActivityValue(self, enemyID, 0, GetActivityValue(self, enemyID, 0) + score); } @@ -499,7 +499,7 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 const auto soloWaveMissions = waves.at(completedWave).soloMissions; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr && !player->GetIsDead()) { SetActivityValue(self, playerID, 1, currentTime); SetActivityValue(self, playerID, 2, state.waveNumber); @@ -558,7 +558,7 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 // Done void BaseWavesServer::UpdateMissionForAllPlayers(Entity* self, uint32_t missionID) { for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { auto* missionComponent = player->GetComponent(); if (missionComponent == nullptr) return; diff --git a/dScripts/Darkitect.cpp b/dScripts/Darkitect.cpp index b4364332..2881bde8 100644 --- a/dScripts/Darkitect.cpp +++ b/dScripts/Darkitect.cpp @@ -12,7 +12,7 @@ void Darkitect::Reveal(Entity* self, Entity* player) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"reveal", 0, 0, playerID, "", player->GetSystemAddress()); self->AddCallbackTimer(20, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (!player) return; @@ -29,7 +29,7 @@ void Darkitect::Reveal(Entity* self, Entity* player) { character->SetPlayerFlag(1911, true); } - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(player); } }); } diff --git a/dScripts/EquipmentScripts/PersonalFortress.cpp b/dScripts/EquipmentScripts/PersonalFortress.cpp index f1fe73ee..7e6d3566 100644 --- a/dScripts/EquipmentScripts/PersonalFortress.cpp +++ b/dScripts/EquipmentScripts/PersonalFortress.cpp @@ -26,7 +26,7 @@ void PersonalFortress::OnStartup(Entity* self) { true, true, true, true, true, true, true, true, true ); - EntityManager::Instance()->SerializeEntity(owner); + Game::entityManager->SerializeEntity(owner); } void PersonalFortress::OnDie(Entity* self, Entity* killer) { @@ -47,7 +47,7 @@ void PersonalFortress::OnDie(Entity* self, Entity* killer) { true, true, true, true, true, true, true, true, true ); - EntityManager::Instance()->SerializeEntity(owner); + Game::entityManager->SerializeEntity(owner); } void PersonalFortress::OnTimerDone(Entity* self, std::string timerName) { diff --git a/dScripts/ScriptedPowerupSpawner.cpp b/dScripts/ScriptedPowerupSpawner.cpp index 3c1d1cca..2c502f26 100644 --- a/dScripts/ScriptedPowerupSpawner.cpp +++ b/dScripts/ScriptedPowerupSpawner.cpp @@ -21,7 +21,7 @@ void ScriptedPowerupSpawner::OnTimerDone(Entity* self, std::string message) { drops.emplace(itemLOT, 1); // Spawn the required number of powerups - auto* owner = EntityManager::Instance()->GetEntity(self->GetSpawnerID()); + auto* owner = Game::entityManager->GetEntity(self->GetSpawnerID()); if (owner != nullptr) { auto* renderComponent = self->GetComponent(); for (auto i = 0; i < self->GetVar(u"numberOfPowerups"); i++) { diff --git a/dScripts/SpawnPetBaseServer.cpp b/dScripts/SpawnPetBaseServer.cpp index 75b46382..395a20c2 100644 --- a/dScripts/SpawnPetBaseServer.cpp +++ b/dScripts/SpawnPetBaseServer.cpp @@ -11,7 +11,7 @@ void SpawnPetBaseServer::OnStartup(Entity* self) { } void SpawnPetBaseServer::OnUse(Entity* self, Entity* user) { - auto possibleSpawners = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(u"petType") + "Spawner"); + auto possibleSpawners = Game::entityManager->GetEntitiesInGroup(self->GetVar(u"petType") + "Spawner"); if (possibleSpawners.empty()) return; @@ -33,8 +33,8 @@ void SpawnPetBaseServer::OnUse(Entity* self, Entity* user) { new LDFData(u"spawnTimer", 1.0f) }; - auto* pet = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(pet); + auto* pet = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(pet); self->SetVar(u"spawnedPets", self->GetVar(u"spawnedPets") + "," + std::to_string(pet->GetObjectID())); @@ -57,7 +57,7 @@ bool SpawnPetBaseServer::CheckNumberOfPets(Entity* self, Entity* user) { if (petID.empty()) continue; - const auto* spawnedPet = EntityManager::Instance()->GetEntity(std::stoull(petID)); + const auto* spawnedPet = Game::entityManager->GetEntity(std::stoull(petID)); if (spawnedPet == nullptr) continue; diff --git a/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp b/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp index 76c0289e..595da4db 100644 --- a/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp +++ b/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp @@ -14,7 +14,7 @@ void ActVehicleDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { Entity* player; if (possessableComponent != nullptr) { - auto* player = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* player = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (player == nullptr) { return; @@ -28,7 +28,7 @@ void ActVehicleDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { return; } - vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) { return; diff --git a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp index 769a8fd9..45b2da05 100644 --- a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp +++ b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp @@ -11,7 +11,7 @@ void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, st if (splitArguments.size() > 1) { const auto eventName = splitArguments[0]; - const auto player = EntityManager::Instance()->GetEntity(std::stoull(splitArguments[1])); + const auto player = Game::entityManager->GetEntity(std::stoull(splitArguments[1])); if (player != nullptr) { if (eventName == "updatePlayer") { diff --git a/dScripts/ai/AG/AgBusDoor.cpp b/dScripts/ai/AG/AgBusDoor.cpp index 4910d0c5..fd6c272e 100644 --- a/dScripts/ai/AG/AgBusDoor.cpp +++ b/dScripts/ai/AG/AgBusDoor.cpp @@ -24,12 +24,12 @@ void AgBusDoor::OnProximityUpdate(Entity* self, Entity* entering, std::string na m_OuterCounter = 0; for (const auto& pair : proximityMonitorComponent->GetProximityObjects("busDoor")) { - auto* entity = EntityManager::Instance()->GetEntity(pair.first); + auto* entity = Game::entityManager->GetEntity(pair.first); if (entity != nullptr && entity->IsPlayer()) m_Counter++; } for (const auto& pair : proximityMonitorComponent->GetProximityObjects("busDoorOuter")) { - auto* entity = EntityManager::Instance()->GetEntity(pair.first); + auto* entity = Game::entityManager->GetEntity(pair.first); if (entity != nullptr && entity->IsPlayer()) m_OuterCounter++; } diff --git a/dScripts/ai/AG/AgFans.cpp b/dScripts/ai/AG/AgFans.cpp index aaff9c0d..15f2ed0f 100644 --- a/dScripts/ai/AG/AgFans.cpp +++ b/dScripts/ai/AG/AgFans.cpp @@ -25,7 +25,7 @@ void AgFans::OnStartup(Entity* self) { void AgFans::ToggleFX(Entity* self, bool hit) { std::string fanGroup = self->GetGroups()[0]; - std::vector fanVolumes = EntityManager::Instance()->GetEntitiesInGroup(fanGroup); + std::vector fanVolumes = Game::entityManager->GetEntitiesInGroup(fanGroup); auto* renderComponent = static_cast(self->GetComponent(eReplicaComponentType::RENDER)); @@ -45,9 +45,9 @@ void AgFans::ToggleFX(Entity* self, bool hit) { PhantomPhysicsComponent* volumePhys = static_cast(volume->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(false); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); if (!hit) { - Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0]; + Entity* fxObj = Game::entityManager->GetEntitiesInGroup(fanGroup + "fx")[0]; RenderComponent::PlayAnimation(fxObj, u"trigger"); } } @@ -61,9 +61,9 @@ void AgFans::ToggleFX(Entity* self, bool hit) { PhantomPhysicsComponent* volumePhys = static_cast(volume->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); if (!hit) { - Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0]; + Entity* fxObj = Game::entityManager->GetEntitiesInGroup(fanGroup + "fx")[0]; RenderComponent::PlayAnimation(fxObj, u"idle"); } } diff --git a/dScripts/ai/AG/AgImagSmashable.cpp b/dScripts/ai/AG/AgImagSmashable.cpp index 5e8331b1..2a35ed9a 100644 --- a/dScripts/ai/AG/AgImagSmashable.cpp +++ b/dScripts/ai/AG/AgImagSmashable.cpp @@ -36,9 +36,9 @@ void AgImagSmashable::CrateAnimal(Entity* self) { info.spawnerID = self->GetSpawnerID(); info.spawnerNodeID = 0; - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); } } } diff --git a/dScripts/ai/AG/AgJetEffectServer.cpp b/dScripts/ai/AG/AgJetEffectServer.cpp index 0a26069e..5d25c9e0 100644 --- a/dScripts/ai/AG/AgJetEffectServer.cpp +++ b/dScripts/ai/AG/AgJetEffectServer.cpp @@ -12,7 +12,7 @@ void AgJetEffectServer::OnUse(Entity* self, Entity* user) { ); inUse = true; - auto entities = EntityManager::Instance()->GetEntitiesInGroup("Jet_FX"); + auto entities = Game::entityManager->GetEntitiesInGroup("Jet_FX"); if (entities.empty()) return; GameMessages::SendPlayFXEffect(entities.at(0), 641, u"create", "radarDish", LWOOBJID_EMPTY, 1, 1, true); self->AddTimer("radarDish", 2.0f); @@ -22,7 +22,7 @@ void AgJetEffectServer::OnUse(Entity* self, Entity* user) { void AgJetEffectServer::OnRebuildComplete(Entity* self, Entity* target) { if (self->GetLOT() != 6209) return; - auto entities = EntityManager::Instance()->GetEntitiesInGroup("Jet_FX"); + auto entities = Game::entityManager->GetEntitiesInGroup("Jet_FX"); if (entities.empty()) return; RenderComponent::PlayAnimation(entities.at(0), u"jetFX"); @@ -40,7 +40,7 @@ void AgJetEffectServer::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "radarDish") { GameMessages::SendStopFXEffect(self, true, "radarDish"); } else if (timerName == "PlayEffect") { - auto entities = EntityManager::Instance()->GetEntitiesInGroup("mortarMain"); + auto entities = Game::entityManager->GetEntitiesInGroup("mortarMain"); if (entities.empty()) return; const auto selected = GeneralUtils::GenerateRandomNumber(0, entities.size() - 1); diff --git a/dScripts/ai/AG/AgQbElevator.cpp b/dScripts/ai/AG/AgQbElevator.cpp index e1d78a21..5a535347 100644 --- a/dScripts/ai/AG/AgQbElevator.cpp +++ b/dScripts/ai/AG/AgQbElevator.cpp @@ -26,7 +26,7 @@ void AgQbElevator::OnProximityUpdate(Entity* self, Entity* entering, std::string if (self->GetBoolean(u"qbPlayerRdy")) return; if (status == "ENTER") { - Entity* builder = EntityManager::Instance()->GetEntity(self->GetI64(u"qbPlayer")); + Entity* builder = Game::entityManager->GetEntity(self->GetI64(u"qbPlayer")); if (builder && builder == entering) { //the builder has entered so cancel the start timer and just start moving self->SetBoolean(u"qbPlayerRdy", true); diff --git a/dScripts/ai/AG/AgQbWall.cpp b/dScripts/ai/AG/AgQbWall.cpp index d6222419..3e7d9c2b 100644 --- a/dScripts/ai/AG/AgQbWall.cpp +++ b/dScripts/ai/AG/AgQbWall.cpp @@ -4,7 +4,7 @@ void AgQbWall::OnRebuildComplete(Entity* self, Entity* player) { self->SetVar(u"player", player->GetObjectID()); auto targetWallSpawners = GeneralUtils::UTF16ToWTF8(self->GetVar(u"spawner")); if (targetWallSpawners != "") { - auto groupObjs = EntityManager::Instance()->GetEntitiesInGroup(targetWallSpawners); + auto groupObjs = Game::entityManager->GetEntitiesInGroup(targetWallSpawners); for (auto* obj : groupObjs) { if (obj) { obj->SetVar(u"player", player->GetObjectID()); diff --git a/dScripts/ai/AG/AgSpaceStuff.cpp b/dScripts/ai/AG/AgSpaceStuff.cpp index 0887608e..130d4354 100644 --- a/dScripts/ai/AG/AgSpaceStuff.cpp +++ b/dScripts/ai/AG/AgSpaceStuff.cpp @@ -15,9 +15,9 @@ void AgSpaceStuff::OnStartup(Entity* self) { info.lot = 33; info.spawnerID = self->GetObjectID(); - auto* ref = EntityManager::Instance()->CreateEntity(info); + auto* ref = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(ref); + Game::entityManager->ConstructEntity(ref); self->SetVar(u"ShakeObject", ref->GetObjectID()); @@ -47,7 +47,7 @@ void AgSpaceStuff::OnTimerDone(Entity* self, std::string timerName) { void AgSpaceStuff::DoShake(Entity* self, bool explodeIdle) { if (!explodeIdle) { - auto* ref = EntityManager::Instance()->GetEntity(self->GetVar(u"ShakeObject")); + auto* ref = Game::entityManager->GetEntity(self->GetVar(u"ShakeObject")); const auto randomTime = self->GetVar(u"RandomTime"); auto time = GeneralUtils::GenerateRandomNumber(0, randomTime + 1); @@ -92,7 +92,7 @@ void AgSpaceStuff::DoShake(Entity* self, bool explodeIdle) { } Entity* AgSpaceStuff::GetEntityInGroup(const std::string& group) { - auto entities = EntityManager::Instance()->GetEntitiesInGroup(group); + auto entities = Game::entityManager->GetEntitiesInGroup(group); Entity* en = nullptr; for (auto entity : entities) { diff --git a/dScripts/ai/FV/ActNinjaSensei.cpp b/dScripts/ai/FV/ActNinjaSensei.cpp index 27e42219..6a7dc893 100644 --- a/dScripts/ai/FV/ActNinjaSensei.cpp +++ b/dScripts/ai/FV/ActNinjaSensei.cpp @@ -4,7 +4,7 @@ #include "GameMessages.h" void ActNinjaSensei::OnStartup(Entity* self) { - auto students = EntityManager::Instance()->GetEntitiesInGroup(this->m_StudentGroup); + auto students = Game::entityManager->GetEntitiesInGroup(this->m_StudentGroup); std::vector validStudents = {}; for (auto* student : students) { if (student && student->GetLOT() == this->m_StudentLOT) validStudents.push_back(student); diff --git a/dScripts/ai/FV/ActParadoxPipeFix.cpp b/dScripts/ai/FV/ActParadoxPipeFix.cpp index 10a1e652..aad74dec 100644 --- a/dScripts/ai/FV/ActParadoxPipeFix.cpp +++ b/dScripts/ai/FV/ActParadoxPipeFix.cpp @@ -8,7 +8,7 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { const auto myGroup = "AllPipes"; - const auto groupObjs = EntityManager::Instance()->GetEntitiesInGroup(myGroup); + const auto groupObjs = Game::entityManager->GetEntitiesInGroup(myGroup); auto indexCount = 0; @@ -27,14 +27,14 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { } if (indexCount >= 2) { - const auto refinery = EntityManager::Instance()->GetEntitiesInGroup("Paradox"); + const auto refinery = Game::entityManager->GetEntitiesInGroup("Paradox"); if (!refinery.empty()) { GameMessages::SendPlayFXEffect(refinery[0]->GetObjectID(), 3999, u"create", "pipeFX"); } for (auto* object : groupObjs) { - auto* player = EntityManager::Instance()->GetEntity(object->GetVar(u"PlayerID")); + auto* player = Game::entityManager->GetEntity(object->GetVar(u"PlayerID")); if (player != nullptr) { auto* missionComponent = player->GetComponent(); @@ -53,7 +53,7 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { void ActParadoxPipeFix::OnRebuildNotifyState(Entity* self, eRebuildState state) { if (state == eRebuildState::RESETTING) { - const auto refinery = EntityManager::Instance()->GetEntitiesInGroup("Paradox"); + const auto refinery = Game::entityManager->GetEntitiesInGroup("Paradox"); if (!refinery.empty()) { GameMessages::SendStopFXEffect(refinery[0], true, "pipeFX"); diff --git a/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp b/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp index 3f495ed7..29de1fe5 100644 --- a/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp +++ b/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp @@ -13,7 +13,7 @@ void FvConsoleLeftQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState s if (state == eRebuildState::COMPLETED) { self->SetVar(u"IAmBuilt", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleLeftUp"); @@ -22,7 +22,7 @@ void FvConsoleLeftQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState s self->SetVar(u"IAmBuilt", false); self->SetVar(u"AmActive", false); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleLeftDown"); @@ -38,7 +38,7 @@ void FvConsoleLeftQuickbuild::OnUse(Entity* self, Entity* user) { if (self->GetVar(u"IAmBuilt")) { self->SetVar(u"AmActive", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleLeftActive"); diff --git a/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp b/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp index e03e4135..20194f8d 100644 --- a/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp +++ b/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp @@ -13,7 +13,7 @@ void FvConsoleRightQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState if (state == eRebuildState::COMPLETED) { self->SetVar(u"IAmBuilt", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleRightUp"); @@ -22,7 +22,7 @@ void FvConsoleRightQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState self->SetVar(u"IAmBuilt", false); self->SetVar(u"AmActive", false); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleRightDown"); @@ -38,7 +38,7 @@ void FvConsoleRightQuickbuild::OnUse(Entity* self, Entity* user) { if (self->GetVar(u"IAmBuilt")) { self->SetVar(u"AmActive", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleRightActive"); diff --git a/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp b/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp index 8f2133a9..3f3121ef 100644 --- a/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp +++ b/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp @@ -21,7 +21,7 @@ void FvDragonSmashingGolemQb::OnRebuildNotifyState(Entity* self, eRebuildState s const auto dragonId = self->GetVar(u"Dragon"); - auto* dragon = EntityManager::Instance()->GetEntity(dragonId); + auto* dragon = Game::entityManager->GetEntity(dragonId); if (dragon != nullptr) { dragon->OnFireEventServerSide(self, "rebuildDone"); diff --git a/dScripts/ai/FV/FvFacilityBrick.cpp b/dScripts/ai/FV/FvFacilityBrick.cpp index 6ff12750..d1014ed6 100644 --- a/dScripts/ai/FV/FvFacilityBrick.cpp +++ b/dScripts/ai/FV/FvFacilityBrick.cpp @@ -46,14 +46,14 @@ void FvFacilityBrick::OnNotifyObject(Entity* self, Entity* sender, const std::st } if (self->GetVar(u"ConsoleLEFTActive") && self->GetVar(u"ConsoleRIGHTActive")) { - auto* object = EntityManager::Instance()->GetEntitiesInGroup("Brick")[0]; + auto* object = Game::entityManager->GetEntitiesInGroup("Brick")[0]; if (object != nullptr) { GameMessages::SendPlayFXEffect(object->GetObjectID(), 122, u"create", "bluebrick"); GameMessages::SendPlayFXEffect(object->GetObjectID(), 1034, u"cast", "imaginationexplosion"); } - object = EntityManager::Instance()->GetEntitiesInGroup("Canister")[0]; + object = Game::entityManager->GetEntitiesInGroup("Canister")[0]; if (object != nullptr) { object->Smash(self->GetObjectID(), eKillType::SILENT); @@ -64,7 +64,7 @@ void FvFacilityBrick::OnNotifyObject(Entity* self, Entity* sender, const std::st } else if (self->GetVar(u"ConsoleLEFTActive") || self->GetVar(u"ConsoleRIGHTActive")) { brickSpawner->Activate(); - auto* object = EntityManager::Instance()->GetEntitiesInGroup("Brick")[0]; + auto* object = Game::entityManager->GetEntitiesInGroup("Brick")[0]; if (object != nullptr) { GameMessages::SendStopFXEffect(object, true, "bluebrick"); diff --git a/dScripts/ai/FV/FvFlyingCreviceDragon.cpp b/dScripts/ai/FV/FvFlyingCreviceDragon.cpp index cb0fe3d0..c8ef9ab5 100644 --- a/dScripts/ai/FV/FvFlyingCreviceDragon.cpp +++ b/dScripts/ai/FV/FvFlyingCreviceDragon.cpp @@ -34,7 +34,7 @@ void FvFlyingCreviceDragon::OnTimerDone(Entity* self, std::string timerName) { groupName = "dragonFireballs3"; } - const auto& group = EntityManager::Instance()->GetEntitiesInGroup(groupName); + const auto& group = Game::entityManager->GetEntitiesInGroup(groupName); if (group.empty()) { return; @@ -73,7 +73,7 @@ void FvFlyingCreviceDragon::OnArrived(Entity* self) { } else if (point == 12) { RenderComponent::PlayAnimation(self, u"attack2", 2.0f); - const auto& group2 = EntityManager::Instance()->GetEntitiesInGroup("dragonFireballs2"); + const auto& group2 = Game::entityManager->GetEntitiesInGroup("dragonFireballs2"); if (group2.empty()) { return; diff --git a/dScripts/ai/FV/FvNinjaGuard.cpp b/dScripts/ai/FV/FvNinjaGuard.cpp index c487f5cc..c087c6df 100644 --- a/dScripts/ai/FV/FvNinjaGuard.cpp +++ b/dScripts/ai/FV/FvNinjaGuard.cpp @@ -22,13 +22,13 @@ void FvNinjaGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* ta RenderComponent::PlayAnimation(self, u"scared"); if (self->GetLOT() == 7412) { - auto* rightGuard = EntityManager::Instance()->GetEntity(m_RightGuard); + auto* rightGuard = Game::entityManager->GetEntity(m_RightGuard); if (rightGuard != nullptr) { RenderComponent::PlayAnimation(rightGuard, u"laugh_rt"); } } else if (self->GetLOT() == 11128) { - auto* leftGuard = EntityManager::Instance()->GetEntity(m_LeftGuard); + auto* leftGuard = Game::entityManager->GetEntity(m_LeftGuard); if (leftGuard != nullptr) { RenderComponent::PlayAnimation(leftGuard, u"laugh_lt"); diff --git a/dScripts/ai/FV/FvPandaSpawnerServer.cpp b/dScripts/ai/FV/FvPandaSpawnerServer.cpp index d7dcabcd..bc9f1c8a 100644 --- a/dScripts/ai/FV/FvPandaSpawnerServer.cpp +++ b/dScripts/ai/FV/FvPandaSpawnerServer.cpp @@ -9,7 +9,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { auto* character = target->GetCharacter(); if (character != nullptr && character->GetPlayerFlag(81)) { - auto raceObjects = EntityManager::Instance()->GetEntitiesInGroup("PandaRaceObject"); + auto raceObjects = Game::entityManager->GetEntitiesInGroup("PandaRaceObject"); if (raceObjects.empty()) return; @@ -19,7 +19,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { return; // If the player already spawned a panda - auto playerPandas = EntityManager::Instance()->GetEntitiesInGroup("panda" + std::to_string(target->GetObjectID())); + auto playerPandas = Game::entityManager->GetEntitiesInGroup("panda" + std::to_string(target->GetObjectID())); if (!playerPandas.empty()) { GameMessages::SendFireEventClientSide(self->GetObjectID(), target->GetSystemAddress(), u"playerPanda", target->GetObjectID(), 0, 0, target->GetObjectID()); @@ -27,7 +27,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { } // If there's already too many spawned pandas - auto pandas = EntityManager::Instance()->GetEntitiesInGroup("pandas"); + auto pandas = Game::entityManager->GetEntitiesInGroup("pandas"); if (pandas.size() > 4) { GameMessages::SendFireEventClientSide(self->GetObjectID(), target->GetSystemAddress(), u"tooManyPandas", target->GetObjectID(), 0, 0, target->GetObjectID()); @@ -43,7 +43,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { new LDFData(u"groupID", u"panda" + (GeneralUtils::to_u16string(target->GetObjectID())) + u";pandas") }; - auto* panda = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(panda); + auto* panda = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(panda); } } diff --git a/dScripts/ai/GF/GfBanana.cpp b/dScripts/ai/GF/GfBanana.cpp index 95a831cd..6bc5c179 100644 --- a/dScripts/ai/GF/GfBanana.cpp +++ b/dScripts/ai/GF/GfBanana.cpp @@ -20,9 +20,9 @@ void GfBanana::SpawnBanana(Entity* self) { info.lot = 6909; info.spawnerID = self->GetObjectID(); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); self->SetVar(u"banana", entity->GetObjectID()); @@ -46,7 +46,7 @@ void GfBanana::OnHit(Entity* self, Entity* attacker) { if (bananaId == LWOOBJID_EMPTY) return; - auto* bananaEntity = EntityManager::Instance()->GetEntity(bananaId); + auto* bananaEntity = Game::entityManager->GetEntity(bananaId); if (bananaEntity == nullptr) { self->SetVar(u"banana", LWOOBJID_EMPTY); @@ -79,12 +79,12 @@ void GfBanana::OnHit(Entity* self, Entity* attacker) { info.lot = 6718; info.spawnerID = self->GetObjectID(); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity, UNASSIGNED_SYSTEM_ADDRESS); + Game::entityManager->ConstructEntity(entity, UNASSIGNED_SYSTEM_ADDRESS); */ - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } void GfBanana::OnTimerDone(Entity* self, std::string timerName) { diff --git a/dScripts/ai/GF/GfCampfire.cpp b/dScripts/ai/GF/GfCampfire.cpp index 6a10b39e..aa03da89 100644 --- a/dScripts/ai/GF/GfCampfire.cpp +++ b/dScripts/ai/GF/GfCampfire.cpp @@ -83,7 +83,7 @@ void GfCampfire::OnTimerDone(Entity* self, std::string timerName) { const auto targetId = self->GetVar("target"); - auto* entering = EntityManager::Instance()->GetEntity(targetId); + auto* entering = Game::entityManager->GetEntity(targetId); if (entering == nullptr) { diff --git a/dScripts/ai/GF/PetDigBuild.cpp b/dScripts/ai/GF/PetDigBuild.cpp index 504a1199..9732e56b 100644 --- a/dScripts/ai/GF/PetDigBuild.cpp +++ b/dScripts/ai/GF/PetDigBuild.cpp @@ -30,8 +30,8 @@ void PetDigBuild::OnRebuildComplete(Entity* self, Entity* target) { } } - auto* treasure = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(treasure); + auto* treasure = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(treasure); self->SetVar(u"chestObj", treasure->GetObjectID()); } @@ -40,7 +40,7 @@ void PetDigBuild::OnDie(Entity* self, Entity* killer) { if (treasureID == LWOOBJID_EMPTY) return; - auto treasure = EntityManager::Instance()->GetEntity(treasureID); + auto treasure = Game::entityManager->GetEntity(treasureID); if (treasure == nullptr) return; diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 9543504a..4121bfdf 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -78,7 +78,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int const std::u16string& stringValue) { Game::logger->Log("SGCannon", "Got activity state change request: %s", GeneralUtils::UTF16ToWTF8(stringValue).c_str()); if (stringValue == u"clientready") { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { Game::logger->Log("SGCannon", "Player is ready"); /*GameMessages::SendSetStunned(player->GetObjectID(), eStateChangeType::PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, @@ -95,7 +95,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int Game::logger->Log("SGCannon", "Setting player ID"); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else { Game::logger->Log("SGCannon", "Shooting gallery component is null"); } @@ -111,7 +111,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int possessor->SetPossessableType(ePossessionType::NO_POSSESSION); } - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(player); } self->SetNetworkVar(HideScoreBoardVariable, true); @@ -137,7 +137,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int } void SGCannon::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (!player) return; if (identifier == u"Scoreboardinfo") { @@ -193,7 +193,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { ActivityTimerStart(self, EndWaveTimer, timeLimit, timeLimit); } - const auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + const auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { GameMessages::SendPlayFXEffect(player->GetObjectID(), -1, u"SG-start", ""); @@ -234,13 +234,13 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { PauseChargeCannon(self); } } else if (name == GameOverTimer) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { Game::logger->Log("SGCannon", "Sending ActivityPause true"); GameMessages::SendActivityPause(self->GetObjectID(), true, player->GetSystemAddress()); - /*const auto leftoverCannonballs = EntityManager::Instance()->GetEntitiesInGroup("cannonball"); + /*const auto leftoverCannonballs = Game::entityManager->GetEntitiesInGroup("cannonball"); if (leftoverCannonballs.empty()) { RecordPlayerScore(self); @@ -284,8 +284,8 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { Game::logger->Log("SGCannon", "Spawning enemy %i on path %s", toSpawn.lot, path->pathName.c_str()); - auto* enemy = EntityManager::Instance()->CreateEntity(info, nullptr, self); - EntityManager::Instance()->ConstructEntity(enemy); + auto* enemy = Game::entityManager->CreateEntity(info, nullptr, self); + Game::entityManager->ConstructEntity(enemy); auto* movementAI = new MovementAIComponent(enemy, {}); @@ -334,12 +334,12 @@ void SGCannon::StartGame(Entity* self) { self->SetNetworkVar(AudioStartIntroVariable, true); self->SetVar(CurrentRewardVariable, LOT_NULL); - auto rewardObjects = EntityManager::Instance()->GetEntitiesInGroup(constants.rewardModelGroup); + auto rewardObjects = Game::entityManager->GetEntitiesInGroup(constants.rewardModelGroup); for (auto* reward : rewardObjects) { reward->OnFireEventServerSide(self, ModelToBuildEvent); } - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { GetLeaderboardData(self, player->GetObjectID(), GetActivityID(self)); Game::logger->Log("SGCannon", "Sending ActivityStart"); @@ -384,9 +384,9 @@ void SGCannon::SpawnNewModel(Entity* self) { self->SetNetworkVar(RewardAddedVariable, currentReward); } - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { - for (auto* rewardModel : EntityManager::Instance()->GetEntitiesInGroup(constants.rewardModelGroup)) { + for (auto* rewardModel : Game::entityManager->GetEntitiesInGroup(constants.rewardModelGroup)) { uint32_t lootMatrix; switch (self->GetVar(MatrixVariable)) { case 1: @@ -422,7 +422,7 @@ void SGCannon::SpawnNewModel(Entity* self) { } void SGCannon::RemovePlayer(LWOOBJID playerID) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return; @@ -508,7 +508,7 @@ void SGCannon::RecordPlayerScore(Entity* self) { } void SGCannon::PlaySceneAnimation(Entity* self, const std::u16string& animationName, bool onCannon, bool onPlayer, float_t priority) { - for (auto* cannon : EntityManager::Instance()->GetEntitiesInGroup("cannongroup")) { + for (auto* cannon : Game::entityManager->GetEntitiesInGroup("cannongroup")) { RenderComponent::PlayAnimation(cannon, animationName, priority); } @@ -517,7 +517,7 @@ void SGCannon::PlaySceneAnimation(Entity* self, const std::u16string& animationN } if (onPlayer) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { RenderComponent::PlayAnimation(player, animationName, priority); } @@ -538,7 +538,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { self->SetNetworkVar(ReSetSuperChargeVariable, true); self->SetNetworkVar(HideSuperChargeVariable, true); - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) return; @@ -596,7 +596,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { ActivityTimerStopAllTimers(self); // Destroy all spawners - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup("SGEnemy")) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup("SGEnemy")) { entity->Kill(); } @@ -663,7 +663,7 @@ void SGCannon::RegisterHit(Entity* self, Entity* target, const std::string& time self->SetNetworkVar(u"beatHighScore", GeneralUtils::to_u16string(newScore)); - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) return; auto missionComponent = player->GetComponent(); @@ -713,7 +713,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { if (enable && self->GetVar(SuperChargeActiveVariable)) return; - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) { Game::logger->Log("SGCannon", "Player not found in toggle super charge"); @@ -788,8 +788,8 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { shootingGalleryComponent->SetDynamicParams(properties); - EntityManager::Instance()->SerializeEntity(self); - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(self); + Game::entityManager->SerializeEntity(player); self->SetNetworkVar(CannonBallSkillIDVariable, skillID); self->SetVar(SuperChargeActiveVariable, enable); diff --git a/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp b/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp index 6822abda..b1de87c9 100644 --- a/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp @@ -2,7 +2,7 @@ #include "EntityManager.h" void ZoneSGServer::OnStartup(Entity* self) { - const auto cannons = EntityManager::Instance()->GetEntitiesByLOT(1864); + const auto cannons = Game::entityManager->GetEntitiesByLOT(1864); for (const auto& cannon : cannons) self->SetVar(CannonIDVariable, cannon->GetObjectID()); } @@ -10,7 +10,7 @@ void ZoneSGServer::OnStartup(Entity* self) { void ZoneSGServer::OnActivityStateChangeRequest(Entity* self, const LWOOBJID senderID, const int32_t value1, const int32_t value2, const std::u16string& stringValue) { - auto* cannon = EntityManager::Instance()->GetEntity(self->GetVar(CannonIDVariable)); + auto* cannon = Game::entityManager->GetEntity(self->GetVar(CannonIDVariable)); if (cannon != nullptr) { cannon->OnActivityStateChangeRequest(senderID, value1, value2, stringValue); } @@ -19,7 +19,7 @@ void ZoneSGServer::OnActivityStateChangeRequest(Entity* self, const LWOOBJID sen void ZoneSGServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { - auto* cannon = EntityManager::Instance()->GetEntity(self->GetVar(CannonIDVariable)); + auto* cannon = Game::entityManager->GetEntity(self->GetVar(CannonIDVariable)); if (cannon != nullptr) { cannon->OnFireEventServerSide(sender, args, param1, param2, param3); } diff --git a/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp b/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp index ab659d8a..8f8906d3 100644 --- a/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp +++ b/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp @@ -4,7 +4,7 @@ #include "EntityManager.h" void PropertyDeathPlane::OnCollisionPhantom(Entity* self, Entity* target) { - const auto teleportGroup = EntityManager::Instance()->GetEntitiesInGroup("Teleport"); + const auto teleportGroup = Game::entityManager->GetEntitiesInGroup("Teleport"); if (teleportGroup.size() == 0) { return; diff --git a/dScripts/ai/NS/NsConcertInstrument.cpp b/dScripts/ai/NS/NsConcertInstrument.cpp index ba99d4d1..bd397fbb 100644 --- a/dScripts/ai/NS/NsConcertInstrument.cpp +++ b/dScripts/ai/NS/NsConcertInstrument.cpp @@ -49,7 +49,7 @@ void NsConcertInstrument::OnFireEventServerSide(Entity* self, Entity* sender, st if (activePlayerID == LWOOBJID_EMPTY) return; - const auto activePlayer = EntityManager::Instance()->GetEntity(activePlayerID); + const auto activePlayer = Game::entityManager->GetEntity(activePlayerID); if (activePlayer == nullptr) return; @@ -63,7 +63,7 @@ void NsConcertInstrument::OnTimerDone(Entity* self, std::string name) { return; // If for some reason the player becomes null (for example an unexpected leave), we need to clean up - const auto activePlayer = EntityManager::Instance()->GetEntity(activePlayerID); + const auto activePlayer = Game::entityManager->GetEntity(activePlayerID); if (activePlayer == nullptr && name != "cleanupAfterStop") { StopPlayingInstrument(self, nullptr); return; @@ -126,7 +126,7 @@ void NsConcertInstrument::StartPlayingInstrument(Entity* self, Entity* player) { RenderComponent::PlayAnimation(player, animations.at(instrumentLot), 2.0f); }); - for (auto* soundBox : EntityManager::Instance()->GetEntitiesInGroup("Audio-Concert")) { + for (auto* soundBox : Game::entityManager->GetEntitiesInGroup("Audio-Concert")) { auto* soundTrigger = soundBox->GetComponent(); if (soundTrigger != nullptr) { soundTrigger->ActivateMusicCue(music.at(instrumentLot)); @@ -161,7 +161,7 @@ void NsConcertInstrument::StopPlayingInstrument(Entity* self, Entity* player) { self->SetVar(u"beingPlayed", false); - for (auto* soundBox : EntityManager::Instance()->GetEntitiesInGroup("Audio-Concert")) { + for (auto* soundBox : Game::entityManager->GetEntitiesInGroup("Audio-Concert")) { auto* soundTrigger = soundBox->GetComponent(); if (soundTrigger != nullptr) { soundTrigger->DeactivateMusicCue(music.at(instrumentLot)); diff --git a/dScripts/ai/NS/NsConcertQuickBuild.cpp b/dScripts/ai/NS/NsConcertQuickBuild.cpp index 4589ee6a..960b90d5 100644 --- a/dScripts/ai/NS/NsConcertQuickBuild.cpp +++ b/dScripts/ai/NS/NsConcertQuickBuild.cpp @@ -42,7 +42,7 @@ void NsConcertQuickBuild::OnStartup(Entity* self) { // Get the manager of the crate of this quick build const auto groupNumber = std::stoi(splitGroup.at(3)); - const auto managerObjects = EntityManager::Instance()->GetEntitiesInGroup("CB_" + std::to_string(groupNumber)); + const auto managerObjects = Game::entityManager->GetEntitiesInGroup("CB_" + std::to_string(groupNumber)); if (managerObjects.empty()) return; @@ -67,7 +67,7 @@ float NsConcertQuickBuild::GetBlinkTime(float time) { } void NsConcertQuickBuild::OnDie(Entity* self, Entity* killer) { - auto* managerObject = EntityManager::Instance()->GetEntity(self->GetVar(u"managerObject")); + auto* managerObject = Game::entityManager->GetEntity(self->GetVar(u"managerObject")); if (managerObject) { managerObject->CancelAllTimers(); managerObject->AddCallbackTimer(1.0f, [managerObject]() { @@ -90,7 +90,7 @@ void NsConcertQuickBuild::OnRebuildComplete(Entity* self, Entity* target) { // Find all the quick build objects of the same lot auto finishedQuickBuildObjects = std::vector(); for (auto quickBuildID : finishedQuickBuilds) { - const auto quickBuildObject = EntityManager::Instance()->GetEntity(quickBuildID); + const auto quickBuildObject = Game::entityManager->GetEntity(quickBuildID); if (quickBuildObject && quickBuildObject->GetLOT() == self->GetLOT()) { quickBuildObject->SetVar(u"Player_" + (GeneralUtils::to_u16string(groupNumber)), target->GetObjectID()); finishedQuickBuildObjects.push_back(quickBuildObject); @@ -101,7 +101,7 @@ void NsConcertQuickBuild::OnRebuildComplete(Entity* self, Entity* target) { if (finishedQuickBuildObjects.size() >= 4) { // Move all the platforms so the user can collect the imagination brick - const auto movingPlatforms = EntityManager::Instance()->GetEntitiesInGroup("ConcertPlatforms"); + const auto movingPlatforms = Game::entityManager->GetEntitiesInGroup("ConcertPlatforms"); for (auto* movingPlatform : movingPlatforms) { auto* component = movingPlatform->GetComponent(); if (component) { @@ -184,7 +184,7 @@ void NsConcertQuickBuild::ProgressLicensedTechnician(Entity* self) { for (auto i = 1; i < 5; i++) { const auto playerID = self->GetVar(u"Player_" + (GeneralUtils::to_u16string(i))); if (playerID != LWOOBJID_EMPTY) { - const auto player = EntityManager::Instance()->GetEntity(playerID); + const auto player = Game::entityManager->GetEntity(playerID); if (player) { auto playerMissionComponent = player->GetComponent(); if (playerMissionComponent) @@ -202,7 +202,7 @@ void NsConcertQuickBuild::UpdateEffects(Entity* self) { return; for (const auto& effectName : setIterator->second.effects) { - const auto effectObjects = EntityManager::Instance()->GetEntitiesInGroup(quickBuildFX.at(effectName)); + const auto effectObjects = Game::entityManager->GetEntitiesInGroup(quickBuildFX.at(effectName)); for (auto* effectObject : effectObjects) { GameMessages::SendPlayFXEffect(effectObject, 0, GeneralUtils::ASCIIToUTF16(effectName), effectName + "Effect", LWOOBJID_EMPTY, 1, 1, true); @@ -216,7 +216,7 @@ void NsConcertQuickBuild::CancelEffects(Entity* self) { return; for (const auto& effectName : setIterator->second.effects) { - const auto effectObjects = EntityManager::Instance()->GetEntitiesInGroup(quickBuildFX.at(effectName)); + const auto effectObjects = Game::entityManager->GetEntitiesInGroup(quickBuildFX.at(effectName)); for (auto* effectObject : effectObjects) { GameMessages::SendStopFXEffect(effectObject, true, effectName + "Effect"); } diff --git a/dScripts/ai/NS/NsQbImaginationStatue.cpp b/dScripts/ai/NS/NsQbImaginationStatue.cpp index a2e335b7..8f9a0b09 100644 --- a/dScripts/ai/NS/NsQbImaginationStatue.cpp +++ b/dScripts/ai/NS/NsQbImaginationStatue.cpp @@ -31,7 +31,7 @@ void NsQbImaginationStatue::OnTimerDone(Entity* self, std::string timerName) { void NsQbImaginationStatue::SpawnLoot(Entity* self) { const auto playerId = self->GetVar(u"Player"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; diff --git a/dScripts/ai/NS/WH/RockHydrantBroken.cpp b/dScripts/ai/NS/WH/RockHydrantBroken.cpp index 835d52f6..243761d3 100644 --- a/dScripts/ai/NS/WH/RockHydrantBroken.cpp +++ b/dScripts/ai/NS/WH/RockHydrantBroken.cpp @@ -7,7 +7,7 @@ void RockHydrantBroken::OnStartup(Entity* self) { const auto hydrant = "hydrant" + self->GetVar(u"hydrant"); - const auto bouncers = EntityManager::Instance()->GetEntitiesInGroup(hydrant); + const auto bouncers = Game::entityManager->GetEntitiesInGroup(hydrant); for (auto* bouncer : bouncers) { self->SetVar(u"bouncer", bouncer->GetObjectID()); @@ -23,7 +23,7 @@ void RockHydrantBroken::OnStartup(Entity* self) { void RockHydrantBroken::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "KillBroken") { - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"bouncer")); if (bouncer != nullptr) { GameMessages::SendBouncerActiveStatus(bouncer->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); diff --git a/dScripts/ai/NS/WH/RockHydrantSmashable.cpp b/dScripts/ai/NS/WH/RockHydrantSmashable.cpp index b3a01567..d388baac 100644 --- a/dScripts/ai/NS/WH/RockHydrantSmashable.cpp +++ b/dScripts/ai/NS/WH/RockHydrantSmashable.cpp @@ -15,7 +15,7 @@ void RockHydrantSmashable::OnDie(Entity* self, Entity* killer) { info.settings = { data }; info.spawnerID = self->GetSpawnerID(); - auto* hydrant = EntityManager::Instance()->CreateEntity(info); + auto* hydrant = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(hydrant); + Game::entityManager->ConstructEntity(hydrant); } diff --git a/dScripts/ai/NS/WhFans.cpp b/dScripts/ai/NS/WhFans.cpp index 8500e824..a41a2c23 100644 --- a/dScripts/ai/NS/WhFans.cpp +++ b/dScripts/ai/NS/WhFans.cpp @@ -23,7 +23,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { fanGroup = ""; } - std::vector fanVolumes = EntityManager::Instance()->GetEntitiesInGroup(fanGroup); + std::vector fanVolumes = Game::entityManager->GetEntitiesInGroup(fanGroup); auto* renderComponent = self->GetComponent(); @@ -41,7 +41,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { auto volumePhys = volume->GetComponent(); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(false); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); } } else if (!self->GetVar(u"on") && self->GetVar(u"alive")) { RenderComponent::PlayAnimation(self, u"fan-on"); @@ -52,7 +52,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { auto volumePhys = volume->GetComponent(); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); } } } diff --git a/dScripts/ai/PETS/HydrantSmashable.cpp b/dScripts/ai/PETS/HydrantSmashable.cpp index 1ff082ea..fc83a5d3 100644 --- a/dScripts/ai/PETS/HydrantSmashable.cpp +++ b/dScripts/ai/PETS/HydrantSmashable.cpp @@ -15,7 +15,7 @@ void HydrantSmashable::OnDie(Entity* self, Entity* killer) { info.settings = { data }; info.spawnerID = self->GetSpawnerID(); - auto* hydrant = EntityManager::Instance()->CreateEntity(info); + auto* hydrant = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(hydrant); + Game::entityManager->ConstructEntity(hydrant); } diff --git a/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp b/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp index 853da92d..e8e94b53 100644 --- a/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp +++ b/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp @@ -31,10 +31,10 @@ void AgPropGuard::OnMissionDialogueOK(Entity* self, Entity* target, int missionI (missionID == 320 && state == eMissionState::AVAILABLE) /*|| (state == eMissionState::COMPLETE && missionID == 891 && missionState == eMissionState::READY_TO_COMPLETE)*/ ) { - //GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), u"GuardChat", target->GetObjectID(), 0, target->GetObjectID(), "", target->GetSystemAddress()); + //GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"GuardChat", target->GetObjectID(), 0, target->GetObjectID(), "", target->GetSystemAddress()); target->GetCharacter()->SetPlayerFlag(113, true); - EntityManager::Instance()->GetZoneControlEntity()->AddTimer("GuardFlyAway", 1.0f); + Game::entityManager->GetZoneControlEntity()->AddTimer("GuardFlyAway", 1.0f); } } diff --git a/dScripts/ai/PROPERTY/AgPropguards.cpp b/dScripts/ai/PROPERTY/AgPropguards.cpp index 7e8e2fd1..60a153a6 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.cpp +++ b/dScripts/ai/PROPERTY/AgPropguards.cpp @@ -20,7 +20,7 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission GameMessages::SendPlayCinematic(target->GetObjectID(), u"MissionCam", target->GetSystemAddress()); } else if (missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { // Makes the guard disappear once the mission has been completed - const auto zoneControlID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + const auto zoneControlID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); GameMessages::SendNotifyClientObject(zoneControlID, u"GuardChat", 0, 0, self->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); diff --git a/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp b/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp index f69a3eb6..2bdb0364 100644 --- a/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp @@ -12,14 +12,14 @@ void FvRaceSmashEggImagineServer::OnDie(Entity* self, Entity* killer) { auto* destroyableComponent = killer->GetComponent(); if (destroyableComponent != nullptr) { destroyableComponent->SetImagination(destroyableComponent->GetImagination() + 10); - EntityManager::Instance()->SerializeEntity(killer); + Game::entityManager->SerializeEntity(killer); } // get possessor to progress statistics and tasks. auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* missionComponent = possessor->GetComponent(); diff --git a/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp b/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp index 6a29f9a8..20a3c0cc 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp @@ -30,14 +30,14 @@ void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) { if (destroyableComponent != nullptr) { destroyableComponent->SetImagination(60); - EntityManager::Instance()->SerializeEntity(killer); + Game::entityManager->SerializeEntity(killer); } // Find possessor of race car to progress missions and update stats. auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* missionComponent = possessor->GetComponent(); diff --git a/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp b/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp index 92a50873..d55eeffd 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp @@ -15,7 +15,7 @@ void RaceImaginePowerup::OnFireEventServerSide(Entity* self, Entity* sender, std return; } - auto* vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) { return; diff --git a/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp b/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp index 295f38ee..5fcb2ff4 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp @@ -11,7 +11,7 @@ void RaceSmashServer::OnDie(Entity* self, Entity* killer) { auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* missionComponent = possessor->GetComponent(); diff --git a/dScripts/ai/WILD/WildNinjaSensei.cpp b/dScripts/ai/WILD/WildNinjaSensei.cpp index 42ddfa21..0941e41c 100644 --- a/dScripts/ai/WILD/WildNinjaSensei.cpp +++ b/dScripts/ai/WILD/WildNinjaSensei.cpp @@ -8,27 +8,27 @@ void WildNinjaSensei::OnStartup(Entity* self) { void WildNinjaSensei::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "CraneStart") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Crane"); self->AddTimer("Bow", 15.5f); self->AddTimer("TigerStart", 25); GameMessages::SendPlayAnimation(self, u"crane"); } else if (timerName == "TigerStart") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); GameMessages::SendPlayAnimation(self, u"bow"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Tiger"); self->AddTimer("Bow", 15.5f); self->AddTimer("MantisStart", 25); GameMessages::SendPlayAnimation(self, u"tiger"); } else if (timerName == "MantisStart") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); GameMessages::SendPlayAnimation(self, u"tiger"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Mantis"); self->AddTimer("Bow", 15.5f); self->AddTimer("CraneStart", 25); GameMessages::SendPlayAnimation(self, u"mantis"); } else if (timerName == "Bow") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Bow"); GameMessages::SendPlayAnimation(self, u"bow"); } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 18625960..44796224 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -71,6 +71,7 @@ #include "eMasterMessageType.h" #include "eGameMessageType.h" #include "ZCompression.h" +#include "EntityManager.h" namespace Game { dLogger* logger = nullptr; @@ -83,6 +84,7 @@ namespace Game { std::mt19937 randomEngine; SystemAddress chatSysAddr; bool shouldShutdown = false; + EntityManager* entityManager = nullptr; } // namespace Game bool chatDisabled = false; @@ -251,6 +253,7 @@ int main(int argc, char** argv) { PerformanceManager::SelectProfile(zoneID); + Game::entityManager = new EntityManager(); //Load our level: if (zoneID != 0) { dpWorld::Instance().Initialize(zoneID); @@ -297,6 +300,8 @@ int main(int argc, char** argv) { Game::logger->Log("WorldServer", "FDB Checksum calculated as: %s", databaseChecksum.c_str()); } + } else { + Game::entityManager->Initialize(); } uint32_t currentFrameDelta = highFrameDelta; @@ -383,12 +388,12 @@ int main(int argc, char** argv) { Metrics::EndMeasurement(MetricVariable::Physics); Metrics::StartMeasurement(MetricVariable::UpdateEntities); - EntityManager::Instance()->UpdateEntities(deltaTime); + Game::entityManager->UpdateEntities(deltaTime); Metrics::EndMeasurement(MetricVariable::UpdateEntities); Metrics::StartMeasurement(MetricVariable::Ghosting); if (std::chrono::duration(currentTime - ghostingLastTime).count() >= 1.0f) { - EntityManager::Instance()->UpdateGhosting(); + Game::entityManager->UpdateGhosting(); ghostingLastTime = currentTime; } Metrics::EndMeasurement(MetricVariable::Ghosting); @@ -558,7 +563,7 @@ void HandlePacketChat(Packet* packet) { LWOOBJID playerID; inStream.Read(playerID); - auto player = EntityManager::Instance()->GetEntity(playerID); + auto player = Game::entityManager->GetEntity(playerID); if (!player) return; auto sysAddr = player->GetSystemAddress(); @@ -614,7 +619,7 @@ void HandlePacketChat(Packet* packet) { inStream.Read(playerId); inStream.Read(expire); - auto* entity = EntityManager::Instance()->GetEntity(playerId); + auto* entity = Game::entityManager->GetEntity(playerId); if (entity != nullptr) { entity->GetParentUser()->SetMuteExpire(expire); @@ -678,7 +683,7 @@ void HandlePacket(Packet* packet) { return; } - auto* entity = EntityManager::Instance()->GetEntity(c->GetObjectID()); + auto* entity = Game::entityManager->GetEntity(c->GetObjectID()); if (!entity) { entity = Player::GetPlayer(packet->systemAddress); @@ -695,7 +700,7 @@ void HandlePacket(Packet* packet) { Game::logger->Log("WorldServer", "Deleting player %llu", entity->GetObjectID()); - EntityManager::Instance()->DestroyEntity(entity); + Game::entityManager->DestroyEntity(entity); } { @@ -917,7 +922,7 @@ void HandlePacket(Packet* packet) { if (Game::server->GetZoneID() != 0) { auto user = UserManager::Instance()->GetUser(packet->systemAddress); if (!user) return; - EntityManager::Instance()->DestroyEntity(user->GetLastUsedChar()->GetEntity()); + Game::entityManager->DestroyEntity(user->GetLastUsedChar()->GetEntity()); } //This loops prevents users who aren't authenticated to double-request the char list, which @@ -1005,20 +1010,20 @@ void HandlePacket(Packet* packet) { EntityInfo info{}; info.lot = 1; - Entity* player = EntityManager::Instance()->CreateEntity(info, UserManager::Instance()->GetUser(packet->systemAddress)); + Entity* player = Game::entityManager->CreateEntity(info, UserManager::Instance()->GetUser(packet->systemAddress)); WorldPackets::SendCreateCharacter(packet->systemAddress, player, c->GetXMLData(), username, c->GetGMLevel()); WorldPackets::SendServerState(packet->systemAddress); const auto respawnPoint = player->GetCharacter()->GetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID()); - EntityManager::Instance()->ConstructEntity(player, UNASSIGNED_SYSTEM_ADDRESS, true); + Game::entityManager->ConstructEntity(player, UNASSIGNED_SYSTEM_ADDRESS, true); if (respawnPoint != NiPoint3::ZERO) { GameMessages::SendPlayerReachedRespawnCheckpoint(player, respawnPoint, NiQuaternion::IDENTITY); } - EntityManager::Instance()->ConstructAllEntities(packet->systemAddress); + Game::entityManager->ConstructAllEntities(packet->systemAddress); auto* characterComponent = player->GetComponent(); if (characterComponent) { @@ -1330,6 +1335,7 @@ void FinalizeShutdown() { if (Game::server) delete Game::server; if (Game::logger) delete Game::logger; if (Game::config) delete Game::config; + if (Game::entityManager) delete Game::entityManager; worldShutdownSequenceComplete = true; diff --git a/dZoneManager/Level.cpp b/dZoneManager/Level.cpp index 55790592..3a1cbb45 100644 --- a/dZoneManager/Level.cpp +++ b/dZoneManager/Level.cpp @@ -332,7 +332,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { if (zoneControlObject != nullptr && info.lot == zoneControlObject->GetLOT()) goto deleteSettings; - EntityManager::Instance()->CreateEntity(info, nullptr); + Game::entityManager->CreateEntity(info, nullptr); } else { deleteSettings: diff --git a/dZoneManager/Spawner.cpp b/dZoneManager/Spawner.cpp index 28f77fea..bf01103d 100644 --- a/dZoneManager/Spawner.cpp +++ b/dZoneManager/Spawner.cpp @@ -46,7 +46,7 @@ Spawner::Spawner(const SpawnerInfo info) { } if (m_Info.spawnOnSmashGroupName != "") { - std::vector spawnSmashEntities = EntityManager::Instance()->GetEntitiesInGroup(m_Info.spawnOnSmashGroupName); + std::vector spawnSmashEntities = Game::entityManager->GetEntitiesInGroup(m_Info.spawnOnSmashGroupName); std::vector spawnSmashSpawners = dZoneManager::Instance()->GetSpawnersInGroup(m_Info.spawnOnSmashGroupName); std::vector spawnSmashSpawnersN = dZoneManager::Instance()->GetSpawnersByName(m_Info.spawnOnSmashGroupName); for (Entity* ssEntity : spawnSmashEntities) { @@ -102,11 +102,11 @@ Entity* Spawner::Spawn(std::vector freeNodes, const bool force) { m_EntityInfo.spawnerID = m_Info.spawnerID; } - Entity* rezdE = EntityManager::Instance()->CreateEntity(m_EntityInfo, nullptr); + Entity* rezdE = Game::entityManager->CreateEntity(m_EntityInfo, nullptr); rezdE->GetGroups() = m_Info.groups; - EntityManager::Instance()->ConstructEntity(rezdE); + Game::entityManager->ConstructEntity(rezdE); m_Entities.insert({ rezdE->GetObjectID(), spawnNode }); spawnNode->entities.push_back(rezdE->GetObjectID()); @@ -143,7 +143,7 @@ void Spawner::Reset() { void Spawner::DestroyAllEntities(){ for (auto* node : m_Info.nodes) { for (const auto& element : node->entities) { - auto* entity = EntityManager::Instance()->GetEntity(element); + auto* entity = Game::entityManager->GetEntity(element); if (entity == nullptr) continue; entity->Kill(); } diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index a26e912f..960726a2 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -39,8 +39,8 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { zoneControlTemplate = zone->zoneControlTemplate != -1 ? zone->zoneControlTemplate : 2365; const auto min = zone->ghostdistance_min != -1.0f ? zone->ghostdistance_min : 100; const auto max = zone->ghostdistance != -1.0f ? zone->ghostdistance : 100; - EntityManager::Instance()->SetGhostDistanceMax(max + min); - EntityManager::Instance()->SetGhostDistanceMin(max); + Game::entityManager->SetGhostDistanceMax(max + min); + Game::entityManager->SetGhostDistanceMin(max); m_PlayerLoseCoinsOnDeath = zone->PlayerLoseCoinsOnDeath; } } @@ -48,10 +48,15 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { Game::logger->Log("dZoneManager", "Creating zone control object %i", zoneControlTemplate); // Create ZoneControl object + if (!Game::entityManager) { + Game::logger->Log("dZoneManager", "ERROR: No entity manager loaded. Cannot proceed."); + throw std::invalid_argument("No entity manager loaded. Cannot proceed."); + } + Game::entityManager->Initialize(); EntityInfo info; info.lot = zoneControlTemplate; info.id = 70368744177662; - Entity* zoneControl = EntityManager::Instance()->CreateEntity(info, nullptr, nullptr, true); + Entity* zoneControl = Game::entityManager->CreateEntity(info, nullptr, nullptr, true); m_ZoneControlObject = zoneControl; m_pZone->Initalize(); @@ -148,9 +153,9 @@ LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) { entityInfo.id = objectId; entityInfo.lot = 176; - auto* entity = EntityManager::Instance()->CreateEntity(entityInfo, nullptr, nullptr, false, objectId); + auto* entity = Game::entityManager->CreateEntity(entityInfo, nullptr, nullptr, false, objectId); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); AddSpawner(objectId, spawner); @@ -175,7 +180,7 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id) { return; } - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity != nullptr) { entity->Kill(); diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index 7b0a8412..1765bd9b 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -1,13 +1,14 @@ #include "GameDependencies.h" namespace Game { - dLogger* logger; - dServer* server; - dZoneManager* zoneManager; - dChatFilter* chatFilter; - dConfig* config; + dLogger* logger = nullptr; + dServer* server = nullptr; + dZoneManager* zoneManager = nullptr; + dChatFilter* chatFilter = nullptr; + dConfig* config = nullptr; std::mt19937 randomEngine; - RakPeerInterface* chatServer; - AssetManager* assetManager; + RakPeerInterface* chatServer = nullptr; + AssetManager* assetManager = nullptr; SystemAddress chatSysAddr; + EntityManager* entityManager = nullptr; } diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 353b53b8..95ef2f9f 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -32,11 +32,12 @@ protected: Game::logger = new dLogger("./testing.log", true, true); Game::server = new dServerMock(); Game::config = new dConfig("worldconfig.ini"); + Game::entityManager = new EntityManager(); } void TearDownDependencies() { if (Game::server) delete Game::server; - delete EntityManager::Instance(); + if (Game::entityManager) delete Game::entityManager; if (Game::logger) { Game::logger->Flush(); delete Game::logger; @@ -44,7 +45,7 @@ protected: if (Game::config) delete Game::config; } - EntityInfo info; + EntityInfo info{}; }; #endif //!__GAMEDEPENDENCIES__H__ From 080a833144c314d9fe0068597651e0983e4341b9 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:55:25 -0700 Subject: [PATCH 104/116] Convert BrickDatabase to namespace (#1142) * Convert BrickDatabase to namespace This did not need to be a class. * Fix linker errors * convert to anonymous namespace so the cache is unmodifiable outside the brickcache * Move to lower scope level and remove log --- dGame/dComponents/PetComponent.cpp | 2 +- dGame/dGameMessages/GameMessages.cpp | 2 +- dGame/dGameMessages/GameMessages.h | 2 +- dGame/dUtilities/BrickDatabase.cpp | 12 ++++------ dGame/dUtilities/BrickDatabase.h | 35 +++++++++------------------- 5 files changed, 19 insertions(+), 34 deletions(-) diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 762c4f85..c2843266 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -236,7 +236,7 @@ void PetComponent::OnUse(Entity* originator) { return; } - auto& bricks = BrickDatabase::Instance()->GetBricks(buildFile); + const auto& bricks = BrickDatabase::GetBricks(buildFile); if (bricks.empty()) { ChatPackets::SendSystemMessage(originator->GetSystemAddress(), u"Failed to load the puzzle minigame for this pet."); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 8f7b96e1..390699e4 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3471,7 +3471,7 @@ void GameMessages::SendNotifyTamingModelLoadedOnServer(LWOOBJID objectId, const SEND_PACKET; } -void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, std::vector& bricks, const SystemAddress& sysAddr) { +void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, const std::vector& bricks, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 94bdd3ea..bd1224d3 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -364,7 +364,7 @@ namespace GameMessages { //Pets: void SendNotifyPetTamingMinigame(LWOOBJID objectId, LWOOBJID petId, LWOOBJID playerTamingId, bool bForceTeleport, ePetTamingNotifyType notifyType, NiPoint3 petsDestPos, NiPoint3 telePos, NiQuaternion teleRot, const SystemAddress& sysAddr); - void SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, std::vector& bricks, const SystemAddress& sysAddr); + void SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, const std::vector& bricks, const SystemAddress& sysAddr); void SendNotifyTamingModelLoadedOnServer(LWOOBJID objectId, const SystemAddress& sysAddr); diff --git a/dGame/dUtilities/BrickDatabase.cpp b/dGame/dUtilities/BrickDatabase.cpp index a6c43d52..e4a6a714 100644 --- a/dGame/dUtilities/BrickDatabase.cpp +++ b/dGame/dUtilities/BrickDatabase.cpp @@ -5,14 +5,12 @@ #include "Game.h" #include "AssetManager.h" #include "tinyxml2.h" +#include "Brick.h" -std::vector BrickDatabase::emptyCache{}; -BrickDatabase* BrickDatabase::m_Address = nullptr; +const BrickList& BrickDatabase::GetBricks(const LxfmlPath& lxfmlPath) { + static std::unordered_map m_Cache; + static const BrickList emptyCache; -BrickDatabase::BrickDatabase() = default; -BrickDatabase::~BrickDatabase() = default; - -std::vector& BrickDatabase::GetBricks(const std::string& lxfmlPath) { const auto cached = m_Cache.find(lxfmlPath); if (cached != m_Cache.end()) { @@ -45,7 +43,7 @@ std::vector& BrickDatabase::GetBricks(const std::string& lxfmlPath) { return emptyCache; } - std::vector parts; + BrickList parts; auto* lxfml = doc->FirstChildElement("LXFML"); auto* bricks = lxfml->FirstChildElement("Bricks"); diff --git a/dGame/dUtilities/BrickDatabase.h b/dGame/dUtilities/BrickDatabase.h index 589d46ae..11c64416 100644 --- a/dGame/dUtilities/BrickDatabase.h +++ b/dGame/dUtilities/BrickDatabase.h @@ -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; +using LxfmlPath = std::string; - return m_Address; - } - - std::vector& GetBricks(const std::string& lxfmlPath); - - explicit BrickDatabase(); - - ~BrickDatabase(); - -private: - std::unordered_map> m_Cache; - - static std::vector emptyCache; - - static BrickDatabase* m_Address; //For singleton method - - /* data */ +namespace BrickDatabase { + const BrickList& GetBricks(const LxfmlPath& lxfmlPath); }; + +#endif //!__BRICKDATABASE__H__ From 3e3148e9102c067173b3f4b0c1eded3dde55c780 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:55:33 -0700 Subject: [PATCH 105/116] Move dZoneManager to game namespace (#1143) * convert zone manager to game namespace * Destroy logger last --- dCommon/Game.h | 2 ++ dGame/Character.cpp | 6 ++--- dGame/Entity.cpp | 14 +++++------ dGame/EntityManager.cpp | 4 ++-- dGame/Player.cpp | 2 +- dGame/dBehaviors/PropertyTeleportBehavior.cpp | 4 ++-- dGame/dComponents/CharacterComponent.cpp | 4 ++-- .../ControllablePhysicsComponent.cpp | 2 +- dGame/dComponents/DestroyableComponent.cpp | 8 +++---- dGame/dComponents/InventoryComponent.cpp | 2 +- dGame/dComponents/MissionComponent.cpp | 2 +- dGame/dComponents/MovingPlatformComponent.cpp | 2 +- .../PropertyManagementComponent.cpp | 24 +++++++++---------- dGame/dComponents/PropertyVendorComponent.cpp | 2 +- dGame/dComponents/RacingControlComponent.cpp | 18 +++++++------- .../dComponents/ScriptedActivityComponent.cpp | 4 ++-- dGame/dComponents/TriggerComponent.cpp | 10 ++++---- dGame/dGameMessages/GameMessageHandler.cpp | 2 +- dGame/dGameMessages/GameMessages.cpp | 18 +++++++------- dGame/dMission/Mission.cpp | 6 ++--- dGame/dMission/MissionTask.cpp | 2 +- dGame/dUtilities/Mail.cpp | 4 ++-- dGame/dUtilities/SlashCommandHandler.cpp | 18 +++++++------- dNet/WorldPackets.cpp | 2 +- .../Enemy/AG/BossSpiderQueenEnemyServer.cpp | 4 ++-- .../02_server/Map/AM/AmDropshipComputer.cpp | 6 ++--- .../02_server/Map/FV/ImgBrickConsoleQB.cpp | 16 ++++++------- .../Map/FV/Racing/RaceMaelstromGeiser.cpp | 2 +- .../02_server/Map/General/PetDigServer.cpp | 8 +++---- dScripts/02_server/Map/NS/NsLegoClubDoor.cpp | 2 +- dScripts/02_server/Map/NS/NsLupTeleport.cpp | 2 +- .../Map/Property/AG_Small/ZoneAgProperty.cpp | 8 +++---- .../02_server/Map/njhub/CavePrisonCage.cpp | 2 +- dScripts/02_server/Map/njhub/Lieutenant.cpp | 2 +- .../02_server/Map/njhub/MonCoreNookDoors.cpp | 2 +- .../boss_instance/NjMonastryBossInstance.cpp | 14 +++++------ .../General/MinigameTreasureChestServer.cpp | 4 ++-- dScripts/BasePropertyServer.cpp | 18 +++++++------- dScripts/BaseRandomServer.cpp | 2 +- dScripts/BaseSurvivalServer.cpp | 10 ++++---- dScripts/BaseWavesGenericEnemy.cpp | 2 +- dScripts/BaseWavesServer.cpp | 4 ++-- dScripts/ai/ACT/ActVehicleDeathTrigger.cpp | 2 +- dScripts/ai/FV/FvBrickPuzzleServer.cpp | 6 ++--- dScripts/ai/FV/FvFacilityBrick.cpp | 6 ++--- dScripts/ai/GF/GfJailWalls.cpp | 8 +++---- dScripts/ai/GF/TriggerAmbush.cpp | 4 ++-- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 4 ++-- dScripts/ai/PROPERTY/AgPropguards.cpp | 2 +- dWorldServer/WorldServer.cpp | 17 +++++++------ dZoneManager/Level.cpp | 8 +++---- dZoneManager/Spawner.cpp | 4 ++-- dZoneManager/Zone.cpp | 2 +- dZoneManager/dZoneManager.cpp | 2 -- dZoneManager/dZoneManager.h | 9 ------- 55 files changed, 169 insertions(+), 175 deletions(-) diff --git a/dCommon/Game.h b/dCommon/Game.h index f099734a..09ac6f6e 100644 --- a/dCommon/Game.h +++ b/dCommon/Game.h @@ -11,6 +11,7 @@ class RakPeerInterface; class AssetManager; struct SystemAddress; class EntityManager; +class dZoneManager; namespace Game { extern dLogger* logger; @@ -24,4 +25,5 @@ namespace Game { extern SystemAddress chatSysAddr; extern bool shouldShutdown; extern EntityManager* entityManager; + extern dZoneManager* zoneManager; } diff --git a/dGame/Character.cpp b/dGame/Character.cpp index aa734271..c5602bf2 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -241,7 +241,7 @@ void Character::DoQuickXMLDataParse() { //To try and fix the AG landing into: if (m_ZoneID == 1000 && Game::server->GetZoneID() == 1100) { //sneakily insert our position: - auto pos = dZoneManager::Instance()->GetZone()->GetSpawnPos(); + auto pos = Game::zoneManager->GetZone()->GetSpawnPos(); character->SetAttribute("lzx", pos.x); character->SetAttribute("lzy", pos.y); character->SetAttribute("lzz", pos.z); @@ -296,7 +296,7 @@ void Character::UnlockEmote(int emoteID) { void Character::SetBuildMode(bool buildMode) { m_BuildMode = buildMode; - auto* controller = dZoneManager::Instance()->GetZoneControlObject(); + auto* controller = Game::zoneManager->GetZoneControlObject(); controller->OnFireEventServerSide(m_OurEntity, buildMode ? "OnBuildModeEnter" : "OnBuildModeLeave"); } @@ -312,7 +312,7 @@ void Character::SaveXMLToDatabase() { character->SetAttribute("gm", static_cast(m_GMLevel)); character->SetAttribute("cc", m_Coins); - auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); // lzid garbage, binary concat of zoneID, zoneInstance and zoneClone if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0) { uint64_t lzidConcat = zoneInfo.GetCloneID(); diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index adf26c78..998541ad 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -267,13 +267,13 @@ void Entity::Initialize() { if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) { pos = m_Character->GetRespawnPoint(mapID); - rot = dZoneManager::Instance()->GetZone()->GetSpawnRot(); + rot = Game::zoneManager->GetZone()->GetSpawnRot(); } else if (targetScene != nullptr) { pos = targetScene->GetPosition(); rot = targetScene->GetRotation(); } else { - pos = dZoneManager::Instance()->GetZone()->GetSpawnPos(); - rot = dZoneManager::Instance()->GetZone()->GetSpawnRot(); + pos = Game::zoneManager->GetZone()->GetSpawnPos(); + rot = Game::zoneManager->GetZone()->GetSpawnRot(); } controllablePhysics->SetPosition(pos); @@ -505,7 +505,7 @@ void Entity::Initialize() { // ZoneControl script if (m_TemplateID == 2365) { CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable(); - const auto zoneID = dZoneManager::Instance()->GetZoneID(); + const auto zoneID = Game::zoneManager->GetZoneID(); const CDZoneTable* zoneData = zoneTable->Query(zoneID.GetMapID()); if (zoneData != nullptr) { @@ -691,7 +691,7 @@ void Entity::Initialize() { } std::string pathName = GetVarAsString(u"attached_path"); - const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName); + const Path* path = Game::zoneManager->GetZone()->GetPath(pathName); //Check to see if we have an attached path and add the appropiate component to handle it: if (path){ @@ -1544,14 +1544,14 @@ void Entity::Kill(Entity* murderer) { const auto& grpNameQBShowBricks = GetVar(u"grpNameQBShowBricks"); if (!grpNameQBShowBricks.empty()) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(grpNameQBShowBricks); + auto spawners = Game::zoneManager->GetSpawnersByName(grpNameQBShowBricks); Spawner* spawner = nullptr; if (!spawners.empty()) { spawner = spawners[0]; } else { - spawners = dZoneManager::Instance()->GetSpawnersInGroup(grpNameQBShowBricks); + spawners = Game::zoneManager->GetSpawnersInGroup(grpNameQBShowBricks); if (!spawners.empty()) { spawner = spawners[0]; diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index e0baa61a..28b5f526 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -60,7 +60,7 @@ void EntityManager::Initialize() { m_GhostingEnabled = std::find( m_GhostingExcludedZones.begin(), m_GhostingExcludedZones.end(), - dZoneManager::Instance()->GetZoneID().GetMapID() + Game::zoneManager->GetZoneID().GetMapID() ) == m_GhostingExcludedZones.end(); // grab hardcore mode settings and load them with sane defaults @@ -75,7 +75,7 @@ void EntityManager::Initialize() { // If cloneID is not zero, then hardcore mode is disabled // aka minigames and props - if (dZoneManager::Instance()->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false; + if (Game::zoneManager->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false; } Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentEntity, const bool controller, const LWOOBJID explicitId) { diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 55881dca..48b983aa 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -62,7 +62,7 @@ void Player::SetSystemAddress(const SystemAddress& value) { void Player::SetRespawnPos(const NiPoint3 position) { m_respawnPos = position; - m_Character->SetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID(), position); + m_Character->SetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID(), position); } void Player::SetRespawnRot(const NiQuaternion rotation) { diff --git a/dGame/dBehaviors/PropertyTeleportBehavior.cpp b/dGame/dBehaviors/PropertyTeleportBehavior.cpp index c49c821d..309fc929 100644 --- a/dGame/dBehaviors/PropertyTeleportBehavior.cpp +++ b/dGame/dBehaviors/PropertyTeleportBehavior.cpp @@ -23,11 +23,11 @@ void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStrea LWOMAPID targetMapId = m_MapId; LWOCLONEID targetCloneId = character->GetPropertyCloneID(); - if (dZoneManager::Instance()->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) { + if (Game::zoneManager->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) { targetMapId = character->GetLastNonInstanceZoneID(); targetCloneId = 0; } else { - character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZoneID().GetMapID()); + character->SetLastNonInstanceZoneID(Game::zoneManager->GetZoneID().GetMapID()); } ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, false, [objId](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 32fe564c..10a4e9db 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -419,7 +419,7 @@ void CharacterComponent::TrackMissionCompletion(bool isAchievement) { // Achievements are tracked separately for the zone if (isAchievement) { - const auto mapID = dZoneManager::Instance()->GetZoneID().GetMapID(); + const auto mapID = Game::zoneManager->GetZoneID().GetMapID(); GetZoneStatisticsForMap(mapID).m_AchievementsCollected++; } } @@ -480,7 +480,7 @@ void CharacterComponent::TrackArmorDelta(int32_t armor) { void CharacterComponent::TrackRebuildComplete() { UpdatePlayerStatistic(QuickBuildsCompleted); - const auto mapID = dZoneManager::Instance()->GetZoneID().GetMapID(); + const auto mapID = Game::zoneManager->GetZoneID().GetMapID(); GetZoneStatisticsForMap(mapID).m_QuickBuildsCompleted++; } diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index 2d5d6209..a658ccd7 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -194,7 +194,7 @@ void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument* doc) { return; } - auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0) { character->SetAttribute("lzx", m_Position.x); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 11b5895a..4c726bad 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -779,13 +779,13 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } } else { //Check if this zone allows coin drops - if (dZoneManager::Instance()->GetPlayerLoseCoinOnDeath()) { + if (Game::zoneManager->GetPlayerLoseCoinOnDeath()) { auto* character = m_Parent->GetCharacter(); uint64_t coinsTotal = character->GetCoins(); - const uint64_t minCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMin; + const uint64_t minCoinsToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathMin; if (coinsTotal >= minCoinsToLose) { - const uint64_t maxCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMax; - const float coinPercentageToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathPercent; + const uint64_t maxCoinsToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathMax; + const float coinPercentageToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathPercent; uint64_t coinsToLose = std::max(static_cast(coinsTotal * coinPercentageToLose), minCoinsToLose); coinsToLose = std::min(maxCoinsToLose, coinsToLose); diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index be1edb27..66b47e52 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -922,7 +922,7 @@ void InventoryComponent::UnEquipItem(Item* item) { // Trigger property event if (PropertyManagementComponent::Instance() != nullptr && item->GetCount() > 0 && Inventory::FindInventoryTypeForLot(item->GetLot()) == MODELS) { PropertyManagementComponent::Instance()->GetParent()->OnZonePropertyModelRemovedWhileEquipped(m_Parent); - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyModelRemovedWhileEquipped(m_Parent); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyModelRemovedWhileEquipped(m_Parent); } } diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index 8f61c1aa..40411902 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -26,7 +26,7 @@ std::unordered_map> MissionComponent: //! Initializer MissionComponent::MissionComponent(Entity* parent) : Component(parent) { - m_LastUsedMissionOrderUID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue(); + m_LastUsedMissionOrderUID = Game::zoneManager->GetUniqueMissionIdStartingValue(); } //! Destructor diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 3b3acb72..f4dcdbe9 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -59,7 +59,7 @@ MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::stri m_MoverSubComponentType = eMoverSubComponentType::mover; m_MoverSubComponent = new MoverSubComponent(m_Parent->GetDefaultPosition()); m_PathName = GeneralUtils::ASCIIToUTF16(pathName); - m_Path = dZoneManager::Instance()->GetZone()->GetPath(pathName); + m_Path = Game::zoneManager->GetZone()->GetPath(pathName); m_NoAutoStart = false; if (m_Path == nullptr) { diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 25d7fb80..c8937c35 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -38,7 +38,7 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo instance = this; - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); @@ -98,7 +98,7 @@ void PropertyManagementComponent::SetOwner(Entity* value) { } std::vector PropertyManagementComponent::GetPaths() const { - const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); + const auto zoneId = Game::zoneManager->GetZone()->GetWorldID(); auto query = CDClientDatabase::CreatePreppedStmt( "SELECT path FROM PropertyTemplate WHERE mapID = ?;"); @@ -192,7 +192,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { auto character = entity->GetCharacter(); if (!character) return false; - auto* zone = dZoneManager::Instance()->GetZone(); + auto* zone = Game::zoneManager->GetZone(); const auto& worldId = zone->GetZoneID(); const auto propertyZoneId = worldId.GetMapID(); @@ -240,7 +240,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { return false; } - auto* zoneControlObject = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneControlObject = Game::zoneManager->GetZoneControlObject(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControlObject)) { script->OnZonePropertyRented(zoneControlObject, entity); } @@ -376,9 +376,9 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N info.spawnerID = persistentId; GeneralUtils::SetBit(info.spawnerID, eObjectBits::CLIENT); - const auto spawnerId = dZoneManager::Instance()->MakeSpawner(info); + const auto spawnerId = Game::zoneManager->MakeSpawner(info); - auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId); + auto* spawner = Game::zoneManager->GetSpawner(spawnerId); auto ldfModelBehavior = new LDFData(u"modelBehaviors", 0); auto userModelID = new LDFData(u"userModelID", info.spawnerID); @@ -433,7 +433,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet const auto spawnerId = index->second; - auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId); + auto* spawner = Game::zoneManager->GetSpawner(spawnerId); models.erase(id); @@ -496,7 +496,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY); if (spawner != nullptr) { - dZoneManager::Instance()->RemoveSpawner(spawner->m_Info.spawnerID); + Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID); } else { model->Smash(LWOOBJID_EMPTY, eKillType::SILENT); } @@ -549,7 +549,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY); if (spawner != nullptr) { - dZoneManager::Instance()->RemoveSpawner(spawner->m_Info.spawnerID); + Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID); } else { model->Smash(LWOOBJID_EMPTY, eKillType::SILENT); } @@ -652,9 +652,9 @@ void PropertyManagementComponent::Load() { node->config = settings; - const auto spawnerId = dZoneManager::Instance()->MakeSpawner(info); + const auto spawnerId = Game::zoneManager->MakeSpawner(info); - auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId); + auto* spawner = Game::zoneManager->GetSpawner(spawnerId); auto* model = spawner->Spawn(); @@ -786,7 +786,7 @@ void PropertyManagementComponent::OnQueryPropertyData(Entity* originator, const author = m_Parent->GetObjectID(); } - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = worldId.GetMapID(); Game::logger->Log("Properties", "Getting property info for %d", zoneId); diff --git a/dGame/dComponents/PropertyVendorComponent.cpp b/dGame/dComponents/PropertyVendorComponent.cpp index ed89bfc7..cff4995c 100644 --- a/dGame/dComponents/PropertyVendorComponent.cpp +++ b/dGame/dComponents/PropertyVendorComponent.cpp @@ -43,7 +43,7 @@ void PropertyVendorComponent::OnBuyFromVendor(Entity* originator, const bool con GameMessages::SendPropertyRentalResponse(m_Parent->GetObjectID(), 0, 0, 0, 0, originator->GetSystemAddress()); - auto* controller = dZoneManager::Instance()->GetZoneControlObject(); + auto* controller = Game::zoneManager->GetZoneControlObject(); controller->OnFireEventServerSide(m_Parent, "propertyRented"); diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 8dd23e53..d669049d 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -49,7 +49,7 @@ RacingControlComponent::RacingControlComponent(Entity* parent) m_MainWorld = 1200; const auto worldID = Game::server->GetZoneID(); - if (dZoneManager::Instance()->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10; + if (Game::zoneManager->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10; m_ActivityID = 42; CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); @@ -105,7 +105,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Calculate the vehicle's starting position. - auto* path = dZoneManager::Instance()->GetZone()->GetPath( + auto* path = Game::zoneManager->GetZone()->GetPath( GeneralUtils::UTF16ToWTF8(m_PathName)); auto spawnPointEntities = Game::entityManager->GetEntitiesByLOT(4843); @@ -394,11 +394,11 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu if (m_SoloRacing || m_LoadedPlayers > 2) { missionComponent->Progress(eMissionTaskType::RACING, data->finished, (LWOOBJID)eRacingTaskParam::FINISH_WITH_PLACEMENT); // Finish in 1st place on a race if (data->finished == 1) { - missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks. - missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::WIN_RACE_IN_WORLD); // Finished first place in specific world. + missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks. + missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::WIN_RACE_IN_WORLD); // Finished first place in specific world. } if (data->finished == m_LoadedPlayers) { - missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world. + missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world. } } } else if ((id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") && button == m_ActivityExitConfirm) { @@ -650,11 +650,11 @@ void RacingControlComponent::Update(float deltaTime) { } // Spawn imagination pickups - auto* minSpawner = dZoneManager::Instance()->GetSpawnersByName( + auto* minSpawner = Game::zoneManager->GetSpawnersByName( "ImaginationSpawn_Min")[0]; - auto* medSpawner = dZoneManager::Instance()->GetSpawnersByName( + auto* medSpawner = Game::zoneManager->GetSpawnersByName( "ImaginationSpawn_Med")[0]; - auto* maxSpawner = dZoneManager::Instance()->GetSpawnersByName( + auto* maxSpawner = Game::zoneManager->GetSpawnersByName( "ImaginationSpawn_Max")[0]; minSpawner->Activate(); @@ -723,7 +723,7 @@ void RacingControlComponent::Update(float deltaTime) { } // Race routines - auto* path = dZoneManager::Instance()->GetZone()->GetPath( + auto* path = Game::zoneManager->GetZone()->GetPath( GeneralUtils::UTF16ToWTF8(m_PathName)); for (auto& player : m_RacingPlayers) { diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 2bf788c3..23c65ae1 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -149,7 +149,7 @@ void ScriptedActivityComponent::PlayerJoinLobby(Entity* player) { auto* character = player->GetCharacter(); if (character != nullptr) - character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZone()->GetWorldID()); + character->SetLastNonInstanceZoneID(Game::zoneManager->GetZone()->GetWorldID()); for (Lobby* lobby : m_Queue) { if (lobby->players.size() < m_ActivityInfo.maxTeamSize || m_ActivityInfo.maxTeamSize == 1 && lobby->players.size() < m_ActivityInfo.maxTeams) { @@ -310,7 +310,7 @@ bool ScriptedActivityComponent::IsValidActivity(Entity* player) { } ChatPackets::SendSystemMessage(player->GetSystemAddress(), u"Sorry, this activity is not ready."); - static_cast(player)->SendToZone(dZoneManager::Instance()->GetZone()->GetWorldID()); // Gets them out of this stuck state + static_cast(player)->SendToZone(Game::zoneManager->GetZone()->GetWorldID()); // Gets them out of this stuck state return false; }*/ diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index 963bfe8f..ab52c4e5 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -26,7 +26,7 @@ TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo uint32_t triggerID; GeneralUtils::TryParse(tokens.at(1), triggerID); - m_Trigger = dZoneManager::Instance()->GetZone()->GetTrigger(sceneID, triggerID); + m_Trigger = Game::zoneManager->GetZone()->GetTrigger(sceneID, triggerID); if (!m_Trigger) m_Trigger = new LUTriggers::Trigger(); } @@ -409,25 +409,25 @@ void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::s } void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->Activate(); } } void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->Deactivate(); } } void TriggerComponent::HandleResetSpawnerNetwork(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->Reset(); } } void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->DestroyAllEntities(); } } diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index ddb7d6f3..83005b6f 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -170,7 +170,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System // After we've done our thing, tell the client they're ready GameMessages::SendPlayerReady(entity, sysAddr); - GameMessages::SendPlayerReady(dZoneManager::Instance()->GetZoneControlObject(), sysAddr); + GameMessages::SendPlayerReady(Game::zoneManager->GetZoneControlObject(), sysAddr); break; } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 390699e4..05f47844 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2355,13 +2355,13 @@ void GameMessages::HandleStartBuildingWithItem(RakNet::BitStream* inStream, Enti void GameMessages::HandlePropertyEditorBegin(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { PropertyManagementComponent::Instance()->OnStartBuilding(); - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyEditBegin(); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyEditBegin(); } void GameMessages::HandlePropertyEditorEnd(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { PropertyManagementComponent::Instance()->OnFinishBuilding(); - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyEditEnd(); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyEditEnd(); } void GameMessages::HandlePropertyContentsFromClient(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -2373,7 +2373,7 @@ void GameMessages::HandlePropertyContentsFromClient(RakNet::BitStream* inStream, } void GameMessages::HandlePropertyModelEquipped(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyModelEquipped(); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyModelEquipped(); } void GameMessages::HandlePlacePropertyModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -2599,7 +2599,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT); //We need to get the propertyID: (stolen from Wincent's propertyManagementComp) - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); @@ -4137,7 +4137,7 @@ void GameMessages::HandleRacingClientReady(RakNet::BitStream* inStream, Entity* return; } - auto* racingControlComponent = dZoneManager::Instance()->GetZoneControlObject()->GetComponent(); + auto* racingControlComponent = Game::zoneManager->GetZoneControlObject()->GetComponent(); if (racingControlComponent == nullptr) { return; @@ -4185,7 +4185,7 @@ void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, inStream->Read(lootOwnerID); } - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); @@ -4228,7 +4228,7 @@ void GameMessages::HandleRacingPlayerInfoResetFinished(RakNet::BitStream* inStre return; } - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); @@ -4258,7 +4258,7 @@ void GameMessages::HandleUpdatePropertyPerformanceCost(RakNet::BitStream* inStre if (performanceCost == 0.0f) return; - auto zone = dZoneManager::Instance()->GetZone(); + auto zone = Game::zoneManager->GetZone(); const auto& worldId = zone->GetZoneID(); const auto cloneId = worldId.GetCloneID(); const auto zoneId = worldId.GetMapID(); @@ -4990,7 +4990,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity } if (mapId == 0) { - mapId = dZoneManager::Instance()->GetZoneID().GetMapID(); // Fallback to sending the player back to the same zone. + mapId = Game::zoneManager->GetZoneID().GetMapID(); // Fallback to sending the player back to the same zone. } Game::logger->Log("FireEventServerSide", "Player %llu has requested zone transfer to (%i, %i).", sender->GetObjectID(), (int)mapId, (int)cloneId); diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index bd5c67e9..34641335 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -34,7 +34,7 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_Timestamp = 0; - m_UniqueMissionID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue(); + m_UniqueMissionID = Game::zoneManager->GetUniqueMissionIdStartingValue(); m_Reward = 0; @@ -443,9 +443,9 @@ void Mission::YieldRewards() { int32_t coinsToSend = 0; if (info->LegoScore > 0) { eLootSourceType lootSource = info->isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; - if (levelComponent->GetLevel() >= dZoneManager::Instance()->GetWorldConfig()->levelCap) { + if (levelComponent->GetLevel() >= Game::zoneManager->GetWorldConfig()->levelCap) { // Since the character is at the level cap we reward them with coins instead of UScore. - coinsToSend += info->LegoScore * dZoneManager::Instance()->GetWorldConfig()->levelCapCurrencyConversion; + coinsToSend += info->LegoScore * Game::zoneManager->GetWorldConfig()->levelCapCurrencyConversion; } else { characterComponent->SetUScore(characterComponent->GetUScore() + info->LegoScore); GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), info->LegoScore, lootSource); diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index 95e97a53..6bc12b72 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -391,7 +391,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& // The meaning of associate can be found in eRacingTaskParam.h if (parameters.empty()) break; - if (!InAllTargets(dZoneManager::Instance()->GetZone()->GetWorldID()) && !(parameters[0] == 4 || parameters[0] == 5) && !InAllTargets(value)) break; + if (!InAllTargets(Game::zoneManager->GetZone()->GetWorldID()) && !(parameters[0] == 4 || parameters[0] == 5) && !InAllTargets(value)) break; if (parameters[0] != associate) break; diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index 5dc55765..d33af6dc 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -195,7 +195,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd uint32_t itemID = static_cast(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(entity->GetComponent(eReplicaComponentType::INVENTORY)); Item* item = nullptr; @@ -203,7 +203,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 { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index e0a69e02..d35beba8 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -272,7 +272,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) { @@ -282,7 +282,7 @@ 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..."); @@ -336,7 +336,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "resurrect") { - ScriptedActivityComponent* scriptedActivityComponent = dZoneManager::Instance()->GetZoneControlObject()->GetComponent(); + ScriptedActivityComponent* scriptedActivityComponent = Game::zoneManager->GetZoneControlObject()->GetComponent(); 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."); @@ -351,7 +351,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()))); } @@ -1541,7 +1541,7 @@ 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) { @@ -1645,13 +1645,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } 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(); @@ -1685,13 +1685,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(); diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index 5fce14d3..35c985eb 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -19,7 +19,7 @@ void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, flo RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE); - auto zone = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zone = Game::zoneManager->GetZone()->GetZoneID(); bitStream.Write(static_cast(zone.GetMapID())); bitStream.Write(static_cast(zone.GetInstanceID())); //bitStream.Write(static_cast(zone.GetCloneID())); diff --git a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp index ada8223a..8d092078 100644 --- a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp @@ -52,7 +52,7 @@ void BossSpiderQueenEnemyServer::OnStartup(Entity* self) { } void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { - if (dZoneManager::Instance()->GetZoneID().GetMapID() == instanceZoneID) { + if (Game::zoneManager->GetZoneID().GetMapID() == instanceZoneID) { auto* missionComponent = killer->GetComponent(); if (missionComponent == nullptr) return; @@ -276,7 +276,7 @@ void BossSpiderQueenEnemyServer::RunRainOfFire(Entity* self) { auto index = 0u; for (const auto& rofGroup : ROFTargetGroupIDTable) { - const auto spawners = dZoneManager::Instance()->GetSpawnersInGroup(rofGroup); + const auto spawners = Game::zoneManager->GetSpawnersInGroup(rofGroup); std::vector spawned; diff --git a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp index f23fa93f..1ee2aba3 100644 --- a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp +++ b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp @@ -42,7 +42,7 @@ void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { const auto nextPipeNum = pipeNum + 1; - const auto samePipeSpawners = dZoneManager::Instance()->GetSpawnersByName(myGroup); + const auto samePipeSpawners = Game::zoneManager->GetSpawnersByName(myGroup); if (!samePipeSpawners.empty()) { samePipeSpawners[0]->SoftReset(); @@ -53,7 +53,7 @@ void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { if (killer != nullptr && killer->IsPlayer()) { const auto nextPipe = pipeGroup + std::to_string(nextPipeNum); - const auto nextPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto nextPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!nextPipeSpawners.empty()) { nextPipeSpawners[0]->Activate(); @@ -61,7 +61,7 @@ void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { } else { const auto nextPipe = pipeGroup + "1"; - const auto firstPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto firstPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!firstPipeSpawners.empty()) { firstPipeSpawners[0]->Activate(); diff --git a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp index ec86b0fa..cf065ad6 100644 --- a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp +++ b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp @@ -93,13 +93,13 @@ void ImgBrickConsoleQB::OnUse(Entity* self, Entity* user) { } void ImgBrickConsoleQB::SpawnBrick(Entity* self) { - const auto netDevil = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug"); + const auto netDevil = Game::zoneManager->GetSpawnersByName("MaelstromBug"); if (!netDevil.empty()) { netDevil[0]->Reset(); netDevil[0]->Deactivate(); } - const auto brick = dZoneManager::Instance()->GetSpawnersByName("Imagination"); + const auto brick = Game::zoneManager->GetSpawnersByName("Imagination"); if (!brick.empty()) { brick[0]->Activate(); } @@ -117,7 +117,7 @@ void ImgBrickConsoleQB::SmashCanister(Entity* self) { canister->Smash(canister->GetObjectID(), eKillType::VIOLENT); } - const auto canister = dZoneManager::Instance()->GetSpawnersByName("BrickCanister"); + const auto canister = Game::zoneManager->GetSpawnersByName("BrickCanister"); if (!canister.empty()) { canister[0]->Reset(); canister[0]->Deactivate(); @@ -195,29 +195,29 @@ void ImgBrickConsoleQB::OnDie(Entity* self, Entity* killer) { const auto firstPipe = pipeGroup + "1"; - const auto samePipeSpawner = dZoneManager::Instance()->GetSpawnersByName(myGroup); + const auto samePipeSpawner = Game::zoneManager->GetSpawnersByName(myGroup); if (!samePipeSpawner.empty()) { samePipeSpawner[0]->Reset(); samePipeSpawner[0]->Deactivate(); } - const auto firstPipeSpawner = dZoneManager::Instance()->GetSpawnersByName(firstPipe); + const auto firstPipeSpawner = Game::zoneManager->GetSpawnersByName(firstPipe); if (!firstPipeSpawner.empty()) { firstPipeSpawner[0]->Activate(); } - const auto netdevil = dZoneManager::Instance()->GetSpawnersByName("Imagination"); + const auto netdevil = Game::zoneManager->GetSpawnersByName("Imagination"); if (!netdevil.empty()) { netdevil[0]->Reset(); netdevil[0]->Deactivate(); } - const auto brick = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug"); + const auto brick = Game::zoneManager->GetSpawnersByName("MaelstromBug"); if (!brick.empty()) { brick[0]->Activate(); } - const auto canister = dZoneManager::Instance()->GetSpawnersByName("BrickCanister"); + const auto canister = Game::zoneManager->GetSpawnersByName("BrickCanister"); if (!canister.empty()) { canister[0]->Activate(); } diff --git a/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp b/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp index c607c0fc..48d1b255 100644 --- a/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp +++ b/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp @@ -57,7 +57,7 @@ void RaceMaelstromGeiser::OnProximityUpdate(Entity* self, Entity* entering, std: GameMessages::SendDie(vehicle, self->GetObjectID(), LWOOBJID_EMPTY, true, eKillType::VIOLENT, u"", 0, 0, 0, true, false, 0); - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index e1bedc5e..0ea78e4f 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -48,8 +48,8 @@ void PetDigServer::OnStartup(Entity* self) { // Reset any bouncers that might've been created by the previous dig if (digInfo.bouncer) { auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar(u"BouncerNumber")); - auto bouncerSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncer" + bounceNumber); - auto switchSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); + auto bouncerSpawners = Game::zoneManager->GetSpawnersByName("PetBouncer" + bounceNumber); + auto switchSpawners = Game::zoneManager->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); for (auto* bouncerSpawner : bouncerSpawners) { for (auto* bouncer : bouncerSpawner->m_Info.nodes) @@ -142,8 +142,8 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe void PetDigServer::HandleBouncerDig(const Entity* self, const Entity* owner) { auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar(u"BouncerNumber")); - auto bouncerSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncer" + bounceNumber); - auto switchSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); + auto bouncerSpawners = Game::zoneManager->GetSpawnersByName("PetBouncer" + bounceNumber); + auto switchSpawners = Game::zoneManager->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); for (auto* bouncerSpawner : bouncerSpawners) { bouncerSpawner->Activate(); diff --git a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp index d7ee5fed..35d4735c 100644 --- a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp +++ b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp @@ -4,7 +4,7 @@ #include "Amf3.h" void NsLegoClubDoor::OnStartup(Entity* self) { - self->SetVar(u"currentZone", (int32_t)dZoneManager::Instance()->GetZoneID().GetMapID()); + self->SetVar(u"currentZone", (int32_t)Game::zoneManager->GetZoneID().GetMapID()); self->SetVar(u"choiceZone", m_ChoiceZoneID); self->SetVar(u"teleportAnim", m_TeleportAnim); self->SetVar(u"teleportString", m_TeleportString); diff --git a/dScripts/02_server/Map/NS/NsLupTeleport.cpp b/dScripts/02_server/Map/NS/NsLupTeleport.cpp index 74f8ace1..c75143fc 100644 --- a/dScripts/02_server/Map/NS/NsLupTeleport.cpp +++ b/dScripts/02_server/Map/NS/NsLupTeleport.cpp @@ -4,7 +4,7 @@ #include "Amf3.h" void NsLupTeleport::OnStartup(Entity* self) { - self->SetVar(u"currentZone", (int32_t)dZoneManager::Instance()->GetZoneID().GetMapID()); + self->SetVar(u"currentZone", (int32_t)Game::zoneManager->GetZoneID().GetMapID()); self->SetVar(u"choiceZone", m_ChoiceZoneID); self->SetVar(u"teleportAnim", m_TeleportAnim); self->SetVar(u"teleportString", m_TeleportString); diff --git a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp index 31086cf4..6f2f6d36 100644 --- a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp @@ -61,7 +61,7 @@ void ZoneAgProperty::OnPlayerLoaded(Entity* self, Entity* player) { self->SetVar(u"numberOfPlayers", numberOfPlayers + 1); } - if (dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID() == 1102) { + if (Game::zoneManager->GetZone()->GetZoneID().GetMapID() == 1102) { GameMessages::SendPlay2DAmbientSound(player, GUIDMaelstrom); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"maelstromSkyOn", 0, 0, LWOOBJID_EMPTY, "", player->GetSystemAddress()); @@ -93,7 +93,7 @@ void ZoneAgProperty::OnZoneLoadedInfo(Entity* self) { void ZoneAgProperty::LoadInstance(Entity* self) { SetGameVariables(self); - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(self->GetVar(InstancerSpawner))) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(self->GetVar(InstancerSpawner))) { for (auto* spawnerNode : spawner->m_Info.nodes) { spawnerNode->config.push_back( new LDFData(u"custom_script_server", @@ -180,7 +180,7 @@ void ZoneAgProperty::StartMaelstrom(Entity* self, Entity* player) { } uint32_t ZoneAgProperty::RetrieveSpawnerId(Entity* self, const std::string& spawner) { - auto spawnerIDs = dZoneManager::Instance()->GetSpawnersByName(spawner); + auto spawnerIDs = Game::zoneManager->GetSpawnersByName(spawner); if (spawnerIDs.empty()) return 0; @@ -193,7 +193,7 @@ void ZoneAgProperty::OnTimerDone(Entity* self, std::string timerName) { void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { if (timerName == "GuardFlyAway") { - const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); + const auto zoneId = Game::zoneManager->GetZone()->GetWorldID(); if (zoneId != 1150) return; diff --git a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp index ecd6a9e2..9bd89067 100644 --- a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp +++ b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp @@ -13,7 +13,7 @@ void CavePrisonCage::OnStartup(Entity* self) { return; } - auto* spawner = dZoneManager::Instance()->GetSpawnersByName("PrisonCounterweight_0" + GeneralUtils::UTF16ToWTF8(myNum))[0]; + auto* spawner = Game::zoneManager->GetSpawnersByName("PrisonCounterweight_0" + GeneralUtils::UTF16ToWTF8(myNum))[0]; self->SetVar(u"CWSpawner", spawner); diff --git a/dScripts/02_server/Map/njhub/Lieutenant.cpp b/dScripts/02_server/Map/njhub/Lieutenant.cpp index d3b0fc1f..74f0e215 100644 --- a/dScripts/02_server/Map/njhub/Lieutenant.cpp +++ b/dScripts/02_server/Map/njhub/Lieutenant.cpp @@ -31,7 +31,7 @@ void Lieutenant::OnDie(Entity* self, Entity* killer) { return; } - const auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); if (spawners.empty()) { return; diff --git a/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp b/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp index dc759c50..a6db5064 100644 --- a/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp +++ b/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp @@ -12,7 +12,7 @@ void MonCoreNookDoors::SpawnDoor(Entity* self) { return; } - const auto spawners = dZoneManager::Instance()->GetSpawnersByName("MonCoreNookDoor0" + doorNum); + const auto spawners = Game::zoneManager->GetSpawnersByName("MonCoreNookDoor0" + doorNum); if (spawners.empty()) { return; diff --git a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp index 459d3e25..d31f7b17 100644 --- a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp +++ b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp @@ -22,7 +22,7 @@ void NjMonastryBossInstance::OnStartup(Entity* self) { // Add a notification request for all the spawned entities, corresponds to notifySpawnedObjectLoaded for (const auto& spawnerName : spawnerNames) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->AddEntitySpawnedCallback([self, this](Entity* entity) { const auto lot = entity->GetLOT(); switch (lot) { @@ -153,7 +153,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string } } } else if (timerName == SpawnCounterWeightTimer) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(CounterweightSpawner); + auto spawners = Game::zoneManager->GetSpawnersByName(CounterweightSpawner); if (!spawners.empty()) { // Spawn the counter weight at a specific waypoint, there's one for each round auto* spawner = spawners.front(); @@ -173,7 +173,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, BottomFrakSpawn, UNASSIGNED_SYSTEM_ADDRESS); } else if (timerName == SpawnLowerFrakjawTimer) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(LowerFrakjawSpawner); + auto spawners = Game::zoneManager->GetSpawnersByName(LowerFrakjawSpawner); if (!spawners.empty()) { auto* spawner = spawners.front(); spawner->Activate(); @@ -182,7 +182,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, FireRailSpawn, UNASSIGNED_SYSTEM_ADDRESS); - auto spawners = dZoneManager::Instance()->GetSpawnersByName(FireRailSpawner); + auto spawners = Game::zoneManager->GetSpawnersByName(FireRailSpawner); if (!spawners.empty()) { auto* spawner = spawners.front(); spawner->Activate(); @@ -210,7 +210,7 @@ void NjMonastryBossInstance::StartFight(Entity* self) { self->SetVar(FightStartedVariable, true); // Activate the frakjaw spawner - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(LedgeFrakjawSpawner)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(LedgeFrakjawSpawner)) { spawner->Activate(); } } @@ -455,7 +455,7 @@ void NjMonastryBossInstance::LowerFrakjaw(Entity* self, Entity* frakjaw) { } void NjMonastryBossInstance::SpawnOnNetwork(Entity* self, const LOT& toSpawn, const uint32_t& numberToSpawn, const std::string& spawnerName) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); if (spawners.empty() || numberToSpawn <= 0) return; @@ -485,7 +485,7 @@ void NjMonastryBossInstance::FightOver(Entity* self) { // Remove all the enemies from the battlefield for (auto i = 1; i < 5; i++) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(BaseEnemiesSpawner + std::to_string(i)); + auto spawners = Game::zoneManager->GetSpawnersByName(BaseEnemiesSpawner + std::to_string(i)); if (!spawners.empty()) { auto* spawner = spawners.front(); spawner->Deactivate(); diff --git a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp index 83f8b30d..e06ed1d9 100644 --- a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp +++ b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp @@ -40,7 +40,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) { sac->PlayerRemove(user->GetObjectID()); - auto* zoneControl = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneControl = Game::zoneManager->GetZoneControlObject(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "Survival_Update", 0); } @@ -56,7 +56,7 @@ uint32_t MinigameTreasureChestServer::CalculateActivityRating(Entity* self, LWOO void MinigameTreasureChestServer::OnStartup(Entity* self) { // BONS treasure chest thinks it's on FV, causing it to start a lobby - if (dZoneManager::Instance()->GetZoneID().GetMapID() == 1204) { + if (Game::zoneManager->GetZoneID().GetMapID() == 1204) { auto* sac = self->GetComponent(); if (sac != nullptr) { sac->SetInstanceMapID(1204); diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index 579ae87a..fe20b09d 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -92,7 +92,7 @@ void BasePropertyServer::BasePlayerLoaded(Entity* self, Entity* player) { Game::entityManager->DestructEntity(plaque); } - const auto& mapID = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& mapID = Game::zoneManager->GetZone()->GetZoneID(); if (propertyOwner > 0) { auto* missionComponent = player->GetComponent(); @@ -278,31 +278,31 @@ void BasePropertyServer::RequestDie(Entity* self, Entity* other) { } void BasePropertyServer::ActivateSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->Activate(); } } void BasePropertyServer::DeactivateSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->Deactivate(); } } void BasePropertyServer::TriggerSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersInGroup(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersInGroup(spawnerName)) { spawner->Spawn(); } } void BasePropertyServer::ResetSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->Reset(); } } void BasePropertyServer::DestroySpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { if (!spawner) return; spawner->DestroyAllEntities(); spawner->Deactivate(); @@ -322,10 +322,10 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam } else if (timerName == StartQuickbuildTimer) { HandleQuickBuildTimer(self); } else if (timerName == "GuardFlyAway") { - const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); + const auto zoneId = Game::zoneManager->GetZone()->GetWorldID(); // No guard for the spider instance fight - if (dZoneManager::Instance()->GetZoneID().GetMapID() == 1150) + if (Game::zoneManager->GetZoneID().GetMapID() == 1150) return; const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(GuardGroup)); @@ -366,7 +366,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam self->AddTimer(TurnSkyOffTimer, 1.5f); self->AddTimer(KillFXObjectTimer, 8.0f); } else if (timerName == TurnSkyOffTimer) { - auto* controller = dZoneManager::Instance()->GetZoneControlObject(); + auto* controller = Game::zoneManager->GetZoneControlObject(); GameMessages::SendNotifyClientObject(controller->GetObjectID(), u"SkyOff", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); } else if (timerName == KillStrombiesTimer) { diff --git a/dScripts/BaseRandomServer.cpp b/dScripts/BaseRandomServer.cpp index 8cc4f993..293fb79a 100644 --- a/dScripts/BaseRandomServer.cpp +++ b/dScripts/BaseRandomServer.cpp @@ -52,7 +52,7 @@ void BaseRandomServer::SpawnSection(Entity* self, const std::string& sectionName } void BaseRandomServer::SetSpawnerNetwork(Entity* self, const std::string& spawnerName, int32_t spawnNum, LOT spawnLOT) { - const auto& spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto& spawners = Game::zoneManager->GetSpawnersByName(spawnerName); if (spawnLOT == 11217 && spawnNum > 1) { spawnNum = 1; diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index 3e32c24b..8859dc02 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -399,7 +399,7 @@ void BaseSurvivalServer::SpawnerReset(SpawnerNetworkCollection& spawnerNetworkCo for (auto& spawner : spawnerNetworkCollection.networks) { for (auto& spawnerName : spawner.names) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName + spawner.number); + auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName + spawner.number); if (!spawners.empty()) { auto* spawnerObject = spawners.at(0); @@ -428,7 +428,7 @@ void BaseSurvivalServer::SpawnerUpdate(Entity* self, SpawnerNetworkCollection& s // If we want to spawn something specific now if (amount != 0) { auto spawnerNetwork = spawnerNetworkCollection.networks.at(0); - auto possibleSpawners = dZoneManager::Instance()->GetSpawnersByName(spawnerNetwork.names.at(0) + spawnerNetwork.number); + auto possibleSpawners = Game::zoneManager->GetSpawnersByName(spawnerNetwork.names.at(0) + spawnerNetwork.number); if (!possibleSpawners.empty()) { SpawnNow(possibleSpawners.at(0), amount); return; @@ -444,7 +444,7 @@ void BaseSurvivalServer::SpawnerUpdate(Entity* self, SpawnerNetworkCollection& s const auto& name = spawnerNetwork.names.at(i); const auto& toSpawn = newSet.at(i); - auto possibleSpawners = dZoneManager::Instance()->GetSpawnersByName(name + spawnerNetwork.number); + auto possibleSpawners = Game::zoneManager->GetSpawnersByName(name + spawnerNetwork.number); if (!possibleSpawners.empty()) { SpawnNow(possibleSpawners.front(), toSpawn); } @@ -495,7 +495,7 @@ SpawnerNetwork BaseSurvivalServer::GetRandomSpawner(SpawnerNetworkCollection& sp void BaseSurvivalServer::ActivateSpawnerNetwork(SpawnerNetworkCollection& spawnerNetworkCollection) { for (auto& spawner : spawnerNetworkCollection.networks) { for (const auto& spawnerName : spawner.names) { - auto possibleSpawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName + spawner.number); + auto possibleSpawners = Game::zoneManager->GetSpawnersByName(spawnerName + spawner.number); if (!possibleSpawners.empty()) { auto* spawnerObject = possibleSpawners.at(0); spawnerObject->Activate(); @@ -509,7 +509,7 @@ void BaseSurvivalServer::UpdateMobLots(SpawnerNetworkCollection& spawnerNetworkC for (auto& spawner : spawnerNetworkCollection.networks) { for (auto& spawnerName : spawner.names) { if (!spawnerName.empty()) { - auto spawnerObjects = dZoneManager::Instance()->GetSpawnersByName(spawnerName + spawner.number); + auto spawnerObjects = Game::zoneManager->GetSpawnersByName(spawnerName + spawner.number); if (!spawnerObjects.empty()) { auto splitName = GeneralUtils::SplitString(spawnerName, '_'); auto cleanName = splitName.size() > 1 ? splitName.at(1) : splitName.at(0); diff --git a/dScripts/BaseWavesGenericEnemy.cpp b/dScripts/BaseWavesGenericEnemy.cpp index 3270e2d8..1e66bfeb 100644 --- a/dScripts/BaseWavesGenericEnemy.cpp +++ b/dScripts/BaseWavesGenericEnemy.cpp @@ -6,7 +6,7 @@ void BaseWavesGenericEnemy::OnStartup(Entity* self) { } void BaseWavesGenericEnemy::OnDie(Entity* self, Entity* killer) { - auto* zoneControlObject = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneControlObject = Game::zoneManager->GetZoneControlObject(); if (zoneControlObject != nullptr) { zoneControlObject->OnFireEventServerSide(killer, "Survival_Update", GetPoints()); } diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index fcaa548e..4add13e6 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -392,7 +392,7 @@ void BaseWavesServer::GameWon(Entity* self) { // Done void BaseWavesServer::SpawnNow(const std::string& spawnerName, uint32_t amount, LOT spawnLot) { - const auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); for (auto* spawner : spawners) { if (spawnLot != LOT_NULL) { spawner->SetSpawnLot(spawnLot); @@ -581,7 +581,7 @@ void BaseWavesServer::UpdateMissionForAllPlayers(Entity* self, uint32_t missionI void BaseWavesServer::ClearSpawners() { for (const auto& spawnerName : spawners) { - const auto spawnerObjects = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto spawnerObjects = Game::zoneManager->GetSpawnersByName(spawnerName); for (auto* spawnerObject : spawnerObjects) { spawnerObject->Reset(); diff --git a/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp b/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp index 595da4db..90333063 100644 --- a/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp +++ b/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp @@ -42,7 +42,7 @@ void ActVehicleDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { GameMessages::SendDie(vehicle, self->GetObjectID(), LWOOBJID_EMPTY, true, eKillType::VIOLENT, u"", 0, 0, 0, true, false, 0); - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); diff --git a/dScripts/ai/FV/FvBrickPuzzleServer.cpp b/dScripts/ai/FV/FvBrickPuzzleServer.cpp index 887b9a4d..ce12d76e 100644 --- a/dScripts/ai/FV/FvBrickPuzzleServer.cpp +++ b/dScripts/ai/FV/FvBrickPuzzleServer.cpp @@ -29,7 +29,7 @@ void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { const auto nextPipeNum = pipeNum + 1; - const auto samePipeSpawners = dZoneManager::Instance()->GetSpawnersByName(myGroup); + const auto samePipeSpawners = Game::zoneManager->GetSpawnersByName(myGroup); if (!samePipeSpawners.empty()) { samePipeSpawners[0]->SoftReset(); @@ -40,7 +40,7 @@ void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { if (killer != nullptr && killer->IsPlayer()) { const auto nextPipe = pipeGroup + std::to_string(nextPipeNum); - const auto nextPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto nextPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!nextPipeSpawners.empty()) { nextPipeSpawners[0]->Activate(); @@ -48,7 +48,7 @@ void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { } else { const auto nextPipe = pipeGroup + "1"; - const auto firstPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto firstPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!firstPipeSpawners.empty()) { firstPipeSpawners[0]->Activate(); diff --git a/dScripts/ai/FV/FvFacilityBrick.cpp b/dScripts/ai/FV/FvFacilityBrick.cpp index d1014ed6..26c07647 100644 --- a/dScripts/ai/FV/FvFacilityBrick.cpp +++ b/dScripts/ai/FV/FvFacilityBrick.cpp @@ -9,9 +9,9 @@ void FvFacilityBrick::OnStartup(Entity* self) { } void FvFacilityBrick::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) { - auto* brickSpawner = dZoneManager::Instance()->GetSpawnersByName("ImaginationBrick")[0]; - auto* bugSpawner = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug")[0]; - auto* canisterSpawner = dZoneManager::Instance()->GetSpawnersByName("BrickCanister")[0]; + auto* brickSpawner = Game::zoneManager->GetSpawnersByName("ImaginationBrick")[0]; + auto* bugSpawner = Game::zoneManager->GetSpawnersByName("MaelstromBug")[0]; + auto* canisterSpawner = Game::zoneManager->GetSpawnersByName("BrickCanister")[0]; if (name == "ConsoleLeftUp") { GameMessages::SendStopFXEffect(self, true, "LeftPipeOff"); diff --git a/dScripts/ai/GF/GfJailWalls.cpp b/dScripts/ai/GF/GfJailWalls.cpp index 1835faa2..1efca1cf 100644 --- a/dScripts/ai/GF/GfJailWalls.cpp +++ b/dScripts/ai/GF/GfJailWalls.cpp @@ -6,11 +6,11 @@ void GfJailWalls::OnRebuildComplete(Entity* self, Entity* target) { const auto wall = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Wall")); - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("Jail0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("Jail0" + wall)) { spawner->Deactivate(); } - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("JailCaptain0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("JailCaptain0" + wall)) { spawner->Deactivate(); } } @@ -20,11 +20,11 @@ void GfJailWalls::OnRebuildNotifyState(Entity* self, eRebuildState state) { const auto wall = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Wall")); - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("Jail0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("Jail0" + wall)) { spawner->Activate(); } - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("JailCaptain0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("JailCaptain0" + wall)) { spawner->Activate(); } } diff --git a/dScripts/ai/GF/TriggerAmbush.cpp b/dScripts/ai/GF/TriggerAmbush.cpp index 726b45d7..7ac329ea 100644 --- a/dScripts/ai/GF/TriggerAmbush.cpp +++ b/dScripts/ai/GF/TriggerAmbush.cpp @@ -13,7 +13,7 @@ void TriggerAmbush::OnProximityUpdate(Entity* self, Entity* entering, std::strin self->SetVar(u"triggered", true); - const auto spawners = dZoneManager::Instance()->GetSpawnersByName("Ambush"); + const auto spawners = Game::zoneManager->GetSpawnersByName("Ambush"); for (auto* spawner : spawners) { spawner->Activate(); @@ -27,7 +27,7 @@ void TriggerAmbush::OnTimerDone(Entity* self, std::string timerName) { self->SetVar(u"triggered", false); - const auto spawners = dZoneManager::Instance()->GetSpawnersByName("Ambush"); + const auto spawners = Game::zoneManager->GetSpawnersByName("Ambush"); for (auto* spawner : spawners) { spawner->Reset(); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 4121bfdf..435f0927 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -142,7 +142,7 @@ void SGCannon::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button if (identifier == u"Scoreboardinfo") { GameMessages::SendDisplayMessageBox(player->GetObjectID(), true, - dZoneManager::Instance()->GetZoneControlObject()->GetObjectID(), + Game::zoneManager->GetZoneControlObject()->GetObjectID(), u"Shooting_Gallery_Retry", 2, u"Retry?", u"", player->GetSystemAddress()); } else { @@ -262,7 +262,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { } const auto& toSpawn = activeSpawns.at(spawnNumber); const auto pathIndex = GeneralUtils::GenerateRandomNumber(0, toSpawn.spawnPaths.size() - 1); - const auto* path = dZoneManager::Instance()->GetZone()->GetPath(toSpawn.spawnPaths.at(pathIndex)); + const auto* path = Game::zoneManager->GetZone()->GetPath(toSpawn.spawnPaths.at(pathIndex)); if (!path) { Game::logger->Log("SGCannon", "Path %s at index %i is null", toSpawn.spawnPaths.at(pathIndex).c_str(), pathIndex); return; diff --git a/dScripts/ai/PROPERTY/AgPropguards.cpp b/dScripts/ai/PROPERTY/AgPropguards.cpp index 60a153a6..c514031a 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.cpp +++ b/dScripts/ai/PROPERTY/AgPropguards.cpp @@ -29,7 +29,7 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission if (spawnerName.empty()) spawnerName = "Guard"; - auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); for (auto* spawner : spawners) { spawner->Deactivate(); } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 44796224..f07c17e3 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -85,6 +85,7 @@ namespace Game { SystemAddress chatSysAddr; bool shouldShutdown = false; EntityManager* entityManager = nullptr; + dZoneManager* zoneManager = nullptr; } // namespace Game bool chatDisabled = false; @@ -254,10 +255,11 @@ int main(int argc, char** argv) { PerformanceManager::SelectProfile(zoneID); Game::entityManager = new EntityManager(); + Game::zoneManager = new dZoneManager(); //Load our level: if (zoneID != 0) { dpWorld::Instance().Initialize(zoneID); - dZoneManager::Instance()->Initialize(LWOZONEID(zoneID, instanceID, cloneID)); + Game::zoneManager->Initialize(LWOZONEID(zoneID, instanceID, cloneID)); g_CloneID = cloneID; // pre calculate the FDB checksum @@ -399,7 +401,7 @@ int main(int argc, char** argv) { Metrics::EndMeasurement(MetricVariable::Ghosting); Metrics::StartMeasurement(MetricVariable::UpdateSpawners); - dZoneManager::Instance()->Update(deltaTime); + Game::zoneManager->Update(deltaTime); Metrics::EndMeasurement(MetricVariable::UpdateSpawners); } @@ -776,7 +778,7 @@ void HandlePacket(Packet* packet) { //Create our user and send them in: UserManager::Instance()->CreateUser(it->second.sysAddr, username, userHash); - auto zone = dZoneManager::Instance()->GetZone(); + auto zone = Game::zoneManager->GetZone(); if (zone) { float x = 0.0f; float y = 0.0f; @@ -1015,7 +1017,7 @@ void HandlePacket(Packet* packet) { WorldPackets::SendCreateCharacter(packet->systemAddress, player, c->GetXMLData(), username, c->GetGMLevel()); WorldPackets::SendServerState(packet->systemAddress); - const auto respawnPoint = player->GetCharacter()->GetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID()); + const auto respawnPoint = player->GetCharacter()->GetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID()); Game::entityManager->ConstructEntity(player, UNASSIGNED_SYSTEM_ADDRESS, true); @@ -1065,7 +1067,7 @@ void HandlePacket(Packet* packet) { //Tell the player to generate BBB models, if any: if (g_CloneID != 0) { - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = Game::server->GetZoneID(); const auto cloneId = g_CloneID; @@ -1175,7 +1177,7 @@ void HandlePacket(Packet* packet) { bitStream.Write(playerName[i]); } - auto zone = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zone = Game::zoneManager->GetZone()->GetZoneID(); bitStream.Write(zone.GetMapID()); bitStream.Write(zone.GetInstanceID()); bitStream.Write(zone.GetCloneID()); @@ -1332,10 +1334,11 @@ void FinalizeShutdown() { Metrics::Clear(); Database::Destroy("WorldServer"); if (Game::chatFilter) delete Game::chatFilter; + if (Game::zoneManager) delete Game::zoneManager; if (Game::server) delete Game::server; - if (Game::logger) delete Game::logger; if (Game::config) delete Game::config; if (Game::entityManager) delete Game::entityManager; + if (Game::logger) delete Game::logger; worldShutdownSequenceComplete = true; diff --git a/dZoneManager/Level.cpp b/dZoneManager/Level.cpp index 3a1cbb45..7d248588 100644 --- a/dZoneManager/Level.cpp +++ b/dZoneManager/Level.cpp @@ -179,8 +179,8 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { //This is a little bit of a bodge, but because the alpha client (HF) doesn't store the //spawn position / rotation like the later versions do, we need to check the LOT for the spawn pos & set it. if (obj.lot == LOT_MARKER_PLAYER_START) { - dZoneManager::Instance()->GetZone()->SetSpawnPos(obj.position); - dZoneManager::Instance()->GetZone()->SetSpawnRot(obj.rotation); + Game::zoneManager->GetZone()->SetSpawnPos(obj.position); + Game::zoneManager->GetZone()->SetSpawnRot(obj.rotation); } std::u16string ldfString = u""; @@ -297,7 +297,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { } } Spawner* spawner = new Spawner(spawnInfo); - dZoneManager::Instance()->AddSpawner(obj.id, spawner); + Game::zoneManager->AddSpawner(obj.id, spawner); } else { //Regular object EntityInfo info; info.spawnerID = 0; @@ -328,7 +328,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { if (!clientOnly) { // We should never have more than 1 zone control object - const auto zoneControlObject = dZoneManager::Instance()->GetZoneControlObject(); + const auto zoneControlObject = Game::zoneManager->GetZoneControlObject(); if (zoneControlObject != nullptr && info.lot == zoneControlObject->GetLOT()) goto deleteSettings; diff --git a/dZoneManager/Spawner.cpp b/dZoneManager/Spawner.cpp index bf01103d..bd1970c6 100644 --- a/dZoneManager/Spawner.cpp +++ b/dZoneManager/Spawner.cpp @@ -47,8 +47,8 @@ Spawner::Spawner(const SpawnerInfo info) { if (m_Info.spawnOnSmashGroupName != "") { std::vector spawnSmashEntities = Game::entityManager->GetEntitiesInGroup(m_Info.spawnOnSmashGroupName); - std::vector spawnSmashSpawners = dZoneManager::Instance()->GetSpawnersInGroup(m_Info.spawnOnSmashGroupName); - std::vector spawnSmashSpawnersN = dZoneManager::Instance()->GetSpawnersByName(m_Info.spawnOnSmashGroupName); + std::vector spawnSmashSpawners = Game::zoneManager->GetSpawnersInGroup(m_Info.spawnOnSmashGroupName); + std::vector spawnSmashSpawnersN = Game::zoneManager->GetSpawnersByName(m_Info.spawnOnSmashGroupName); for (Entity* ssEntity : spawnSmashEntities) { m_SpawnSmashFoundGroup = true; ssEntity->AddDieCallback([=]() { diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 28d3f0c8..7343bb59 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -149,7 +149,7 @@ void Zone::LoadZoneIntoMemory() { info.activeOnLoad = path.spawner.spawnerNetActive; info.isNetwork = true; Spawner* spawner = new Spawner(info); - dZoneManager::Instance()->AddSpawner(info.spawnerID, spawner); + Game::zoneManager->AddSpawner(info.spawnerID, spawner); } } diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 960726a2..51f6e640 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -17,8 +17,6 @@ #include "../dWorldServer/ObjectIDManager.h" -dZoneManager* dZoneManager::m_Address = nullptr; - void dZoneManager::Initialize(const LWOZONEID& zoneID) { Game::logger->Log("dZoneManager", "Preparing zone: %i/%i/%i", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID()); diff --git a/dZoneManager/dZoneManager.h b/dZoneManager/dZoneManager.h index 3086e6d7..1e08b008 100644 --- a/dZoneManager/dZoneManager.h +++ b/dZoneManager/dZoneManager.h @@ -25,14 +25,6 @@ private: void LoadWorldConfig(); public: - static dZoneManager* Instance() { - if (!m_Address) { - m_Address = new dZoneManager(); - } - - return m_Address; - } - void Initialize(const LWOZONEID& zoneID); ~dZoneManager(); @@ -64,7 +56,6 @@ private: */ uint32_t m_UniqueMissionIdStart = 0; - static dZoneManager* m_Address; //Singleton Zone* m_pZone = nullptr; LWOZONEID m_ZoneID; bool m_PlayerLoseCoinsOnDeath; //Do players drop coins in this zone when smashed From 11b0097488c812021b4732f2079e64e23691f3ea Mon Sep 17 00:00:00 2001 From: TAHuntling <38479763+TAHuntling@users.noreply.github.com> Date: Wed, 19 Jul 2023 11:07:41 -0500 Subject: [PATCH 106/116] freemoney type update (#1146) Changed freemoney command to parse 64 bit integers as opposed to 32 bit --- dGame/dUtilities/SlashCommandHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index d35beba8..03e3cc89 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1443,7 +1443,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."); From 342da566788474e62436e280a1444f3b156c8e79 Mon Sep 17 00:00:00 2001 From: TAHuntling <38479763+TAHuntling@users.noreply.github.com> Date: Fri, 21 Jul 2023 19:37:31 -0500 Subject: [PATCH 107/116] Added Player Rewards for Solo Racing (#1150) * Added Player Rewards for Solo Racing * Fixed Dual PlayersRating multiplication * Checking for solo player fixed * Another change to fix issues --- dGame/dComponents/RacingControlComponent.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index d669049d..d3fb7099 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -374,8 +374,12 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu data->collectedRewards = true; // Calculate the score, different loot depending on player count - const auto score = m_LoadedPlayers * 10 + data->finished; + auto playersRating = m_LoadedPlayers; + if(m_LoadedPlayers == 1 && m_SoloRacing) { + playersRating *= 2; + } + const auto score = playersRating * 10 + data->finished; LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); // Giving rewards From cc251d0986d5e9f3ab5106fbc089087dcc530e95 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 21 Jul 2023 19:39:44 -0700 Subject: [PATCH 108/116] Update ActivityManager.cpp --- dScripts/ActivityManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index fbe22da8..24e661e3 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -80,7 +80,7 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const } void ActivityManager::SaveScore(Entity* self, const LWOOBJID playerID, const float primaryScore, const float secondaryScore, const float tertiaryScore) const { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (!player) return; auto* sac = self->GetComponent(); From 887e2a25f08a9572a7f2ef768ba3ebef39c29b73 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 21 Jul 2023 23:18:51 -0700 Subject: [PATCH 109/116] Fix race score bugs num wins serialized properly scores are saved and num wins and times played are incremented properly --- dGame/LeaderboardManager.cpp | 19 +++++++++++++++---- dGame/dComponents/RacingControlComponent.cpp | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 71efe141..a4c6ec1a 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -103,7 +103,7 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { // BestTime:3 entry.push_back(new LDFData(u"License", 1)); // License:1 - 1 if player has completed mission 637 and 0 otherwise - entry.push_back(new LDFData(u"NumWins", rows->getInt("tertiaryScore"))); + entry.push_back(new LDFData(u"NumWins", rows->getInt("numWins"))); // NumWins:1 break; case Type::UnusedLeaderboard4: @@ -342,6 +342,11 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi case Leaderboard::Type::Racing: { oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); + + // For wins we dont care about the score, just the time, so zero out the tertiary. + // Wins are updated later. + oldScore.SetTertiaryScore(0); + newScore.SetTertiaryScore(0); lowerScoreBetter = true; break; } @@ -368,17 +373,23 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi } if (newHighScore) { saveQuery = FormatInsert(leaderboardType, newScore, true); - } else if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore) { - saveQuery = "UPDATE leaderboard SET numWins = numWins + 1, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"; } } else { saveQuery = FormatInsert(leaderboardType, newScore, false); } - + Game::logger->Log("LeaderboardManager", "save query %s %i %i", saveQuery.c_str(), playerID, activityId); std::unique_ptr saveStatement(Database::CreatePreppedStmt(saveQuery)); saveStatement->setInt(1, playerID); saveStatement->setInt(2, activityId); saveStatement->execute(); + + // track wins separately + if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore != 0.0f) { + std::unique_ptr winUpdate(Database::CreatePreppedStmt("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;")); + winUpdate->setInt(1, playerID); + winUpdate->setInt(2, activityId); + winUpdate->execute(); + } } void LeaderboardManager::SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart, const uint32_t resultEnd) { diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 1f3e144a..5de24445 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -838,7 +838,7 @@ void RacingControlComponent::Update(float deltaTime) { "Completed time %llu, %llu", raceTime, raceTime * 1000); - LeaderboardManager::SaveScore(playerEntity->GetObjectID(), m_ActivityID, static_cast(player.bestLapTime), static_cast(player.raceTime), static_cast(player.finished == 1)); + LeaderboardManager::SaveScore(playerEntity->GetObjectID(), m_ActivityID, static_cast(player.raceTime), static_cast(player.bestLapTime), static_cast(player.finished == 1)); // Entire race time missionComponent->Progress(eMissionTaskType::RACING, (raceTime) * 1000, (LWOOBJID)eRacingTaskParam::TOTAL_TRACK_TIME); From a625d2eae5d80ea56e19568c7d1fb69d6301032e Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 21 Jul 2023 23:42:50 -0700 Subject: [PATCH 110/116] Update SGCannon.cpp --- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index d825d8cf..4aa8d0c9 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -564,9 +564,10 @@ void SGCannon::StopGame(Entity* self, bool cancel) { LootGenerator::Instance().GiveActivityLoot(player, self, GetGameID(self), self->GetVar(TotalScoreVariable)); - StopActivity(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), self->GetVar(MaxStreakVariable), percentage); SaveScore(self, player->GetObjectID(), static_cast(self->GetVar(TotalScoreVariable)), static_cast(self->GetVar(MaxStreakVariable)), percentage); + + StopActivity(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), self->GetVar(MaxStreakVariable), percentage); self->SetNetworkVar(AudioFinalWaveDoneVariable, true); // Give the player the model rewards they earned From b87537c637a40736a68545a99c2c833c39b76745 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 22 Jul 2023 02:16:53 -0700 Subject: [PATCH 111/116] bump minor version --- CMakeVariables.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeVariables.txt b/CMakeVariables.txt index d3c8b36f..02173ba7 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -1,6 +1,6 @@ PROJECT_VERSION_MAJOR=1 -PROJECT_VERSION_MINOR=0 -PROJECT_VERSION_PATCH=4 +PROJECT_VERSION_MINOR=1 +PROJECT_VERSION_PATCH=0 # LICENSE LICENSE=AGPL-3.0 # The network version. From 54454973a118739f383418d9b4feee410d058ac5 Mon Sep 17 00:00:00 2001 From: TAHuntling <38479763+TAHuntling@users.noreply.github.com> Date: Sat, 22 Jul 2023 04:49:23 -0500 Subject: [PATCH 112/116] Distance for pet digs increased slightly to help with navmesh issues (#1151) --- dGame/dComponents/PetComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index c2843266..167fbb2f 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -449,7 +449,7 @@ void PetComponent::Update(float deltaTime) { NiPoint3 tresurePosition = closestTresure->GetPosition(); float distance = Vector3::DistanceSquared(position, tresurePosition); - if (distance < 3 * 3) { + if (distance < 5 * 5) { m_Interaction = closestTresure->GetObjectID(); Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, 202, true); From c791d1a237f59b6bf3ea2028004de98a942254fd Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 23 Jul 2023 12:09:07 -0700 Subject: [PATCH 113/116] feature: Auto update of ini files (#1154) * Add auto update of ini files Tested that config options that currently exist are not modified. Tested that if the exact variable name is not located in the destination ini, the config option is added along with all of its corresponding comments. Comments in the build files are ignored to prevent any possible name collision with comments. * Fix typos and empty file issue --- CMakeLists.txt | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d4219f..8f8981ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,15 +97,56 @@ make_directory(${CMAKE_BINARY_DIR}/logs) # Copy resource files on first build set(RESOURCE_FILES "sharedconfig.ini" "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blacklist.dcf") -foreach(resource_file ${RESOURCE_FILES}) - if (NOT EXISTS ${PROJECT_BINARY_DIR}/${resource_file}) +message(STATUS "Checking resource file integrity") +foreach (resource_file ${RESOURCE_FILES}) + set(file_size 0) + if (EXISTS ${PROJECT_BINARY_DIR}/${resource_file}) + file(SIZE ${PROJECT_BINARY_DIR}/${resource_file} file_size) + endif() + if (${file_size} EQUAL 0) configure_file( ${CMAKE_SOURCE_DIR}/resources/${resource_file} ${PROJECT_BINARY_DIR}/${resource_file} COPYONLY ) - message("Moved ${resource_file} to project binary directory") + message(STATUS "Moved " ${resource_file} " to project binary directory") + elseif (resource_file MATCHES ".ini") + message(STATUS "Checking " ${resource_file} " for missing config options") + file(READ ${PROJECT_BINARY_DIR}/${resource_file} current_file_contents) + string(REPLACE "\\\n" "" current_file_contents ${current_file_contents}) + string(REPLACE "\n" ";" current_file_contents ${current_file_contents}) + set(parsed_current_file_contents "") + # Remove comment lines so they do not interfere with the variable parsing + foreach (line ${current_file_contents}) + string(FIND ${line} "#" is_comment) + if (NOT ${is_comment} EQUAL 0) + string(APPEND parsed_current_file_contents ${line}) + endif() + endforeach() + file(READ ${CMAKE_SOURCE_DIR}/resources/${resource_file} depot_file_contents) + string(REPLACE "\\\n" "" depot_file_contents ${depot_file_contents}) + string(REPLACE "\n" ";" depot_file_contents ${depot_file_contents}) + set(line_to_add "") + foreach (line ${depot_file_contents}) + string(FIND ${line} "#" is_comment) + if (NOT ${is_comment} EQUAL 0) + string(REPLACE "=" ";" line_split ${line}) + list(GET line_split 0 variable_name) + if (NOT ${parsed_current_file_contents} MATCHES ${variable_name}) + message(STATUS "Adding missing config option " ${variable_name} " to " ${resource_file}) + set(line_to_add ${line_to_add} ${line}) + foreach (line_to_append ${line_to_add}) + file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n" ${line_to_append}) + endforeach() + file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n") + endif() + set(line_to_add "") + else() + set(line_to_add ${line_to_add} ${line}) + endif() + endforeach() endif() endforeach() +message(STATUS "Resource file integrity check complete") # Copy navmesh data on first build and extract it if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes/) From bd5ead40f64fd33fcacfa08f90e558cd46c62e17 Mon Sep 17 00:00:00 2001 From: avery Date: Sun, 23 Jul 2023 14:59:43 -0700 Subject: [PATCH 114/116] feat: upgrade session keys to use mersenne twister (#1155) * upgrade session keys to use mersenne twister * arithmetic type static assert and windows min/max macro undef --- dAuthServer/AuthServer.cpp | 3 ++ dCommon/GeneralUtils.h | 61 ++++++++++++++++++++++++-------------- dNet/AuthPackets.cpp | 3 +- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 262886d7..38910823 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -29,6 +29,7 @@ namespace Game { dServer* server = nullptr; dConfig* config = nullptr; bool shouldShutdown = false; + std::mt19937 randomEngine; } dLogger* SetupLogger(); @@ -83,6 +84,8 @@ int main(int argc, char** argv) { delete res; delete stmt; + Game::randomEngine = std::mt19937(time(0)); + //It's safe to pass 'localhost' here, as the IP is only used as the external IP. uint32_t maxClients = 50; uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 0a8a0a16..e9e20ba0 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -111,29 +111,6 @@ namespace GeneralUtils { */ bool CheckBit(int64_t value, uint32_t index); - // MARK: Random Number Generation - - //! Generates a random number - /*! - \param min The minimum the generate from - \param max The maximum to generate to - */ - template - inline T GenerateRandomNumber(std::size_t min, std::size_t max) { - // Make sure it is a numeric type - static_assert(std::is_arithmetic::value, "Not an arithmetic type"); - - if constexpr (std::is_integral_v) { // constexpr only necessary on first statement - std::uniform_int_distribution distribution(min, max); - return distribution(Game::randomEngine); - } else if (std::is_floating_point_v) { - std::uniform_real_distribution distribution(min, max); - return distribution(Game::randomEngine); - } - - return T(); - } - bool ReplaceInString(std::string& str, const std::string& from, const std::string& to); std::u16string ReadWString(RakNet::BitStream* inStream); @@ -223,4 +200,42 @@ namespace GeneralUtils { std::hash h; s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2); } + + // MARK: Random Number Generation + + //! Generates a random number + /*! + \param min The minimum the generate from + \param max The maximum to generate to + */ + template + inline T GenerateRandomNumber(std::size_t min, std::size_t max) { + // Make sure it is a numeric type + static_assert(std::is_arithmetic::value, "Not an arithmetic type"); + + if constexpr (std::is_integral_v) { // constexpr only necessary on first statement + std::uniform_int_distribution distribution(min, max); + return distribution(Game::randomEngine); + } else if (std::is_floating_point_v) { + std::uniform_real_distribution distribution(min, max); + return distribution(Game::randomEngine); + } + + return T(); + } + +// on Windows we need to undef these or else they conflict with our numeric limits calls +// DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS +#ifdef _WIN32 +#undef min +#undef max +#endif + + template + inline T GenerateRandomNumber() { + // Make sure it is a numeric type + static_assert(std::is_arithmetic::value, "Not an arithmetic type"); + + return GenerateRandomNumber(std::numeric_limits::min(), std::numeric_limits::max()); + } } diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 4bbb0576..978540c1 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -8,6 +8,7 @@ #include "ZoneInstanceManager.h" #include "MD5.h" #include "SHA512.h" +#include "GeneralUtils.h" #ifdef _WIN32 #include @@ -211,7 +212,7 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd packet.Write(static_cast(64)); // Version Minor // Writes the user key - uint32_t sessionKey = rand(); // not mt but whatever + uint32_t sessionKey = GeneralUtils::GenerateRandomNumber(); std::string userHash = std::to_string(sessionKey); userHash = md5(userHash); PacketUtils::WritePacketWString(userHash, 33, &packet); From 0610fe99f85b4e1c66dd6b3d6bdecee106f561d8 Mon Sep 17 00:00:00 2001 From: TAHuntling <38479763+TAHuntling@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:04:45 -0500 Subject: [PATCH 115/116] fix: Nexus Tower Combat Challenge can be started twice if two players start it at the same time (#1147) * Nexus Tower Dummy Challenge Dual Instance Fix Fix for dual instance starting when two players hit start on the challenge at the same time. * Changed GetVar to GetNetworkVar Changed the if statement to GetNetworkVar boolean of bInUse rather than GetVar boolean of bInUse --- dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp index 2c2f84c2..011a67ea 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp @@ -43,7 +43,7 @@ void NtCombatChallengeServer::OnFireEventServerSide(Entity* self, Entity* sender void NtCombatChallengeServer::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) { - if (identifier == u"PlayButton" && button == 1) { + if (identifier == u"PlayButton" && button == 1 && !self->GetNetworkVar(u"bInUse")) { self->SetNetworkVar(u"bInUse", true); self->SetVar(u"playerID", sender->GetObjectID()); From 304af7922a84f8585c92cbf898c5c5747cab3bd2 Mon Sep 17 00:00:00 2001 From: Daniel Seiler Date: Mon, 24 Jul 2023 03:51:13 +0200 Subject: [PATCH 116/116] Update MariaDB for windows (#792) * Update CMakeMariaDBLists.txt * Update CMakeMariaDBLists.txt --------- Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Co-authored-by: David Markowitz --- thirdparty/CMakeMariaDBLists.txt | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/thirdparty/CMakeMariaDBLists.txt b/thirdparty/CMakeMariaDBLists.txt index cb1e28e7..81b15a6f 100644 --- a/thirdparty/CMakeMariaDBLists.txt +++ b/thirdparty/CMakeMariaDBLists.txt @@ -10,30 +10,42 @@ if(WIN32 AND NOT MARIADB_BUILD_SOURCE) file(MAKE_DIRECTORY "${MARIADB_MSI_DIR}") file(MAKE_DIRECTORY "${MARIADB_CONNECTOR_DIR}") - if(NOT EXISTS "${MARIADB_MSI_DIR}/mariadb-connector-c-3.2.5-win64.msi" ) + # These values need to be updated whenever a new minor release replaces an old one + # Go to https://mariadb.com/downloads/connectors/ to find the up-to-date URL parts + set(MARIADB_CONNECTOR_C_VERSION "3.2.7") + set(MARIADB_CONNECTOR_C_BUCKET "2319651") + set(MARIADB_CONNECTOR_C_MD5 "f8636d733f1d093af9d4f22f3239f885") + set(MARIADB_CONNECTOR_CPP_VERSION "1.0.2") + set(MARIADB_CONNECTOR_CPP_BUCKET "2531525") + set(MARIADB_CONNECTOR_CPP_MD5 "3034bbd6ca00a0125345f9fd1a178401") + + set(MARIADB_CONNECTOR_C_MSI "mariadb-connector-c-${MARIADB_CONNECTOR_C_VERSION}-win64.msi") + set(MARIADB_CONNECTOR_CPP_MSI "mariadb-connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}-win64.msi") + + if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" ) message("Downloading mariadb connector/c") - file(DOWNLOAD https://dlm.mariadb.com/1936366/connectors/c/connector-c-3.2.5/mariadb-connector-c-3.2.5-win64.msi - "${MARIADB_MSI_DIR}/mariadb-connector-c-3.2.5-win64.msi" - EXPECTED_HASH MD5=09d418c290109068a5bea136dafca36b) + file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_C_BUCKET}/Connectors/c/connector-c-${MARIADB_CONNECTOR_C_VERSION}/${MARIADB_CONNECTOR_C_MSI} + "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" + EXPECTED_HASH MD5=${MARIADB_CONNECTOR_C_MD5}) endif() - if(NOT EXISTS "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.msi" ) + if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" ) message("Downloading mariadb connector/c++") - file(DOWNLOAD https://dlm.mariadb.com/1683453/connectors/cpp/connector-cpp-1.0.1/mariadb-connector-cpp-1.0.1-win64.msi - "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.msi" - EXPECTED_HASH MD5=548e743fbf067d21d42b81d958bf4ed7) + file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_CPP_BUCKET}/Connectors/cpp/connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}/${MARIADB_CONNECTOR_CPP_MSI} + "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" + EXPECTED_HASH MD5=${MARIADB_CONNECTOR_CPP_MD5}) endif() file(TO_NATIVE_PATH "${MARIADB_CONNECTOR_DIR}" MSIEXEC_TARGETDIR) # extract msi files without installing to users system if(NOT EXISTS "${MARIADB_C_CONNECTOR_DIR}") - file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/mariadb-connector-c-3.2.5-win64.msi" MSI_DIR) + file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" MSI_DIR) execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) endif() if(NOT EXISTS "${MARIADB_CPP_CONNECTOR_DIR}") - file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.msi" MSI_DIR) + file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" MSI_DIR) execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) endif()