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 001/111] 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 002/111] 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 003/111] 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 004/111] 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 005/111] 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 006/111] 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 007/111] 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 008/111] 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 009/111] 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 010/111] 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 011/111] 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 012/111] 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 013/111] 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 014/111] 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 015/111] 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 016/111] 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 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 017/111] 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 018/111] 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 0f307ac4be582950f306a275c0dd35ad0ef9187c Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 8 May 2023 02:46:55 -0700 Subject: [PATCH 019/111] 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 020/111] 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 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 021/111] 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 022/111] 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 023/111] 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 fcf5c5ea8a722b63256bed616ab2ac86516ee412 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 9 May 2023 00:06:26 -0700 Subject: [PATCH 024/111] 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 025/111] 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 026/111] 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 027/111] 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 028/111] 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 029/111] 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 f26e66da4d1fe8a2575ba81d961f21921e7b6d9c Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 28 May 2023 04:30:20 -0700 Subject: [PATCH 030/111] 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 031/111] 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 032/111] 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 033/111] 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 034/111] 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 035/111] 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 036/111] 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 037/111] 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 038/111] 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 039/111] 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 040/111] 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 041/111] 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 96fc6e81d88298a88d4c9ec615a542891eb5d190 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Mon, 5 Jun 2023 02:24:00 -0700 Subject: [PATCH 042/111] 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 043/111] 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 044/111] 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 045/111] 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 046/111] 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 047/111] 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 048/111] 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 049/111] 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 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 050/111] 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 051/111] 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 052/111] 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 053/111] 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 054/111] 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 055/111] 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 056/111] 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 057/111] 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 058/111] 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 059/111] 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 060/111] 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 061/111] 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 062/111] 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 063/111] 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 064/111] 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 065/111] 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 066/111] 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 067/111] 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 068/111] 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 069/111] 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 070/111] 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 071/111] 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 072/111] 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 073/111] 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 074/111] 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 075/111] 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 076/111] 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 077/111] 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 078/111] 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() From e299bf9b625eb38d883a4ce2724069a5eba38453 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Mon, 31 Jul 2023 01:49:43 -0500 Subject: [PATCH 079/111] fix: read and store the zone transition width properly (#1169) --- dZoneManager/Zone.cpp | 2 +- dZoneManager/Zone.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 7343bb59..6b153706 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -349,7 +349,7 @@ void Zone::LoadSceneTransition(std::istream& file) { uint8_t length; BinaryIO::BinaryRead(file, length); sceneTrans.name = BinaryIO::ReadString(file, length); - file.ignore(4); + BinaryIO::BinaryRead(file, sceneTrans.width); } //BR�THER MAY I HAVE SOME L��PS? diff --git a/dZoneManager/Zone.h b/dZoneManager/Zone.h index 9c5322a1..b3e72036 100644 --- a/dZoneManager/Zone.h +++ b/dZoneManager/Zone.h @@ -30,6 +30,7 @@ struct SceneTransitionInfo { struct SceneTransition { std::string name; std::vector points; + float width; }; struct MovingPlatformPathWaypoint { From 0d48cfe8c003095c6f47598accfdbb5a62c686f4 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 31 Jul 2023 00:22:56 -0700 Subject: [PATCH 080/111] fix: Nipoint3 Operator+= (#1172) * fix operator += * fix operator += --- dCommon/NiPoint3.cpp | 8 +++++--- dCommon/NiPoint3.h | 2 +- tests/dCommonTests/TestNiPoint3.cpp | 9 +++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dCommon/NiPoint3.cpp b/dCommon/NiPoint3.cpp index b2ffa0d1..20780815 100644 --- a/dCommon/NiPoint3.cpp +++ b/dCommon/NiPoint3.cpp @@ -129,11 +129,13 @@ NiPoint3 NiPoint3::operator+(const NiPoint3& point) const { } //! Operator for addition of vectors -NiPoint3 NiPoint3::operator+=(const NiPoint3& point) const { - return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z); +NiPoint3& NiPoint3::operator+=(const NiPoint3& point) { + this->x += point.x; + this->y += point.y; + this->z += point.z; + return *this; } - //! Operator for subtraction of vectors NiPoint3 NiPoint3::operator-(const NiPoint3& point) const { return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z); diff --git a/dCommon/NiPoint3.h b/dCommon/NiPoint3.h index f76b9269..c956b654 100644 --- a/dCommon/NiPoint3.h +++ b/dCommon/NiPoint3.h @@ -136,7 +136,7 @@ public: NiPoint3 operator+(const NiPoint3& point) const; //! Operator for addition of vectors - NiPoint3 operator+=(const NiPoint3& point) const; + NiPoint3& operator+=(const NiPoint3& point); //! Operator for subtraction of vectors NiPoint3 operator-(const NiPoint3& point) const; diff --git a/tests/dCommonTests/TestNiPoint3.cpp b/tests/dCommonTests/TestNiPoint3.cpp index 33cd51d2..fbc98eb0 100644 --- a/tests/dCommonTests/TestNiPoint3.cpp +++ b/tests/dCommonTests/TestNiPoint3.cpp @@ -12,3 +12,12 @@ TEST(dCommonTests, NiPoint3Test) { // Check what unitize does to a vector of length 0 ASSERT_EQ(NiPoint3::ZERO.Unitize(), NiPoint3::ZERO); } + +TEST(dCommonTests, NiPoint3OperatorTest) { + NiPoint3 a(1, 2, 3); + NiPoint3 b(4, 5, 6); + a += b; + EXPECT_FLOAT_EQ(a.x, 5); + EXPECT_FLOAT_EQ(a.y, 7); + EXPECT_FLOAT_EQ(a.z, 9); +} From c2b4aa40264691496bf27e0ada664b13a7f3644c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 3 Aug 2023 05:51:52 -0500 Subject: [PATCH 081/111] refactor: Vendor inventory loading (#1163) * refactor: Vendor inventory loading Implement proper delta compression dynamically determine multicostitems and standard cost items Quatantine max's custom code * address feedback * fix newline * oops * remove header * fix default and const for * he said make it a reference too, not just const --- dDatabase/Tables/CDVendorComponentTable.cpp | 2 +- dGame/dComponents/VendorComponent.cpp | 174 +++++++++++--------- dGame/dComponents/VendorComponent.h | 115 +++++-------- dGame/dGameMessages/GameMessages.cpp | 14 +- dZoneManager/dZoneManager.cpp | 2 +- 5 files changed, 142 insertions(+), 165 deletions(-) diff --git a/dDatabase/Tables/CDVendorComponentTable.cpp b/dDatabase/Tables/CDVendorComponentTable.cpp index dfff2e20..17989dfb 100644 --- a/dDatabase/Tables/CDVendorComponentTable.cpp +++ b/dDatabase/Tables/CDVendorComponentTable.cpp @@ -22,7 +22,7 @@ CDVendorComponentTable::CDVendorComponentTable(void) { while (!tableData.eof()) { CDVendorComponent entry; entry.id = tableData.getIntField("id", -1); - entry.buyScalar = tableData.getFloatField("buyScalar", -1.0f); + entry.buyScalar = tableData.getFloatField("buyScalar", 0.0f); entry.sellScalar = tableData.getFloatField("sellScalar", -1.0f); entry.refreshTimeSeconds = tableData.getFloatField("refreshTimeSeconds", -1.0f); entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index e89cc926..245ea9b1 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -1,26 +1,28 @@ #include "VendorComponent.h" - -#include - -#include "Game.h" +#include "BitStream.h" #include "dServer.h" - +#include "dZoneManager.h" +#include "WorldConfig.h" #include "CDComponentsRegistryTable.h" #include "CDVendorComponentTable.h" #include "CDLootMatrixTable.h" #include "CDLootTableTable.h" +#include "CDItemComponentTable.h" VendorComponent::VendorComponent(Entity* parent) : Component(parent) { + m_HasStandardCostItems = false; + m_HasMultiCostItems = false; SetupConstants(); RefreshInventory(true); } -VendorComponent::~VendorComponent() = default; - void VendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - outBitStream->Write1(); - outBitStream->Write1(); // Has standard items (Required for vendors with missions.) - outBitStream->Write(HasCraftingStation()); // Has multi use items + outBitStream->Write(bIsInitialUpdate || m_DirtyVendor); + if (bIsInitialUpdate || m_DirtyVendor) { + outBitStream->Write(m_HasStandardCostItems); + outBitStream->Write(m_HasMultiCostItems); + if (!bIsInitialUpdate) m_DirtyVendor = false; + } } void VendorComponent::OnUse(Entity* originator) { @@ -28,97 +30,74 @@ void VendorComponent::OnUse(Entity* originator) { GameMessages::SendVendorStatusUpdate(m_Parent, originator->GetSystemAddress()); } -float VendorComponent::GetBuyScalar() const { - return m_BuyScalar; -} - -float VendorComponent::GetSellScalar() const { - return m_SellScalar; -} - -void VendorComponent::SetBuyScalar(float value) { - m_BuyScalar = value; -} - -void VendorComponent::SetSellScalar(float value) { - m_SellScalar = value; -} - -std::map& VendorComponent::GetInventory() { - return m_Inventory; -} - -bool VendorComponent::HasCraftingStation() { - // As far as we know, only Umami has a crafting station - return m_Parent->GetLOT() == 13800; -} - void VendorComponent::RefreshInventory(bool isCreation) { - //Custom code for Max vanity NPC - if (m_Parent->GetLOT() == 9749 && Game::server->GetZoneID() == 1201) { - if (!isCreation) return; - m_Inventory.insert({ 11909, 0 }); //Top hat w frog - m_Inventory.insert({ 7785, 0 }); //Flash bulb - m_Inventory.insert({ 12764, 0 }); //Big fountain soda - m_Inventory.insert({ 12241, 0 }); //Hot cocoa (from fb) + SetHasStandardCostItems(false); + SetHasMultiCostItems(false); + m_Inventory.clear(); + + // Custom code for Max vanity NPC and Mr.Ree cameras + if(isCreation && m_Parent->GetLOT() == 9749 && Game::server->GetZoneID() == 1201) { + SetupMaxCustomVendor(); return; } - m_Inventory.clear(); + auto* lootMatrixTable = CDClientManager::Instance().GetTable(); - std::vector lootMatrices = lootMatrixTable->Query([=](CDLootMatrix entry) { return (entry.LootMatrixIndex == m_LootMatrixID); }); + const auto lootMatrices = lootMatrixTable->Query([=](CDLootMatrix entry) { return (entry.LootMatrixIndex == m_LootMatrixID); }); if (lootMatrices.empty()) return; - // Done with lootMatrix table auto* lootTableTable = CDClientManager::Instance().GetTable(); + auto* itemComponentTable = CDClientManager::Instance().GetTable(); + auto* compRegistryTable = CDClientManager::Instance().GetTable(); for (const auto& lootMatrix : lootMatrices) { int lootTableID = lootMatrix.LootTableIndex; - std::vector vendorItems = lootTableTable->Query([=](CDLootTable entry) { return (entry.LootTableIndex == lootTableID); }); + auto vendorItems = lootTableTable->Query([=](CDLootTable entry) { return (entry.LootTableIndex == lootTableID); }); if (lootMatrix.maxToDrop == 0 || lootMatrix.minToDrop == 0) { - for (CDLootTable item : vendorItems) { - m_Inventory.insert({ item.itemid, item.sortPriority }); + for (const auto& item : vendorItems) { + if (!m_HasStandardCostItems || !m_HasMultiCostItems) { + auto itemComponentID = compRegistryTable->GetByIDAndType(item.itemid, eReplicaComponentType::ITEM, -1); + if (itemComponentID == -1) { + Game::logger->Log("VendorComponent", "Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT()); + continue; + } + auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID); + if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true); + if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true); + } + m_Inventory.push_back(SoldItem(item.itemid, item.sortPriority)); } } else { auto randomCount = GeneralUtils::GenerateRandomNumber(lootMatrix.minToDrop, lootMatrix.maxToDrop); for (size_t i = 0; i < randomCount; i++) { if (vendorItems.empty()) break; - auto randomItemIndex = GeneralUtils::GenerateRandomNumber(0, vendorItems.size() - 1); - - const auto& randomItem = vendorItems[randomItemIndex]; - + const auto& randomItem = vendorItems.at(randomItemIndex); vendorItems.erase(vendorItems.begin() + randomItemIndex); - - m_Inventory.insert({ randomItem.itemid, randomItem.sortPriority }); + if (!m_HasStandardCostItems || !m_HasMultiCostItems) { + auto itemComponentID = compRegistryTable->GetByIDAndType(randomItem.itemid, eReplicaComponentType::ITEM, -1); + if (itemComponentID == -1) { + Game::logger->Log("VendorComponent", "Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT()); + continue; + } + auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID); + if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true); + if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true); + } + m_Inventory.push_back(SoldItem(randomItem.itemid, randomItem.sortPriority)); } } } - - //Because I want a vendor to sell these cameras - if (m_Parent->GetLOT() == 13569) { - auto randomCamera = GeneralUtils::GenerateRandomNumber(0, 2); - - switch (randomCamera) { - case 0: - m_Inventory.insert({ 16253, 0 }); //Grungagroid - break; - case 1: - m_Inventory.insert({ 16254, 0 }); //Hipstabrick - break; - case 2: - m_Inventory.insert({ 16204, 0 }); //Megabrixel snapshot - break; - default: - break; - } - } + HandleMrReeCameras(); // Callback timer to refresh this inventory. - m_Parent->AddCallbackTimer(m_RefreshTimeSeconds, [this]() { - RefreshInventory(); + if (m_RefreshTimeSeconds > 0.0) { + m_Parent->AddCallbackTimer(m_RefreshTimeSeconds, [this]() { + RefreshInventory(); }); + } + Game::entityManager->SerializeEntity(m_Parent); GameMessages::SendVendorStatusUpdate(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); } @@ -129,12 +108,47 @@ void VendorComponent::SetupConstants() { auto* vendorComponentTable = CDClientManager::Instance().GetTable(); std::vector vendorComps = vendorComponentTable->Query([=](CDVendorComponent entry) { return (entry.id == componentID); }); if (vendorComps.empty()) return; - m_BuyScalar = vendorComps[0].buyScalar; - m_SellScalar = vendorComps[0].sellScalar; - m_RefreshTimeSeconds = vendorComps[0].refreshTimeSeconds; - m_LootMatrixID = vendorComps[0].LootMatrixIndex; + auto vendorData = vendorComps.at(0); + if (vendorData.buyScalar == 0.0) m_BuyScalar = Game::zoneManager->GetWorldConfig()->vendorBuyMultiplier; + else m_BuyScalar = vendorData.buyScalar; + m_SellScalar = vendorData.sellScalar; + m_RefreshTimeSeconds = vendorData.refreshTimeSeconds; + m_LootMatrixID = vendorData.LootMatrixIndex; } bool VendorComponent::SellsItem(const LOT item) const { - return m_Inventory.find(item) != m_Inventory.end(); + return std::count_if(m_Inventory.begin(), m_Inventory.end(), [item](const SoldItem& lhs) { + return lhs.lot == item; + }) > 0; +} + + +void VendorComponent::SetupMaxCustomVendor(){ + SetHasStandardCostItems(true); + m_Inventory.push_back(SoldItem(11909, 0)); // Top hat w frog + m_Inventory.push_back(SoldItem(7785, 0)); // Flash bulb + m_Inventory.push_back(SoldItem(12764, 0)); // Big fountain soda + m_Inventory.push_back(SoldItem(12241, 0)); // Hot cocoa (from fb) +} + +void VendorComponent::HandleMrReeCameras(){ + if (m_Parent->GetLOT() == 13569) { + SetHasStandardCostItems(true); + auto randomCamera = GeneralUtils::GenerateRandomNumber(0, 2); + + LOT camera = 0; + DluAssert(randomCamera >= 0 && randomCamera <= 2); + switch (randomCamera) { + case 0: + camera = 16253; // Grungagroid + break; + case 1: + camera = 16254; // Hipstabrick + break; + case 2: + camera = 16204; // Megabrixel snapshot + break; + } + m_Inventory.push_back(SoldItem(camera, 0)); + } } diff --git a/dGame/dComponents/VendorComponent.h b/dGame/dComponents/VendorComponent.h index cbff0cfd..4a9b582e 100644 --- a/dGame/dComponents/VendorComponent.h +++ b/dGame/dComponents/VendorComponent.h @@ -9,91 +9,54 @@ #include "RakNetTypes.h" #include "eReplicaComponentType.h" -/** - * A component for vendor NPCs. A vendor sells items to the player. - */ +struct SoldItem { + SoldItem(const LOT lot, const int32_t sortPriority) { + this->lot = lot; + this->sortPriority = sortPriority; + }; + LOT lot = 0; + int32_t sortPriority = 0; +}; + class VendorComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR; - + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR; VendorComponent(Entity* parent); - ~VendorComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - void OnUse(Entity* originator) override; - - /** - * Gets the buy scaler - * @return the buy scaler - */ - float GetBuyScalar() const; - - /** - * Sets the buy scalar. - * @param value the new value. - */ - void SetBuyScalar(float value); - - /** - * Gets the buy scaler - * @return the buy scaler - */ - float GetSellScalar() const; - - /** - * Sets the sell scalar. - * @param value the new value. - */ - void SetSellScalar(float value); - - /** - * True if the NPC LOT is 13800, the only NPC with a crafting station. - */ - bool HasCraftingStation(); - - /** - * Gets the list if items the vendor sells. - * @return the list of items. - */ - std::map& GetInventory(); - - /** - * Refresh the inventory of this vendor. - */ void RefreshInventory(bool isCreation = false); - - /** - * Called on startup of vendor to setup the variables for the component. - */ void SetupConstants(); - bool SellsItem(const LOT item) const; + float GetBuyScalar() const { return m_BuyScalar; } + float GetSellScalar() const { return m_SellScalar; } + void SetBuyScalar(const float value) { m_BuyScalar = value; } + void SetSellScalar(const float value) { m_SellScalar = value; } + const std::vector& GetInventory() { return m_Inventory; } + + void SetHasMultiCostItems(const bool hasMultiCostItems) { + if (m_HasMultiCostItems == hasMultiCostItems) return; + m_HasMultiCostItems = hasMultiCostItems; + m_DirtyVendor = true; + } + + void SetHasStandardCostItems(const bool hasStandardCostItems) { + if (m_HasStandardCostItems == hasStandardCostItems) return; + m_HasStandardCostItems = hasStandardCostItems; + m_DirtyVendor = true; + } + + private: - /** - * The buy scalar. - */ - float m_BuyScalar; - - /** - * The sell scalar. - */ - float m_SellScalar; - - /** - * The refresh time of this vendors' inventory. - */ - float m_RefreshTimeSeconds; - - /** - * Loot matrix id of this vendor. - */ - uint32_t m_LootMatrixID; - - /** - * The list of items the vendor sells. - */ - std::map m_Inventory; + void SetupMaxCustomVendor(); + void HandleMrReeCameras(); + float m_BuyScalar = 0.0f; + float m_SellScalar = 0.0f; + float m_RefreshTimeSeconds = 0.0f; + uint32_t m_LootMatrixID = 0; + std::vector m_Inventory; + bool m_DirtyVendor = false; + bool m_HasStandardCostItems = false; + bool m_HasMultiCostItems = false; }; #endif // VENDORCOMPONENT_H diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 8d8085a9..c3358625 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1286,21 +1286,21 @@ void GameMessages::SendVendorStatusUpdate(Entity* entity, const SystemAddress& s VendorComponent* vendor = static_cast(entity->GetComponent(eReplicaComponentType::VENDOR)); if (!vendor) return; - std::map vendorItems = vendor->GetInventory(); + auto vendorItems = vendor->GetInventory(); bitStream.Write(entity->GetObjectID()); bitStream.Write(eGameMessageType::VENDOR_STATUS_UPDATE); bitStream.Write(bUpdateOnly); - bitStream.Write(static_cast(vendorItems.size())); + bitStream.Write(vendorItems.size()); - for (std::pair item : vendorItems) { - bitStream.Write(static_cast(item.first)); - bitStream.Write(static_cast(item.second)); + for (const auto& item : vendorItems) { + bitStream.Write(item.lot); + bitStream.Write(item.sortPriority); } - if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST - SEND_PACKET; + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; + SEND_PACKET; } void GameMessages::SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr) { diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 51f6e640..7b352a57 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -277,7 +277,7 @@ void dZoneManager::LoadWorldConfig() { m_WorldConfig->characterMaxSlope = worldConfig.getFloatField("character_max_slope"); m_WorldConfig->defaultRespawnTime = worldConfig.getFloatField("defaultrespawntime"); m_WorldConfig->missionTooltipTimeout = worldConfig.getFloatField("mission_tooltip_timeout"); - m_WorldConfig->vendorBuyMultiplier = worldConfig.getFloatField("vendor_buy_multiplier"); + m_WorldConfig->vendorBuyMultiplier = worldConfig.getFloatField("vendor_buy_multiplier", 0.1); m_WorldConfig->petFollowRadius = worldConfig.getFloatField("pet_follow_radius"); m_WorldConfig->characterEyeHeight = worldConfig.getFloatField("character_eye_height"); m_WorldConfig->flightVerticalVelocity = worldConfig.getFloatField("flight_vertical_velocity"); From a22ecf385f766056ed3c72b9c862daa8e4835532 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 3 Aug 2023 21:27:40 -0500 Subject: [PATCH 082/111] feature: add full known GM list (#1171) * feature: add full GM list * Fix compiling * add tests Fix more issues --- dCommon/dEnums/eGameMessageType.h | 1868 ++++++++++++++--- dGame/dGameMessages/GameMessageHandler.cpp | 14 +- dGame/dGameMessages/GameMessages.cpp | 14 +- .../dGameMessagesTests/CMakeLists.txt | 3 +- .../LegacyGameMessageTests.cpp | 298 +++ 5 files changed, 1899 insertions(+), 298 deletions(-) create mode 100644 tests/dGameTests/dGameMessagesTests/LegacyGameMessageTests.cpp diff --git a/dCommon/dEnums/eGameMessageType.h b/dCommon/dEnums/eGameMessageType.h index 051a5ae8..69f542e1 100644 --- a/dCommon/dEnums/eGameMessageType.h +++ b/dCommon/dEnums/eGameMessageType.h @@ -4,300 +4,1602 @@ #include enum class eGameMessageType : uint16_t { - TELEPORT = 19, - SET_PLAYER_CONTROL_SCHEME = 26, - DROP_CLIENT_LOOT = 30, - DIE = 37, - REQUEST_DIE = 38, - PLAY_EMOTE = 41, - PLAY_ANIMATION = 43, - CONTROL_BEHAVIOR = 48, - SET_NAME = 72, - ECHO_START_SKILL = 118, - START_SKILL = 119, - VERIFY_ACK = 121, - ADD_SKILL = 127, - REMOVE_SKILL = 128, - SET_CURRENCY = 133, - PICKUP_CURRENCY = 137, - PICKUP_ITEM = 139, - TEAM_PICKUP_ITEM = 140, - PLAY_FX_EFFECT = 154, - STOP_FX_EFFECT = 155, - REQUEST_RESURRECT = 159, - RESURRECT = 160, + GET_POSITION = 0, + GET_ROTATION = 1, + GET_LINEAR_VELOCITY = 2, + GET_ANGULAR_VELOCITY = 3, + GET_FORWARD_VELOCITY = 4, + GET_PLAYER_FORWARD = 5, + GET_FORWARD_VECTOR = 6, + SET_POSITION = 7, + SET_LOCAL_POSITION = 8, + SET_ROTATION = 9, + SET_LINEAR_VELOCITY = 10, + MODIFY_LINEAR_VELOCITY = 11, + SET_ANGULAR_VELOCITY = 12, + MODIFY_ANGULAR_VELOCITY = 13, + DEFLECT = 14, + SEND_POSITION_UPDATE = 15, + SET_OBJECT_SCALE = 16, + GET_OBJECT_SCALE = 17, + TIMED_SCALE_FINISHED = 18, + TELEPORT = 19, + TOGGLE_PLAYER_FWD_TO_CAMERA = 20, + LOCK_PLAYER_ROT_TO_CAMERA = 21, + UNLOCK_PLAYER_ROT_FROM_CAMERA = 22, + TOGGLE_PLAYER_ROT_LOCK_TO_MOUSE = 23, + LOCK_PLAYER_ROT_TO_MOUSE = 24, + UNLOCK_PLAYER_ROT_FROM_MOUSE = 25, + SET_PLAYER_CONTROL_SCHEME = 26, + GET_PLAYER_CONTROL_SCHEME = 27, + RESET_PLAYER_CONTROL_SCHEME = 28, + PLAYER_TO_PREVIOUS_CONTROL_SCHEME = 29, + DROP_CLIENT_LOOT = 30, + GET_SPEED = 34, + GET_ROT_SPEED = 35, + IS_DEAD = 36, + DIE = 37, + REQUEST_DIE = 38, + ADD_OBJECT = 39, + PLAY_EMOTE = 41, + PRELOAD_ANIMATION = 42, + PLAY_ANIMATION = 43, + ANIMATION_COMPLETE = 44, + ENABLE_HIGHLIGHT = 45, + DISABLE_HIGHLIGHT = 46, + GET_ANIMATION_NAMES = 47, + CONTROL_BEHAVIORS = 48, + BLEND_PRIMARY_ANIMATION = 52, + SET_OFFSCREEN_ANIMATION = 53, + GET_MOVEMENT_INPUT_VALUES = 54, + SWAP_TEXTURE = 55, + SWAP_COLOR = 56, + ATTACH_HAIR = 57, + GET_ENTITY_STRUCT = 58, + SET_ENTITY_STRUCT = 59, + SET_ATTR = 60, + GET_ATTR = 61, + ON_HIT = 62, + HIT_OR_HEAL_RESULT = 63, + SHOW_ATTACK = 64, + GO_TO = 65, + GET_CONFIG_DATA = 66, + SET_CONFIG_DATA = 68, + GET_INVENTORY_EXTRA_INFO = 69, + GET_DISPLAY_NAME = 70, + GET_NAME = 71, + SET_NAME = 72, + IS_NAME_LOCALIZED = 73, + GET_HAIR_COLOR = 74, + SET_HAIR_COLOR = 75, + GET_HAIR_STYLE = 76, + SET_HAIR_STYLE = 77, + GET_HEAD = 78, + SET_HEAD = 79, + GET_TORSO = 80, + SET_TORSO = 81, + GET_LEGS = 82, + SET_LEGS = 83, + SET_PROXIMITY_RADIUS = 84, + PROXIMITY_UPDATE = 85, + GET_PROXIMITY_OBJECTS = 86, + UNSET_PROXIMITY_RADIUS = 87, + CLEAR_PROXIMITY_RADIUS = 88, + GET_PROXIMITY_DATA = 89, + SET_PROXIMITY_RADIUS_ICON = 90, + TOGGLE_TAC_ARC = 93, + CAST_SKILL = 95, + CAST_LOCAL_SKILL = 96, + ECHO_LOCAL_SKILL = 97, + QUEUE_AI_SKILL = 98, + ADD_THREAT_RATING = 99, + GET_THREAT_RATING = 100, + CLEAR_THREAT_LIST = 103, + GET_TIME_FOR_NPC_SKILL = 111, + ENEMY_HEAL_NOTIFICATION = 112, + RESET_SCRIPTED_AI_STATE = 113, + ENABLE_COMBAT_AI_COMPONENT = 114, + COMBAT_AI_FORCE_TETHER = 115, + SUSPEND_MOVEMENT_AI = 116, + NOTIFY_SCRIPT_VARS_INITIALIZED = 117, + ECHO_START_SKILL = 118, + START_SKILL = 119, + CASTER_DEAD = 120, + VERIFY_ACK = 121, + ADD_PENDING_VERIFY = 122, + MAP_SKILL = 123, + SELECT_SKILL = 124, + CAST_ACTIVE_SKILL = 125, + MODIFY_SKILL_COOLDOWN = 126, + ADD_SKILL = 127, + REMOVE_SKILL = 128, + LOG = 129, + LOG_CHAT = 130, + SET_MAX_CURRENCY = 131, + GET_MAX_CURRENCY = 132, + SET_CURRENCY = 133, + GET_CURRENCY = 134, + ADD_PENDING_CURRENCY = 136, + PICKUP_CURRENCY = 137, + SERVER_DELETE_LOOT_ITEM = 138, + PICKUP_ITEM = 139, + TEAM_PICKUP_ITEM = 140, + CLIENT_DELETE_LOOT_ITEM = 141, + CLIENT_SET_LOOT_ITEM_FFA = 143, + COLLISION_PHANTOM = 144, + OFF_COLLISION_PHANTOM = 145, + COLLISION_PROXIMITY = 146, + OFF_COLLISION_PROXIMITY = 147, + COLLISION = 148, + OFF_COLLISION = 149, + GET_SKILLS = 150, + CLEAR_FX_SINGLE_EFFECT = 152, + GET_FX_EXIST_EFFECT = 153, + PLAY_FX_EFFECT = 154, + STOP_FX_EFFECT = 155, + CLEAR_FX_ALL_CREATE_EFFECTS = 156, + UPDATE_FX_ALL_CREATE_EFFECTS = 157, + REQUEST_RESURRECT = 159, + RESURRECT = 160, + UPDATE_FROM_GHOST = 162, + FETCH_GHOST = 163, + KFM_LOADED = 164, + NIF_LOADED = 165, + HKX_LOADED = 166, + MOVE_TO_DELETE_QUEUE = 167, + RESTORE_FROM_DELETE_QUEUE = 168, + IS_ENEMY = 169, + GET_FACTION = 170, + SET_IMAGINATION = 171, + GET_IMAGINATION = 172, + SET_MAX_IMAGINATION = 173, + GET_MAX_IMAGINATION = 174, + MODIFY_IMAGINATION = 175, + MODIFY_MAX_IMAGINATION = 176, + SET_HEALTH = 177, + GET_HEALTH = 178, + SET_MAX_HEALTH = 179, + GET_MAX_HEALTH = 180, + MODIFY_HEALTH = 181, + MODIFY_MAX_HEALTH = 182, + SET_ARMOR = 183, + GET_ARMOR = 184, + SET_MAX_ARMOR = 185, + GET_MAX_ARMOR = 186, + MODIFY_ARMOR = 187, + MODIFY_MAX_ARMOR = 188, + POP_HEALTH_STATE = 190, PUSH_EQUIPPED_ITEMS_STATE = 191, - POP_EQUIPPED_ITEMS_STATE = 192, - SET_GM_LEVEL = 193, - SET_STUNNED = 198, - SET_STUN_IMMUNITY = 200, - KNOCKBACK = 202, - REBUILD_CANCEL = 209, - ENABLE_REBUILD = 213, - MOVE_ITEM_IN_INVENTORY = 224, - ADD_ITEM_TO_INVENTORY_CLIENT_SYNC = 227, - REMOVE_ITEM_FROM_INVENTORY = 230, - EQUIP_ITEM = 231, - UN_EQUIP_ITEM = 233, - OFFER_MISSION = 248, - RESPOND_TO_MISSION = 249, - NOTIFY_MISSION = 254, - NOTIFY_MISSION_TASK = 255, - REBUILD_NOTIFY_STATE = 336, - TERMINATE_INTERACTION = 357, - SERVER_TERMINATE_INTERACTION = 358, - REQUEST_USE = 364, - VENDOR_OPEN_WINDOW = 369, - BUY_FROM_VENDOR = 373, - SELL_TO_VENDOR = 374, - TEAM_SET_OFF_WORLD_FLAG = 383, - SET_INVENTORY_SIZE = 389, - ACKNOWLEDGE_POSSESSION = 391, + POP_EQUIPPED_ITEMS_STATE = 192, + SET_GM_LEVEL = 193, + GET_GM_LEVEL = 194, + ADD_STATUS_EFFECT = 196, + REMOVE_STATUS_EFFECT = 197, + SET_STUNNED = 198, + GET_STUNNED = 199, + SET_STUN_IMMUNITY = 200, + GET_STUN_IMMUNITY = 201, + KNOCKBACK = 202, + SET_VISIBLE = 203, + GET_VISIBLE = 204, + REPORT_ITEM_INFO = 205, + GET_REBUILD_STATE = 207, + REBUILD_CANCEL = 209, + REBUILD_START = 211, + ENABLE_REBUILD = 213, + SKILL_FAILURE = 214, + IS_ATTACK_STANCE = 216, + SET_OBJECT_RENDER = 217, + REQUEST_MAPPED_SKILLS = 218, + UI_SELECT_MAPPED_SKILL = 219, + GET_INVENTORY_ITEM_IN_SLOT = 220, + GET_FIRST_INVENTORY_ITEM_BY_LOT = 221, + GET_SMALLEST_INVENTORY_STACK_BY_LOT = 222, + MOVE_ITEM_IN_INVENTORY = 224, + ADD_ITEM_TO_INVENTORY_CLIENT_SYNC = 227, + GET_EQUIPPED_ITEMS = 229, + REMOVE_ITEM_FROM_INVENTORY = 230, + EQUIP_INVENTORY = 231, + UN_EQUIP_INVENTORY = 233, + EQUIP_ITEM = 234, + UN_EQUIP_ITEM = 235, + IS_ITEM_RESPOND = 236, + IS_ITEM_EQUIPPED = 237, + ATTACH_ITEM = 238, + DETACH_ITEM = 239, + GET_NODE = 240, + GET_LOT = 241, + IS_ITEM_EQUIPPABLE = 242, + GET_CURRENT_ANIMATION = 243, + GET_INV_ITEM_COUNT = 244, + POST_LOAD_EQUIP = 245, + SET_PHYSICS_ACTIVE_STATE = 246, + GET_CURRENT_SKILL_TAC_ARC = 247, + OFFER_MISSION = 248, + RESPOND_TO_MISSION = 249, + GET_MISSION_STATE = 250, + GET_MISSION_COMPLETE_TIMESTAMP = 251, + NOTIFY_MISSION = 254, + NOTIFY_MISSION_TASK = 255, + ARE_GFX_LOADED = 257, + ADDED_TO_WORLD = 258, + REMOVE_EXTRA_GFX_FROM_PIPE = 259, + HIDE_EQUIPED_WEAPON = 260, + UN_HIDE_EQUIPED_WEAPON = 261, + GET_ITEM_SLOT = 262, + IS_CHARACTER = 263, + SET_IMMUNITY = 264, + TOGGLE_TOOLTIPS = 266, + GET_TOOLTIPS_DISABLED = 267, + GET_BOUNDING_INFO = 268, + OVERRIDE_BOUNDING_RADIUS = 269, + GET_OFFSCREEN = 270, + USE_STATE_MACHINE = 271, + ADD_STATE = 272, + ADD_SUB_STATE = 273, + SET_STATE = 274, + SET_SUB_STATE = 275, + ADD_MESSAGE = 276, + RELOAD_SCRIPT = 277, + RELOAD_ALL_SCRIPTS = 278, + FRIEND_INVITE_MSG = 279, + ADD_FRIEND_REPOSNSE_MSG = 280, + REMOVE_FRIEND_RESPONSE_MSG = 281, + ADD_FRIEND_FROM_UI_MSG = 282, + GET_CACHED_FRIENDS_LIST_MSG = 283, + REQUEST_NEW_FRIENDS_LIST_MSG = 284, + REPOPULATE_FRIENDS_LIST_MSG = 285, + ADD_IGNORE_REPONSE_MSG = 286, + REMOVE_IGNORE_RESPONSE_MSG = 287, + ADD_IGNORE_FROM_UI_MSG = 288, + GET_CACHED_IGNORE_LIST_MSG = 289, + REQUEST_NEW_IGNORE_LIST_MSG = 290, + REMOVE_FRIEND_BY_NAME = 291, + REMOVE_IGNORE_BY_NAME = 292, + IS_PLAYER_IN_IGNORE_LIST_MSG = 293, + REPOPULATE_IGNORE_LIST_MSG = 294, + GET_INVENTORY_LIST = 295, + UPDATE_FRIEND_MSG = 296, + UPDATE_FRIEND_NAME_MSG = 297, + UPDATE_IGNORE_NAME_MSG = 298, + DEPARTED = 299, + ARRIVED = 300, + TEMPLATE_CHANGE_WAYPOINTS = 301, + CANCELLED = 302, + FLUSH_CACHED_GRAPHICS = 303, + FOLLOW_TARGET = 304, + TIMER_DONE = 305, + TIMER_CANCELLED = 306, + SET_TETHER_POINT = 307, + GET_TETHER_POINT = 308, + LEFT_TETHER_RADIUS = 309, + GET_SCRIPT_VARS_PTR = 310, + FACE_TARGET = 311, + ROTATE_BY_DEGREES = 312, + STRING_RENDERED = 313, + RESET_PRIMARY_ANIMATION = 314, + FACE_PLAY_STREAM = 315, + TORSO_PLAY_STREAM = 316, + CAN_PICKUP = 317, + GET_INVENTORY_SIZE = 318, + GET_INVENTORY_COUNT = 319, + GET_OBJECTS_IN_GROUP = 320, + HIDE_ITEM = 321, + IS_OBJECT_IN_FOV = 322, + GET_TYPE = 323, + TEAM_INVITE_MSG = 324, + TEAM_GET_SIZE = 325, + TEAM_REQUEST_SET_LOOT = 326, + TEAM_REMOVE_PLAYER_MSG = 327, + TEAM_UPDATE_PLAYER_NAME_MSG = 328, + SET_UPDATABLE = 329, + REQUEST_TEAM_UI_UPDATE = 330, + SET_COLLISION_GROUP = 331, + GET_COLLISION_GROUP = 332, + GET_ORIGINAL_COLLISION_GROUP = 333, + SET_COLLISION_GROUP_TO_ORIGINAL = 334, + GET_OBJECT_RADIUS = 335, + REBUILD_NOTIFY_STATE = 336, + GET_PLAYER_INTERACTION = 337, + SET_PLAYER_INTERACTION = 338, + FORCE_PLAYER_TO_INTERACT = 339, + GET_SELECTED_POTENTIAL_INTERACTION = 340, + SET_SELECTED_POTENTIAL_INTERACTION = 341, + GET_INTERACTION_DISTANCE = 342, + SET_INTERACTION_DISTANCE = 343, + CALCULATE_INTERACTION_DISTANCE = 344, + INTERACTION_ATTEMPT_FROM_OUT_OF_RANGE = 345, + SET_PICKING_TARGET = 346, + CLIENT_UNUSE = 347, + BEGIN_PET_INTERACTION = 348, + WANTS_INTERACTION_ICON = 349, + PROPERTY_EDIT_ICON_INTERACTION = 350, + PROPERTY_MODEL_INTERACTION = 351, + GET_INTERACTION_DETAILS = 352, + GET_DISABLED_INTERACTION_TYPES = 353, + GET_INTERACTION_INFO = 354, + INTERACTION_GAME_STATE_CHANGE = 355, + TOGGLE_INTERACTION_UPDATES = 356, + TERMINATE_INTERACTION = 357, + SERVER_TERMINATE_INTERACTION = 358, + GET_PLAYERS_TARGET_FOR_SELECTION = 359, + PROCESS_INTERACTION_UNDER_CURSOR = 360, + HANDLE_INTERACT_ACTION = 361, + ATTEMPT_INTERACTION = 362, + HANDLE_INTERACTION_CAMERA = 363, + REQUEST_USE = 364, + CLIENT_USE = 366, + GET_PLAYER_MULTI_INTERACTION = 367, + GET_MULTI_INTERACTION_STATE = 368, + VENDOR_OPEN_WINDOW = 369, + VENDOR_CLOSE_WINDOW = 370, + EMOTE_PLAYED = 371, + EMOTE_RECEIVED = 372, + BUY_FROM_VENDOR = 373, + SELL_TO_VENDOR = 374, + ADD_DONATION_ITEM = 375, + REMOVE_DONATION_ITEM = 376, + CONFIRM_DONATION_ON_PLAYER = 378, + CANCEL_DONATION_ON_PLAYER = 379, + TEAM_GET_LEADER = 380, + TEAM_GET_ON_WORLD_MEMBERS = 381, + TEAM_GET_ALL_MEMBERS = 382, + TEAM_SET_OFF_WORLD_FLAG = 383, + SET_TRANSPARENCY = 385, + GET_PREFERS_FADE = 386, + PROJECTILE_IMPACT = 387, + SET_PROJECTILE_PARAMS = 388, + SET_INVENTORY_SIZE = 389, + ACKNOWLEDGE_POSSESSION = 391, + SET_POSSESSED_OBJECT = 392, + CHANGE_POSSESSOR = 393, + GET_POSSESSION_TYPE = 395, + GET_POSSESSED_OBJECT = 396, + GET_POSSESSOR = 397, + IS_POSSESSED = 398, + ENABLE_ACTIVITY = 399, SET_SHOOTING_GALLERY_PARAMS = 400, - REQUEST_ACTIVITY_START_STOP = 402, - REQUEST_ACTIVITY_ENTER = 403, - REQUEST_ACTIVITY_EXIT = 404, - ACTIVITY_ENTER = 405, - ACTIVITY_EXIT = 406, - ACTIVITY_START = 407, - ACTIVITY_STOP = 408, - SHOOTING_GALLERY_CLIENT_AIM_UPDATE = 409, - SHOOTING_GALLERY_FIRE = 411, - REQUEST_VENDOR_STATUS_UPDATE = 416, - VENDOR_STATUS_UPDATE = 417, - NOTIFY_CLIENT_SHOOTING_GALLERY_SCORE = 425, - CONSUME_CLIENT_ITEM = 427, - CLIENT_ITEM_CONSUMED = 428, - UPDATE_SHOOTING_GALLERY_ROTATION = 448, - SET_FLAG = 471, - NOTIFY_CLIENT_FLAG_CHANGE = 472, - VENDOR_TRANSACTION_RESULT = 476, - HAS_BEEN_COLLECTED = 486, - DISPLAY_CHAT_BUBBLE = 495, - SPAWN_PET = 498, - DESPAWN_PET = 499, - PLAYER_LOADED = 505, - PLAYER_READY = 509, - REQUEST_LINKED_MISSION = 515, - INVALID_ZONE_TRANSFER_LIST = 519, - MISSION_DIALOGUE_OK = 520, - DISPLAY_MESSAGE_BOX = 529, - MESSAGE_BOX_RESPOND = 530, - CHOICE_BOX_RESPOND = 531, - SMASH = 537, - UNSMASH = 538, - PLACE_MODEL_RESPONSE = 547, - SET_SHOOTING_GALLERY_RETICULE_EFFECT = 548, - SET_JET_PACK_MODE = 561, - REGISTER_PET_ID = 565, - REGISTER_PET_DBID = 566, - SHOW_ACTIVITY_COUNTDOWN = 568, - START_ACTIVITY_TIME = 576, - ACTIVITY_PAUSE = 602, - USE_NON_EQUIPMENT_ITEM = 603, - USE_ITEM_RESULT = 607, - COMMAND_PET = 640, - PET_RESPONSE = 641, - REQUEST_ACTIVITY_SUMMARY_LEADERBOARD_DATA = 648, - SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA = 649, - NOTIFY_OBJECT = 656, - CLIENT_NOTIFY_PET = 659, - NOTIFY_PET = 660, - NOTIFY_PET_TAMING_MINIGAME = 661, - START_SERVER_PET_MINIGAME_TIMER = 662, - CLIENT_EXIT_TAMING_MINIGAME = 663, - PET_NAME_CHANGED = 686, - PET_TAMING_MINIGAME_RESULT = 667, - PET_TAMING_TRY_BUILD_RESULT = 668, - NOTIFY_TAMING_BUILD_SUCCESS = 673, - NOTIFY_TAMING_MODEL_LOADED_ON_SERVER = 674, - ACTIVATE_BUBBLE_BUFF = 678, - DEACTIVATE_BUBBLE_BUFF = 679, - ADD_PET_TO_PLAYER = 681, - REQUEST_SET_PET_NAME = 683, - SET_PET_NAME = 684, - NOTIFY_PET_TAMING_PUZZLE_SELECTED = 675, - SHOW_PET_ACTION_BUTTON = 692, - SET_EMOTE_LOCK_STATE = 693, - USE_ITEM_REQUIREMENTS_RESPONSE = 703, - PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT = 713, - DOWNLOAD_PROPERTY_DATA = 716, - QUERY_PROPERTY_DATA = 717, - PROPERTY_EDITOR_BEGIN = 724, - PROPERTY_EDITOR_END = 725, - IS_MINIFIG_IN_A_BUBBLE = 729, - START_PATHING = 733, - ACTIVATE_BUBBLE_BUFF_FROM_SERVER = 734, - DEACTIVATE_BUBBLE_BUFF_FROM_SERVER = 735, - NOTIFY_CLIENT_ZONE_OBJECT = 737, - UPDATE_REPUTATION = 746, - PROPERTY_RENTAL_RESPONSE = 750, - REQUEST_PLATFORM_RESYNC = 760, - PLATFORM_RESYNC = 761, - PLAY_CINEMATIC = 762, - END_CINEMATIC = 763, - CINEMATIC_UPDATE = 764, - TOGGLE_GHOST_REFERENCE_OVERRIDE = 767, - SET_GHOST_REFERENCE_POSITION = 768, - FIRE_EVENT_SERVER_SIDE = 770, - SET_NETWORK_SCRIPT_VAR = 781, - UPDATE_MODEL_FROM_CLIENT = 793, - DELETE_MODEL_FROM_CLIENT = 794, - PLAY_ND_AUDIO_EMITTER = 821, - PLAY2_DAMBIENT_SOUND = 831, - ENTER_PROPERTY1 = 840, - ENTER_PROPERTY2 = 841, - PROPERTY_ENTRANCE_SYNC = 842, - PROPERTY_SELECT_QUERY = 845, - PARSE_CHAT_MESSAGE = 850, - BROADCAST_TEXT_TO_CHATBOX = 858, - OPEN_PROPERTY_MANAGEMENT = 860, - OPEN_PROPERTY_VENDOR = 861, - UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK = 863, - CLIENT_TRADE_REQUEST = 868, + OPEN_ACTIVITY_START_DIALOG = 401, + REQUEST_ACTIVITY_START_STOP = 402, + REQUEST_ACTIVITY_ENTER = 403, + REQUEST_ACTIVITY_EXIT = 404, + ACTIVITY_ENTER = 405, + ACTIVITY_EXIT = 406, + ACTIVITY_START = 407, + ACTIVITY_STOP = 408, + SHOOTING_GALLERY_CLIENT_AIM_UPDATE = 409, + ROTATE_TO_POINT = 410, + SHOOTING_GALLERY_FIRE = 411, + CALCULATE_FIRING_PARAMETERS = 412, + GET_MUZZLE_OFFSET = 413, + GET_ACTIVITY_POINTS = 414, + TEAM_IS_ON_WORLD_MEMBER = 415, + REQUEST_VENDOR_STATUS_UPDATE = 416, + VENDOR_STATUS_UPDATE = 417, + CANCEL_MISSION = 418, + RESET_MISSIONS = 419, + RENDER_COMPONENT_READY = 420, + SEND_MINIFIG_DECALS = 421, + PHYSICS_COMPONENT_READY = 422, + ENTER_STANDBY_MODE = 423, + LEAVE_STANDBY_MODE = 424, + NOTIFY_CLIENT_SHOOTING_GALLERY_SCORE = 425, + REQUEST_CONSUME_ITEM = 426, + CONSUME_CLIENT_ITEM = 427, + CLIENT_ITEM_CONSUMED = 428, + QUERY_STANDBY_MODE = 429, + GET_NI_BOUND = 430, + MISSION_FAILURE = 431, + GET_ANIMATION_TIME = 432, + GET_CURRENT_ACTIVITY = 434, + SET_EYEBROWS = 435, + GET_EYEBROWS = 436, + SET_EYES = 437, + GET_EYES = 438, + SET_MOUTH = 439, + GET_MOUTH = 440, + IS_OBJECT_SMASHABLE = 441, + SMASHABLE_STATE_CHANGED = 443, + USE_STATE_LOGGER = 444, + ROTATE_SUB_NODE = 445, + GET_SUB_NODE_POSITION = 446, + GET_SUB_NODE = 447, + UPDATE_SHOOTING_GALLERY_ROTATION = 448, + RENDER_FLOATING_TEXT = 449, + REQUEST2_D_TEXT_ELEMENT = 450, + UPDATE2_D_TEXT_ELEMENT = 451, + REMOVE2_D_TEXT_ELEMENT = 452, + SET_COLOR = 453, + GET_COLOR = 454, + HKX_CHARACTER_LOADED = 455, + ACTIVATE_PHYSICS = 457, + SET_ICON_ABOVE_HEAD = 458, + ADD_ICON_COMPOSITE = 459, + CLEAR_ICON_COMPOSITES = 460, + ICON_NIF_LOADED = 461, + ICON_KFM_LOADED = 462, + GET_OVERHEAD_ICON_PROPERTIES_FROM_PARENT = 463, + BOUNCE_PLAYER = 464, + SET_USER_CTRL_COMP_PAUSE = 466, + HAS_COLLIDED = 467, + GET_TOOLTIP_FLAG = 468, + SET_TOOLTIP_FLAG = 469, + GET_FLAG = 470, + SET_FLAG = 471, + NOTIFY_CLIENT_FLAG_CHANGE = 472, + CURSOR_ON = 473, + CURSOR_OFF = 474, + HELP = 475, + VENDOR_TRANSACTION_RESULT = 476, + PERFORM_SPECIAL_DEATH = 477, + GET_SHADER_ID = 478, + GET_RENDER_ENVIRONMENT = 479, + FINISHED_LOADING_SCENE = 480, + GET_SKILL_INFO = 481, + ACTIVITY_CANCEL = 482, + MISSION_USES_OBJECT = 483, + GET_POSITIONAL_ID = 484, + SET_COLLECTIBLE_STATUS = 485, + HAS_BEEN_COLLECTED = 486, + HAS_BEEN_COLLECTED_BY_CLIENT = 487, + GET_POS_UPDATE_STATS = 488, + GET_NUM_VIEWERS_SCOPING_THIS = 489, + GET_ACTIVITY_USER = 490, + GET_ALL_ACTIVITY_USERS = 491, + GET_MISSION_FOR_PLAYER = 492, + SET_FACTION = 493, + SET_PLATFORM_IDLE_STATE = 494, + DISPLAY_CHAT_BUBBLE = 495, + REQUEST_CHAT_BUBBLE_ELEMENT = 496, + GET_MISSION_DATA = 497, + SPAWN_PET = 498, + DESPAWN_PET = 499, + SET_LOCAL_SPACE_STATE = 500, + GET_LOCAL_SPACE_STATE = 501, + SET_POSITION_TO_LOCAL_POSITION = 502, + ALLOW_LOCAL_SPACE_UPDATE = 503, + TOGGLE_FREE_CAM_MODE = 504, + PLAYER_LOADED = 505, + PLAYER_ADDED_TO_WORLD_LOCAL = 506, + OBJECT_LOADED = 507, + GET_PLAYER_READY = 508, + PLAYER_READY = 509, + SET_SMASHABLE_PARAMS = 510, + IS_LOOTABLE_CHEST = 511, + LOOT_OPEN_WINDOW = 512, + LOOT_SELECTION_UPDATE = 513, + TAKE_LOOT_CHEST_ITEM = 514, + REQUEST_LINKED_MISSION = 515, + TRANSFER_TO_ZONE = 516, + TRANSFER_TO_ZONE_CHECKED_IM = 517, + SECURED_TRANSFER_TO_ZONE = 518, + INVALID_ZONE_TRANSFER_LIST = 519, + MISSION_DIALOGUE_OK = 520, + GET_OBJECT_IN_SCOPE = 521, + SET_LAUNCHED_STATE = 522, + P_CREATE_EFFECT_FINISHED = 523, + SMASHED_OBJECT = 524, + CHECK_SMASHCHAIN_OVERRIDE = 525, + DISPLAY_REBUILD_ACTIVATOR = 526, + TRANSFER_TO_LAST_NON_INSTANCE = 527, + SET_ACTIVE_LOCAL_CHARACTER_ID = 528, + DISPLAY_MESSAGE_BOX = 529, + MESSAGE_BOX_RESPOND = 530, + CHOICE_BOX_RESPOND = 531, + SERVER_SET_USER_CTRL_COMP_PAUSE = 532, + SET_CHARACTER_AUTO_RUN = 533, + FOLLOW_WAYPOINTS = 534, + SWAP_DECAL_AND_COLOR = 535, + CONTINUE_WAYPOINTS = 536, + SMASH = 537, + UN_SMASH = 538, + GET_IS_SMASHED = 539, + GET_UP_VECTOR = 540, + SET_GRAVITY_SCALE = 541, + SET_GRAVITY_SCALE_FOR_RIGID_BODY = 542, + STOP_MOVING = 543, + SET_PATHING_SPEED = 544, + SET_SHIELDED = 545, + SET_SHOOTING_GALLERY_RETICULE_EFFECT = 546, + PLACE_MODEL_RESPONSE = 547, + SET_DODGE_INFO = 548, + GET_DODGE_INFO = 549, + SET_SKILL_ATTACK_SPEED = 550, + GET_SKILL_COOLDOWN_GROUP = 551, + GET_INITIAL_SKILL_COOLDOWN = 552, + GET_SKILL_COOLDOWN_REMAINING = 553, + GET_GLOBAL_COOLDOWN = 554, + SET_GLOBAL_COOLDOWN = 555, + RESET_GLOBAL_COOLDOWN = 556, + FINDINVENTORY_ITEM = 558, + PATH_STUCK = 559, + SET_CURRENT_PATH = 560, + SET_JET_PACK_MODE = 561, + SET_JET_PACK_TIME = 562, + PET_FOLLOW_OWNER = 563, + PLAYER_DIED = 564, + REGISTER_PET_ID = 565, + REGISTER_PET_DBID = 566, + GET_PET_ID = 567, + SHOW_ACTIVITY_COUNTDOWN = 568, + DISPLAY_TOOLTIP = 569, + SET_PHANTOM_BASE = 570, + GET_MOTION_STATE = 571, + GET_MOTION_CONFIG = 572, + SET_ACTIVE_PROJECTILE_SKILL = 573, + INITIALIZE_MISSION_VISUALS = 574, + GET_MISSIONS = 575, + START_ACTIVITY_TIME = 576, + ADD_ACTIVITY_TIME = 577, + GUILD_GET_SIZE = 578, + GUILD_CAN_WE_INVITE = 579, + GUILD_CAN_WE_KICK = 580, + SET_CHAR_GUILD_INFO = 581, + GET_CHAR_GUILD_INFO = 582, + GET_CHAR_IS_IN_GUILD = 583, + RE_RENDER_NAME_BILLBOARD = 584, + IS_IN_LOCAL_CHAR_PROXIMITY = 585, + GUILD_SET_STATUS = 586, + GUILD_ADD_PLAYER = 587, + GUILD_REMOVE_PLAYER = 588, + GUILD_UPDATE_PLAYER_NAME = 589, + GUILD_SET_PLAYER_RANK = 590, + GUILD_SET_ONLINE_STATUS = 591, + GUILD_INVITE = 592, + REQUEST_GUILD_DATA = 593, + POPULATE_GUILD_DATA = 594, + GET_CACHED_GUILD_DATA = 595, + GUILD_RENDER_NAME = 596, + GET_IS_SUPPORTED = 600, + CHARACTER_SUPPORT_CHANGED = 601, + ACTIVITY_PAUSE = 602, + USE_NON_EQUIPMENT_ITEM = 603, + REQUEST_USE_ITEM_ON = 604, + REQUEST_USE_ITEM_ON_TARGET = 605, + USE_ITEM_ON = 606, + USE_ITEM_RESULT = 607, + GET_PARENT_OBJ = 608, + SET_PARENT_OBJ = 609, + GET_UPDATES_WITH_PARENT_POSITION = 610, + PARENT_REMOVED = 611, + PARENT_LEFT_SCOPE = 612, + PARENT_ENTERED_SCOPE = 613, + CHILD_LOADED = 614, + CHILD_REMOVED = 615, + CHILD_DETACHED = 616, + CHILD_ENTERED_SCOPE = 617, + CHILD_LEFT_SCOPE = 618, + GET_CHILD_OBJECTS = 619, + ZONE_TRANSFER_FINISHED = 621, + CHAT_CONNECTION_UPDATE = 622, + PLATFORM_AT_LAST_WAYPOINT = 623, + LOOT_TAKE_ALL = 624, + GET_EQUIPPED_ITEM_INFO = 625, + DISPLAY_GUILD_CREATE_BOX = 626, + GET_EDITOR_LEVEL = 627, + GET_ACCOUNT_ID = 628, + GET_LAST_LOGOUT = 629, + GET_LAST_PROP_MOD_DISPLAY_TIME = 630, + SET_LAST_PROP_MOD_DISPLAY_TIME = 631, + SHOW_ACTIVITY_SUMMARY = 632, + CAN_RECEIVE_ALL_REWARDS = 633, + GET_ACTIVITY_REWARD = 634, + LOOT_CLOSE_WINDOW = 635, + GET_BLUEPRINT_ID = 636, + NOTIFY_BLUEPRINT_UPDATE = 637, + FETCH_MODEL_METADATA_REQUEST = 638, + FETCH_MODEL_METADATA_RESPONSE = 639, + COMMAND_PET = 640, + PET_RESPONSE = 641, + GET_ICON_ABOVE_HEAD_STATE = 642, + GET_ICON_ABOVE_HEAD = 643, + ICON_FINISHED_LOADING = 644, + ADD_PET_STATE = 645, + REMOVE_PET_STATE = 646, + SET_PET_STATE = 647, + REQUEST_ACTIVITY_SUMMARY_LEADERBOARD_DATA = 648, + SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA = 649, + SET_ON_TEAM = 650, + GET_PET_HAS_STATE = 651, + FIND_PROPERTY = 652, + SET_PET_MOVEMENT_STATE = 653, + GET_ITEM_TYPE = 654, + GET_ITEM_INFO_KEY = 655, + NOTIFY_OBJECT = 656, + IS_PET_WILD = 657, + CLIENT_NOTIFY_PET = 659, + NOTIFY_PET = 660, + NOTIFY_PET_TAMING_MINIGAME = 661, + START_SERVER_PET_MINIGAME_TIMER = 662, + CLIENT_EXIT_TAMING_MINIGAME = 663, + GET_BUILDMODE_ACTIVE = 664, + GET_PET_TAMING_MINIGAME_ACTIVE = 665, + PET_TAMING_OBJECT_PICKED = 666, + PET_TAMING_MINIGAME_RESULT = 667, + PET_TAMING_TRY_BUILD_RESULT = 668, + SET_PET_TAMING_MODEL = 669, + GET_PET_TAMING_MODEL = 670, + PET_ON_SWITCH = 671, + PET_OFF_SWITCH = 672, + NOTIFY_TAMING_BUILD_SUCCESS = 673, + NOTIFY_TAMING_MODEL_LOADED_ON_SERVER = 674, + NOTIFY_TAMING_PUZZLE_SELECTED = 675, + GET_INSTRUCTION_COUNT = 676, + GET_IS_NPC = 677, + ACTIVATE_BUBBLE_BUFF = 678, + DECTIVATE_BUBBLE_BUFF = 679, // thanks netdevil + EXHIBIT_VOTE = 680, + ADD_PET_TO_PLAYER = 681, + REMOVE_PET_FROM_PLAYER = 682, + REQUEST_SET_PET_NAME = 683, + SET_PET_NAME = 684, + PET_NAME_CHANGED = 686, + GET_PET_AT_INDEX = 687, + GET_LOT_FOR_PET_BY_DBID = 688, + GET_NAME_FOR_PET_BY_DBID = 689, + GET_ACTIVE_PET_OBJ_ID = 690, + GET_ACTIVE_PET_INVENTORY_OBJ_ID = 691, + SHOW_PET_ACTION_BUTTON = 692, + SET_EMOTE_LOCK_STATE = 693, + GET_EMOTE_LOCK_STATE = 694, + LEAVE_TEAM_MSG = 695, + TEAM_KICK_PLAYER_MSG = 697, + TEAM_SET_LEADER_SEND_MSG = 698, + USE_ITEM_ON_CLIENT = 699, + DOES_FORWARD_TARGET_CLICKING = 700, + CHECK_USE_REQUIREMENTS = 701, + USE_REQUIREMENTS_RESPONSE = 702, + USE_ITEM_REQUIREMENTS_RESPONSE = 703, + PET_ADDED_TO_WORLD = 704, + BOUNCER_TRIGGERED = 705, + EXHIBIT_QUERY_CURRENT_MODEL = 706, + EXHIBIT_QUERY_CURRENT_MODEL_RESPONSE = 707, + EXHIBIT_ATTEMPT_VOTE = 708, + EXHIBIT_VOTE_RESPONSE = 709, + EHIBIT_REQUERYMODELS = 710, + IS_SKILL_ACTIVE = 711, + TOGGLE_ACTIVE_SKILL = 712, + PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT = 713, + EXHIBIT_GET_INFO = 714, + GET_PROPERTY_DATA = 715, + DOWNLOAD_PROPERTY_DATA = 716, + QUERY_PROPERTY_DATA = 717, + MODEL_MODERATION_ACTION = 719, + NOTIFY_SERVER_UGC_REVIEW_READY = 720, + NOTIFY_CLIENT_UGC_REVIEW_READY = 721, + OLD_USE_ITEM_ON = 722, + FIND_PROPERTY_FOR_SALE_RESPONSE = 723, + PROPERTY_EDITOR_BEGIN = 724, + PROPERTY_EDITOR_END = 725, + PROPERTY_EDITOR_SET_MODE = 726, + TOGGLE_TRIGGER = 727, + FIRE_EVENT = 728, + IS_MINIFIG_IN_A_BUBBLE = 729, + GET_ITEM_INFO = 730, + MISSION_NEEDS_LOT = 731, + STOP_PATHING = 732, + START_PATHING = 733, + ACTIVATE_BUBBLE_BUFF_FROM_SERVER = 734, + DEACTIVATE_BUBBLE_BUFF_FROM_SERVER = 735, + HAS_SKILL = 736, + NOTIFY_CLIENT_ZONE_OBJECT = 737, + MOVE_OBJECT = 738, + ROTATE_OBJECT = 739, + GET_SPAWNER_CONFIG_DATA = 740, + UPDATE_SPAWNER_CONFIG_DATA = 741, + TURN_AROUND = 743, + GO_FORWARD = 744, + GO_BACKWARD = 745, + UPDATE_REPUTATION = 746, + GET_REPUTATION = 747, + ADD_REPUTATION = 748, + UPDATE_PROPERTY_DATA = 749, + PROPERTY_RENTAL_RESPONSE = 750, + EXHIBIT_PLACEMENT_RESPONSE = 751, + SQUIRT_WITH_WATERGUN = 752, + GET_VOTES_LEFT = 753, + ADJUST_VOTES_LEFT = 754, + EVADE_TARGET = 755, + STOPPED_EVADING = 756, + GET_PET_HAS_ABILITY = 757, + REQUEST_PLATFORM_RESYNC = 760, + PLATFORM_RESYNC = 761, + PLAY_CINEMATIC = 762, + END_CINEMATIC = 763, + CINEMATIC_UPDATE = 764, + ATTACH_CAMERA_TO_RAIL = 765, + DETACH_CAMERA_FROM_RAIL = 766, + TOGGLE_GHOST_REFERENCE_OVERRIDE = 767, + SET_GHOST_REFERENCE_POSITION = 768, + GET_GHOST_REFERENCE_POSITION = 769, + FIRE_EVENT_SERVER_SIDE = 770, + GET_PET_ABILITY_OBJECT = 771, + TEAM_INVITE_MSG_FROM_UI = 772, + ADD_CAMERA_EFFECT = 773, + REMOVE_CAMERA_EFFECT = 774, + REMOVE_ALL_CAMERA_EFFECTS = 775, + GET_MY_PROPERTIES_IN_THIS_ZONE = 776, + IS_MODEL_WITHIN_PROPERTY_BOUNDS = 777, + PROPERTY_DATA_RESULTS = 778, + ON_UN_SERIALIZE = 779, + SCRIPT_NETWORK_VAR_UPDATE = 781, + ADD_OBJECT_TO_GROUP = 783, + REMOVE_OBJECT_FROM_GROUP = 784, + IS_OBJECT_STATIC = 785, + GET_HAS_MISSION = 786, + GET_MISSION_TARGET_LOT = 787, + GET_MISSION_OFFERER_LOT = 788, + USE_UNIQUE_ITEM = 789, + GET_IS_PET = 790, + DELETE_PROPERTY = 791, + CREATEMODEL_FROM_CLIENT = 792, + UPDATE_MODEL_FROM_CLIENT = 793, + DELETE_MODEL_FROM_CLIENT = 794, + SHOW_PROPERTY_BOUNDS = 795, + SET_PROPERTY_I_DS = 796, + PLAY_FACE_DECAL_ANIMATION = 797, + ADD_ACTIVITY_USER = 798, + REMOVE_ACTIVITY_USER = 799, + GET_NUM_ACTIVITY_USERS = 800, + ACTIVITY_USER_EXISTS = 801, + DO_COMPLETE_ACTIVITY_EVENTS = 805, + SET_ACTIVITY_PARAMS = 806, + SET_ACTIVITY_USER_DATA = 807, + GET_ACTIVITY_USER_DATA = 808, + DO_CALCULATE_ACTIVITY_RATING = 809, + ND_AUDIO_POST_SETUP = 812, + ND_AUDIO_PRE_SHUTDOWN = 813, + SET_ND_AUDION_LISTENER_STANCE = 814, + SET_UP_ND_AUDIO_EMIITTER = 815, + SHUT_DOWN_ND_AUDIO_EMITTER = 816, + METAIFY_ND_AUDIO_EMITTER = 817, + UN_METAIFY_ND_AUDIO_EMITTER = 818, + METAIFY_ND_AUDIO_EMITTERS = 819, + UN_METAIFY_ND_AUDIO_EMITTERS = 820, + PLAY_ND_AUDIO_EMITTER = 821, + STOP_ND_AUDIO_EMITTER = 822, + STOP_ND_AUDIO_EMITTER_ALL = 823, + SET_ND_AUDIO_EMITTER_PARAMETER = 824, + SET_ND_AUDIO_EMITTERS_PARAMETER = 825, + ND_AUDIO_CALLBACK = 826, + ACTIVATE_ND_AUDIO_MUSIC_CUE = 827, + DEACTIVATE_ND_AUDIO_MUSIC_CUE = 828, + FLASH_ND_AUDIO_MUSIC_CUE = 829, + SET_ND_AUDIO_MUSIC_PARAMETER = 830, + PLAY2_D_AMBIENT_SOUND = 831, + STOP2_D_AMBIENT_SOUND = 832, + PLAY3_D_AMBIENT_SOUND = 834, + STOP3_D_AMBIENT_SOUND = 835, + ACTIVATE_ND_AUDIO_MIXER_PROGRAM = 836, + DEACTIVATE_ND_AUDIO_MIXER_PROGRAM = 837, + UPDATE_ACTIVITY_LEADERBOARD = 838, + ACTIVITY_LEADERBOARD_UPDATED = 839, + ENTER_PROPERTY1 = 840, + ENTER_PROPERTY2 = 841, + PROPERTY_ENTRANCE_SYNC = 842, + SEND_PROPERTY_POPULATION_TO_CLIENT = 843, + SEN_PROPERTY_PLAQUE_VIS_UPDATE = 844, + PROPERTY_SELECT_QUERY = 845, + CREATE_POSITION_STRING = 848, + GET_PARALLEL_POSITION = 849, + PARSE_CHAT_MESSAGE = 850, + SET_MISSION_TYPE_STATE = 851, + GET_LOCATIONS_VISITED = 852, + GET_MISSION_TYPE_STATES = 853, + GET_TIME_PLAYED = 854, + SET_MISSION_VIEWED = 855, + SLASH_COMMAND_TEXT_FEEDBACK = 856, + HANDLE_SLASH_COMMAND_KORE_DEBUGGER = 857, + BROADCAST_TEXT_TO_CHATBOX = 858, + OPEN_PROPERTY_MANAGEMENT = 860, + OPEN_PROPERTY_VENDOR = 861, + VOTE_ON_PROPERTY = 862, + UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK = 863, + NOTIFY_PLAYER_OF_PROPERTY_SUBMISSION = 865, + NOTIFY_PLAYER_OF_MODEL_SUBMISSION = 866, + PHYSICS_SYSTEM_LOADED = 867, + CLIENT_TRADE_REQUEST = 868, SERVER_TRADE_REQUEST = 869, - SERVER_TRADE_INVITE = 870, - CLIENT_TRADE_REPLY = 871, + SERVER_TRADE_INVITE = 870, + CLIENT_TRADE_REPLY = 871, SERVER_TRADE_REPLY = 872, - SERVER_TRADE_INITIAL_REPLY = 873, - SERVER_TRADE_FINAL_REPLY = 874, - CLIENT_TRADE_UPDATE = 875, + SERVER_TRADE_INITIAL_REPLY = 873, + SERVER_TRADE_FINAL_REPLY = 874, + CLIENT_TRADE_UPDATE = 875, SERVER_SIDE_TRADE_UPDATE = 876, - SERVER_TRADE_UPDATE = 877, - CLIENT_TRADE_CANCEL = 878, - CLIENT_SIDE_TRADE_CANCEL = 879, - CLIENT_TRADE_ACCEPT = 880, + SERVER_TRADE_UPDATE = 877, + CLIENT_TRADE_CANCEL = 878, + CLIENT_SIDE_TRADE_CANCEL = 879, + CLIENT_TRADE_ACCEPT = 880, SERVER_SIDE_TRADE_ACCEPT = 881, SERVER_SIDE_TRADE_CANCEL = 882, - SERVER_TRADE_CANCEL = 883, - SERVER_TRADE_ACCEPT = 884, - READY_FOR_UPDATES = 888, - ORIENT_TO_OBJECT = 905, - ORIENT_TO_POSITION = 906, - ORIENT_TO_ANGLE = 907, - BOUNCER_ACTIVE_STATUS = 942, - UN_USE_BBB_MODEL = 999, - BBB_LOAD_ITEM_REQUEST = 1000, - BBB_SAVE_REQUEST = 1001, - BBB_SAVE_RESPONSE = 1006, - NOTIFY_CLIENT_OBJECT = 1042, - DISPLAY_ZONE_SUMMARY = 1043, - ZONE_SUMMARY_DISMISSED = 1044, - ACTIVITY_STATE_CHANGE_REQUEST = 1053, - MODIFY_PLAYER_ZONE_STATISTIC = 1046, - START_BUILDING_WITH_ITEM = 1057, - START_ARRANGING_WITH_ITEM = 1061, - FINISH_ARRANGING_WITH_ITEM = 1062, - DONE_ARRANGING_WITH_ITEM = 1063, - SET_BUILD_MODE = 1068, - BUILD_MODE_SET = 1069, - SET_BUILD_MODE_CONFIRMED = 1073, - NOTIFY_CLIENT_FAILED_PRECONDITION = 1081, - MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1093, - MODULAR_BUILD_BEGIN = 1094, - MODULAR_BUILD_END = 1095, - MODULAR_BUILD_MOVE_AND_EQUIP = 1096, - MODULAR_BUILD_FINISH = 1097, - REPORT_BUG = 1198, - MISSION_DIALOGUE_CANCELLED = 1129, - ECHO_SYNC_SKILL = 1144, - SYNC_SKILL = 1145, - REQUEST_SERVER_PROJECTILE_IMPACT = 1148, - DO_CLIENT_PROJECTILE_IMPACT = 1151, - MODULAR_BUILD_CONVERT_MODEL = 1155, - SET_PLAYER_ALLOWED_RESPAWN = 1165, - UI_MESSAGE_SERVER_TO_SINGLE_CLIENT = 1184, - UI_MESSAGE_SERVER_TO_ALL_CLIENTS = 1185, - PET_TAMING_TRY_BUILD = 1197, - REQUEST_SMASH_PLAYER = 1202, - FIRE_EVENT_CLIENT_SIDE = 1213, - TOGGLE_GM_INVIS = 1218, - CHANGE_OBJECT_WORLD_STATE = 1223, - VEHICLE_LOCK_INPUT = 1230, - VEHICLE_UNLOCK_INPUT = 1231, - RACING_RESET_PLAYER_TO_LAST_RESET = 1252, + SERVER_TRADE_CANCEL = 883, + SERVER_TRADE_ACCEPT = 884, + GET_TRADE_INFO = 885, + KF_LOADED = 886, + BRICKS_LOADED = 887, + READY_FOR_UPDATES = 888, + SEND_READY_FOR_UPDATES = 889, + SET_LAST_CUSTOM_BUILD = 890, + GET_LAST_CUSTOM_BUILD = 891, + GET_STATUS_EFFECT_BY_ID = 892, + GET_ALL_STATUS_EFFECTS = 893, + CHILD_RENDER_COMPONENT_READY = 894, + NOTIFY_APPEARANCE_CHANGED_MSG = 895, + SET_PHYSICS_MOTION_STATE = 896, + GET_PHYSICS_MOTION_STATE = 897, + ATTACH_GRAYSCALE_EFFECT = 898, + ATTACH_FADE_EFFECT = 899, + ATTACH_CHANGE_RENDER_ENVIRONMENT_EFFECT = 900, + FORCE_MOVEMENT = 901, + CANCEL_FORCE_MOVEMENT = 902, + SET_IGNORE_PROJECTILE_COLLISION = 903, + GET_IGNORE_PROJECTILE_COLLISION = 904, + ORIENT_TO_OBJECT = 905, + ORIENT_TO_POSITION = 906, + ORIENT_TO_ANGLE = 907, + NOTIFY_CLIENT_UGC_MODEL_READY = 909, + NOTIFY_CLIENT_UGC_ICON_READY = 911, + PROPERTY_BUILD_MODE_CHANGED = 912, + PROPERTY_BUILD_MODE_UPDATE = 913, + PROPERTY_DELETION_ACTION = 914, + PROPERTY_MODERATION_STATUS_ACTION = 915, + PROPERTY_MODERATION_STATUS_ACTION_RESPONSE = 916, + PROPERTY_MODERATION_STATUS_UPDATE = 917, + PROPERTY_NEEDS_GM_ATTENTION = 918, + PROPERTY_MODERATION_CHANGED = 919, + INVENTORY_REFRESH_ITEM_DETAILS = 922, + INVENTORY_LOAD_CUSTOM_ICON = 923, + GET_STATUS_EFFECT_BY_TYPE = 924, + RELEASE_CHARGED_SKILL = 925, + PROPERTY_RELOAD_DB = 926, + SET_PLAYER_TARGET = 927, + GET_PLAYER_TARGET = 928, + LOCK_CAMERA_NETWORKED = 929, + MOVE_CAMERA_NETWORKED = 930, + REBUILD_ACTIVATED = 931, + BOUNCE_NOTIFICATION = 932, + REQUEST_CLIENT_BOUNCE = 934, + GET_RECENT_BOUNCED = 935, + SET_RECENT_BOUNCED = 936, + SET_ACTIVE_STATE = 937, + GET_ACTIVE_STATE = 938, + HAS_COMPONENT_TYPE = 939, + GET_COMPONENT_LIST = 940, + RESPONDS_TO_FACTION = 941, + BOUNCER_ACTIVE_STATUS = 942, + HF_ATTRIBUTES_PUSH = 943, + HF_ATTRIBUTES_PULL = 944, + HF_ATTRIBUTES_PATH_DISPLAY = 945, + HF_CONTROLS_PULL = 946, + HF_OBJECT_SELECTED = 947, + HF_PLACEHOLDER_UPDATE = 948, + HF_PLACEHOLDER_TOGGLE = 949, + HF_GET_ASSOCIATED_PATHS = 950, + HF_GETS_WANT_PATH = 951, + GET_RECENT_MOVEMENT_KEYS = 952, + TRACK_RECENT_MOVEMENT_KEYS = 953, + PHYSICS_MOVEMENT_NOTIFICATION_REQUEST = 954, + PHYSICS_MOVEMENT_NOTIFICATION = 955, + MOVE_INVENTORY_SINGLE = 956, + MOVE_INVENTORY_BATCH = 957, + MINI_GAME_SET_PARAMETERS = 958, + MINI_GAME_GET_TEAM_SKILLS = 961, + MINI_GAME_GET_TEAM_SCORE = 963, + MINI_GAME_GET_PLAYER_SCORE = 967, + MINI_GAME_GET_TEAM_COLOR = 972, + MINI_GAME_GET_TEAM_PLAYERS = 975, + MINI_GAME_UPDATE_CLIENT = 976, + MINI_GAME_GET_TEAM = 977, + MINI_GAME_GET_PARAMETERS = 978, + OBJECT_ACTIVATED_CLIENT = 980, + IS_RESURRECTING = 983, + GET_ITEM_OWNER = 984, + GET_STORED_CONFIG_DATA = 985, + SET_STORED_CONFIG_DATA = 986, + ON_PLAYER_RESSURECTED = 988, + PLAYER_RESURRECTION_FINISHED = 989, + TRANSFORM_CHANGELING_BUILD = 990, + RETURN_CHANGELING_BUILD_ID = 991, + SPEND_BRICK_INVENTORY_FOR_LXFML = 992, + BRICK_INVENTORY_FOR_LXFML_SPENT = 993, + REBUILD_BBB_AUTOSAVE_MSG = 995, + SET_BBB_AUTOSAVE = 996, + USE_BBB_INVENTORY = 998, + UN_USE_BBB_MODEL = 999, + BBB_LOAD_ITEM_REQUEST = 1000, + BBB_SAVE_REQUEST = 1001, + BBBLUP_SAVE_REQUEST = 1002, + BBB_GET_METADATA_SOURCE_ITEM = 1003, + BBB_RESET_METADATA_SOURCE_ITEM = 1004, + BBB_SAVE_RESPONSE = 1005, + PLAYER_EXIT = 1006, + SET_PVP_STATUS = 1008, + GET_PVP_STATUS = 1009, + IS_VALID_PVP_TARGET = 1010, + PVP_RENDER_NAME = 1011, + ATTACH_OBJECT = 1012, + DETACH_OBJECT = 1013, + BOUNCE_SUCCEEDED = 1014, + GET_GAME_OBJECT_POINTER = 1015, + PHANTOM_HKX_LOADED = 1016, + DELAY_CREATE_EFFECT = 1017, + CHOICE_BUILD_SELECTION_CONFIRMED = 1018, + NOTIFY_FADE_UP_VIS_COMPLETE = 1019, + ITEM_HAS_NEW_INFO = 1020, + RESET_SECONDARY_ANIMATION = 1021, + GET_PICK_TYPE = 1022, + SET_PICK_TYPE = 1023, + GET_PRIORITY_PICK_LIST_TYPE = 1024, + REQUEST_PICK_TYPE_UPDATE = 1025, + GET_OVERRIDE_PICK_TYPE = 1026, + REQUEST_DISPLAY_OBJECT_INFO = 1027, + REQUEST_SERVER_OBJECT_INFO = 1028, + REQUEST_OBJECT_INFO_AS_XML = 1029, + GET_OBJECT_REPORT_INFO = 1030, + GET_OBJECT_REPORT_WINDOW_CLOSE = 1031, + GET_OBJECT_REPORT_STATUS = 1032, + GET_MISSION_DATA_FOR_OBJECT_REPORT = 1033, + GET_OBJECT_ROLLOVER_INFO = 1034, + PERFORM_ZONE_ANALYSIS = 1035, + UPDATE_HK_VISUAL_IZATION = 1036, + CLEAR_ITEMS_OWNER = 1037, + APPLY_LINEAR_IMPULSE = 1038, + APPLY_ANGULAR_IMPULSE = 1039, + GET_CONTACT_NORMALS = 1040, + IS_WATCHING_FOR_EMOTE = 1041, + NOTIFY_CLIENT_OBJECT = 1042, + DISPLAY_ZONE_SUMMARY = 1043, + ZONE_SUMMARY_DISMISSED = 1044, + GET_PLAYER_ZONE_STATISTIC = 1045, + MODIFY_PLAYER_ZONE_STATISTIC = 1046, + APPLY_EXTERNAL_FORCE = 1049, + GET_APPLIED_EXTERNAL_FORCE = 1050, + ITEM_EQUIPPED = 1052, + ACTIVITY_STATE_CHANGE_REQUEST = 1053, + OVERRIDE_FRICTION = 1054, + ARRANGE_WITH_ITEM = 1055, + CHECK_CAN_BUILD_WITH_ITEM = 1056, + START_BUILDING_WITH_ITEM = 1057, + START_BUILD_SESSION = 1058, + FINISH_BUILD_SESSION = 1059, + DONE_BUILD_SESSION = 1060, + START_ARRANGING_WITH_ITEM = 1061, + FINISH_ARRANGING_WITH_ITEM = 1062, + DONE_ARRANGING_WITH_ITEM = 1063, + START_ARRANGE_MODE = 1064, + ARRANGE_MODE_WITH_ITEM = 1065, + FINISH_ARRANGE_MODE = 1066, + DONE_ARRANGE_MODE = 1067, + SET_BUILD_MODE = 1068, + BUILD_MODE_SET = 1069, + CONFIRM_BUILD_MODE = 1070, + BUILD_MODE_CONFIRMATION = 1071, + BUILD_EXIT_CONFIRMATION = 1072, + SET_BUILD_MODE_CONFIRMED = 1073, + BUILD_MODE_NOTIFICATION = 1074, + BUILD_MODE_NOTIFICATION_REPORT = 1075, + CLIENT_USE_MODULE_ON = 1076, + SET_MODEL_TO_BUILD = 1077, + SPAWN_MODEL_BRICKS = 1078, + CHECK_PRECONDITION = 1079, + CHECK_ALL_PRECONDITIONS = 1080, + NOTIFY_CLIENT_FAILED_PRECONDITION = 1081, + GET_IS_ITEM_EQUIPPED_BY_LOT = 1082, + GET_IS_ITEM_EQUIPPED_BY_ID = 1083, + GET_OBJECT_DIRECTION_VECTORS = 1084, + GET_CASTABLE_SKILLS = 1085, + CHOICEBUILD_COMPLETE = 1086, + GET_MISSION_CHAT = 1087, + GET_MISSION_AUDIO = 1088, + MODULE_EQUIPPED = 1089, + MODULE_DROPPED = 1090, + MODULE_PICKED_UP = 1091, + MODULE_INFO = 1092, + MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1093, + MODULAR_BUILD_BEGIN = 1094, + MODULAR_BUILD_END = 1095, + MODULAR_BUILD_MOVE_AND_EQUIP = 1096, + MODULAR_BUILD_FINISH = 1097, + SET_REGISTRATION_FOR_UI_UPDATE = 1114, + GO_TO_WAYPOINT = 1115, + ARRIVED_AT_DESIRED_WAYPOINT = 1116, + CHECK_WITHIN_BOUNDS = 1117, + ATTACH_TO_BUILD_ASSEMBLY = 1118, + SET_BUILD_ASSEMBLY = 1119, + RESET_BUILD_ASSEMBLY = 1120, + GET_INVENTORY_ITEM_INFO = 1125, + GET_ITEM_DETAILS = 1126, + GET_BUILD_ACTIVATOR = 1127, + GET_MISSION_ANIMATION = 1128, + MISSION_DIALOGUE_CANCELLED = 1129, + MODULE_ASSEMBLY_DB_DATA = 1130, + MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131, + MODULE_ASSEMBLY_QUERY_DATA = 1132, + MODULE_ASSEMBLY_HKX_LOADED = 1133, + MODULE_ASSEMBLY_NIF_LOADED = 1134, + MODULE_ASSEMBLY_MAIN_NIF_LOADED = 1135, + MODULE_ASSEMBLY_KFM_LOADED = 1136, + GET_PRECONDITION_INFO = 1137, + GET_MODEL_LOT = 1138, + ANIMATION_FINISHED_PRELOADING = 1139, + CHILD_BUILD_ASSEMBLY_COMPLETE = 1140, + CHARACTER_UNSERIALIZED = 1141, + CHARACTER_NEEDS_TRANSITION = 1142, + SET_NEEDS_TRANSITION = 1143, + ECHO_SYNC_SKILL = 1144, + SYNC_SKILL = 1145, + GET_BEHAVIOR_HANDLE = 1146, + ADD_OUTSTANDING_BEHAVIOR = 1147, + REQUEST_SERVER_PROJECTILE_IMPACT = 1148, + OFF_WORLD_IMPACT_REQUEST = 1149, + SERVER_IMPACT_REQUEST = 1150, + DO_CLIENT_PROJECTILE_IMPACT = 1151, + MODULE_ASSEMBLY_PART_INFO = 1152, + GET_BUILD_TYPE = 1153, + CHECK_BUILD_TYPE = 1154, + MODULAR_BUILD_CONVERT_MODEL = 1155, + DO_NPC_SHOWCASE_MODEL_SUBMISSION = 1156, + GET_MISSION_I_DS_LIST = 1157, + SET_SHOWCASE_MISSION_NPC_VALS = 1158, + NOTIFY_SHOWCASE_MISSION_NP_COF_SUCCESS = 1159, + SEND_LUA_NOTIFICATION_REQUEST = 1160, + SEND_LUA_NOTIFICATION_CANCEL = 1161, + ACTIVATOR_TOGGLE = 1162, + MAKE_PHYSICS = 1163, + SET_RESPAWN_GROUP = 1164, + SET_PLAYER_ALLOWED_RESPAWN = 1165, + TOGGLE_SENDING_POSITION_UPDATES = 1166, + TOGGLE_RECEIVING_POSITION_UPDATES = 1167, + GET_ENEMY_PRECONDITIONS = 1168, + START_MODEL_VISUALIZATION = 1169, + PLACE_PROPERTY_MODEL = 1170, + PROPERTY_MODEL_PLACED = 1171, + OPEN_EXHIBIT_REPLACE_MODEL_UI = 1172, + REPLACE_SHOWCASEMODEL = 1173, + CLEAR_UI_HOOK_EXHIBIT_REPLACEMENT = 1174, + ATTACH_FLYTO_SCREEN_POS = 1175, + VEHICLE_GET_DEBUG_INFO = 1176, + VEHICLE_GET_MOVEMENT_INPUT_VALUES = 1177, + ACTIVITY_TIMER_SET = 1178, + ACTIVITY_TIMER_UPDATE = 1179, + ACTIVITY_TIMER_GET = 1180, + ACTIVITY_TIMER_STOP = 1181, + ACTIVITY_TIMER_DONE = 1182, + GET_ATTACK_PRIORITY = 1183, + UI_MESSAGE_SERVER_TO_SINGLE_CLIENT = 1184, + UI_MESSAGE_SERVER_TO_ALL_CLIENTS = 1185, + SET_LOSE_COINS_ON_DEATH = 1186, + LOAD_EFFECTS = 1187, + SET_CUSTOM_BUILD = 1188, + ACTIVITY_TIMER_RESET = 1189, + ACTIVITY_TIMER_STOP_ALL_TIMERS = 1190, + ACTIVITY_TIMER_MODIFY = 1191, + SET_KEYFRAM_TRANSFORM = 1192, + ADD_ACTIVITY_OWNER = 1193, + REMOVE_ACTIVITY_OWNER = 1194, + GET_CURRENT_ACTIVITY_OWNERS = 1195, + TOGGLE_SKILL_DEBUGGING = 1196, + PET_TAMING_TRY_BUILD = 1197, + REPORT_BUG = 1198, + REPORT_OFFENSIVE_MODEL = 1199, + REPORT_OFFENSIVE_PROPERTY = 1200, + GET_ACTIVITY_ID = 1201, + REQUEST_SMASH_PLAYER = 1202, + GET_TIMES_REQUESTED_SMASH = 1203, + RESPONSE_SMASH_PLAYER = 1204, + MODIFY_DAMAGE_ABSORPTION = 1205, + UNCAST_SKILL = 1206, + GET_SHOWCASE_MODEL_READY = 1207, + IS_SKILL_NEEDED = 1208, + GET_COMPONENT_DATA = 1209, + VEHICLE_SET_POWERSLIDE_METHOD = 1210, + SHOWS_NAMETAG = 1211, + FIRE_EVENT_CLIENT_SIDE = 1213, + GET_REQUIRES_NAME_RESUBMISSION = 1216, + SET_REQUIRES_NAME_RESUBMISSION = 1217, + TOGGLE_GM_INVIS = 1218, + GET_GM_INVIS = 1219, + KILLED_PLAYER = 1220, + GET_PICKUP_SKILLS = 1221, + GET_FACTION_SKILL = 1222, + CHANGE_OBJECT_WORLD_STATE = 1223, + GET_OBJECT_WORLD_STATE = 1224, + VISIBILITY_CHANGED = 1225, + MOTION_EFFECT_COMPLETE = 1226, + TOGGLE_FREEZE_MODE = 1227, + SHADER_RENDER_MSG_APPLIED = 1228, + PLAYER_RENAME_REQUEST = 1229, + VEHICLE_LOCK_INPUT = 1230, + VEHICLE_UNLOCK_INPUT = 1231, + SET_AIR_MOVEMENT = 1232, + MOVEMENT_STATE_CHANGED = 1233, + SKILL_MOVEMENT_CANCELLED = 1234, + AIR_MOVEMENT_COMPLETE = 1235, + CANCEL_AIR_MOVEMENT = 1236, + FORCE_MINIFIGURE_TEXTURE_UPDATE = 1237, + RESYNC_EQUIPMENT = 1238, + ADD_COMPONENT_TO_OBJECT = 1239, + VEHICLE_GET_MAX_GAME_SPEED = 1240, + VEHICLE_GET_MAX_GAME_SPEED_WITH_BOOST = 1241, + GET_SPEED_FACTOR = 1242, + FREEZE_INVENTORY = 1243, + ADD_STAT_TRIGGER = 1244, + ADD_STAT_TRIGGER_CHILD = 1245, + CHECK_TRIGGERS_AND_FIRE_IF_NEEDED = 1246, + STAT_EVENT_TRIGGERED = 1247, + GET_CURRENT_SPEED = 1248, + RACING_PLAYER_RANK_CHANGED = 1249, + RACING_PLAYER_WRONG_WAY_STATUS_CHANGED = 1250, + RACING_PLAYER_CROSSED_FINISH_LINE = 1251, + RACING_RESET_PLAYER_TO_LAST_RESET = 1252, RACING_SERVER_SET_PLAYER_LAP_AND_PLANE = 1253, - RACING_SET_PLAYER_RESET_INFO = 1254, - RACING_PLAYER_INFO_RESET_FINISHED = 1255, - LOCK_NODE_ROTATION = 1260, - VEHICLE_SET_WHEEL_LOCK_STATE = 1273, - NOTIFY_VEHICLE_OF_RACING_OBJECT = 1276, - SET_NAME_BILLBOARD_STATE = 1284, - PLAYER_REACHED_RESPAWN_CHECKPOINT = 1296, - HANDLE_UGC_EQUIP_POST_DELETE_BASED_ON_EDIT_MODE = 1300, - HANDLE_UGC_EQUIP_PRE_CREATE_BASED_ON_EDIT_MODE = 1301, - PROPERTY_CONTENTS_FROM_CLIENT = 1305, - GET_MODELS_ON_PROPERTY = 1306, - MATCH_REQUEST = 1308, - MATCH_RESPONSE = 1309, - MATCH_UPDATE = 1310, - MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131, - MODULE_ASSEMBLY_QUERY_DATA = 1132, - SHOW_BILLBOARD_INTERACT_ICON = 1337, - CHANGE_IDLE_FLAGS = 1338, - VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340, - VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341, - VEHICLE_NOTIFY_SERVER_ADD_PASSIVE_BOOST_ACTION = 1342, - VEHICLE_NOTIFY_SERVER_REMOVE_PASSIVE_BOOST_ACTION = 1343, - VEHICLE_ADD_SLOWDOWN_ACTION = 1344, - VEHICLE_REMOVE_SLOWDOWN_ACTION = 1345, - VEHICLE_NOTIFY_SERVER_ADD_SLOWDOWN_ACTION = 1346, - VEHICLE_NOTIFY_SERVER_REMOVE_SLOWDOWN_ACTION = 1347, - BUYBACK_FROM_VENDOR = 1350, - SET_PROPERTY_ACCESS = 1366, + RACING_SET_PLAYER_RESET_INFO = 1254, + RACING_PLAYER_INFO_RESET_FINISHED = 1255, + RACING_PLAYER_OUT_OF_TRACK_BOUNDS = 1256, + RACING_SYNC_INFO = 1257, + RACING_PLAYER_KEEP_ALIVE = 1258, + RACING_SERVER_KEEP_ALIVE = 1259, + LOCK_NODE_ROTATION = 1260, + GET_PHYSICS_COLLIDABLE = 1261, + SET_PHYSICS_COLOR_FOR_DEBUG = 1262, + GET_PHYSICS_COLOR_FOR_DEBUG = 1263, + SET_PHYSICS_TEXT_AND_STATE_FOR_DEBUG = 1264, + REQUEST_INFO_FOR_PHYSICS_DEBUGGER = 1265, + GET_COLLIDABLE_AT_ADDRESS = 1266, + REQUEST_SERVER_GET_COLLIDABLE_REPORT = 1267, + COLLISION_POINT_ADDED = 1268, + COLLISION_POINT_REMOVED = 1269, + SET_ATTACHED = 1270, + SET_DESTROYABLE_MODEL_BRICKS = 1271, + VEHICLE_SET_POWERSLIDE_LOCK_WHEELS = 1273, + VEHICLE_SET_WHEEL_LOCK_STATE = 1273, + SHOW_HEALTH_BAR = 1274, + GET_SHOWS_HEALTH_BAR = 1275, + NOTIFY_VEHICLE_OF_RACING_OBJECT = 1276, + ENABLE_CLIENT_EQUIP_MODE = 1278, + CLIENT_EQUIP_MODE_WAS_CHANGED = 1279, + VEHICLE_GET_SPAWN_HEIGHT = 1281, + SET_NAME_BILLBOARD_STATE = 1284, + CHECK_TARGETING_REQUIREMENTS = 1285, + VEHICLE_CAN_WRECK = 1286, + ATTACH_RENDER_EFFECT = 1287, + DETACH_RENDER_EFFECT = 1288, + IS_PET_USING_ABILITY = 1289, + SET_BLOCKING = 1290, + GET_BLOCKING = 1291, + UPDATE_BLOCKING = 1292, + CHECK_DAMAGE_RESULTS = 1293, + GET_OBJECT_IS_IN_RENDER_PIPE = 1294, + ATTACH_MOTION_FX_ARC = 1295, + PLAYER_REACHED_RESPAWN_CHECKPOINT = 1296, + GET_LAST_RESPAWN_CHECKPOINT = 1297, + GET_VEHICLE_DEBUG_COLLISIONS = 1298, + VISITING_PROPERTY = 1299, + HANDLE_UGC_POST_DELETE_BASED_ON_EDIT_MODE = 1300, + HANDLE_UGC_POST_CREATE_BASED_ON_EDIT_MODE = 1301, + WORLD_CHECK_RESPONSE = 1302, + ADD_DAMAGE_REDUCTION = 1303, + REMOVE_DAMAGE_REDUCTION = 1304, + PROPERTY_CONTENTS_FROM_CLIENT = 1305, + GET_MODELS_ON_PROPERTY = 1306, + IS_SHOWCASE_DISPLAY_PEDESTAL = 1307, + MATCH_REQUEST = 1308, + MATCH_RESPONSE = 1309, + MATCH_UPDATE = 1310, + IS_DEFAULT_SKILL_ACTIVE = 1311, + PROPERTY_EDITOR_CARRY = 1312, + GET_LOOT_OWNER_ID = 1313, + GET_ENEMY_LOOT_TAG = 1314, + GET_NUM_SPAWNED_BRICKS = 1315, + SET_ITEM_EQUIP_TRANSFORM = 1316, + GET_ITEM_EQUIP_TRANSFORM = 1317, + GET_PROPERTY_BUDGET_INFO = 1318, + CHATBOX_IS_INIT = 1319, + GET_SPAWNED_I_DS = 1320, + GET_IMMUNITY = 1321, + GET_GM_IMMUNITY = 1322, + PROCESS_REMOTE_SLASH_COMMAND = 1323, + IS_FRIEND_MSG = 1324, + RACING_PLAYER_EVENT = 1325, + GET_PROPERTY_EDIT_VALID = 1326, + REFRESH_RENDER_ASSET = 1327, + VEHICLE_APPLY_STAT_CHANGE = 1328, + ZONE_LOADED_INFO = 1329, + B3_INTERFACE_ACTION = 1330, + RACING_STAT_MODIFIERS_FROM_CLIENT = 1332, + GET_RACING_STAT_MODIFIERS = 1333, + SET_RACING_STAT_MODIFIERS = 1334, + GET_RACING_LICENSE_LEVEL = 1335, + ADD_EQUIP_CAST = 1336, + SHOW_BILLBOARD_INTERACT_ICON = 1337, + CHANGE_IDLE_FLAGS = 1338, + GET_ANIMATION_FLAG = 1339, + VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340, + VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341, + NOTIFY_SERVER_VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1342, + NOTIFY_SERVER_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1343, + VEHICLE_ADD_SLOWDOWN_ACTION = 1344, + VEHICLE_REMOVE_SLOWDOWN_ACTION = 1345, + NOTIFY_SERVER_VEHICLE_ADD_SLOWDOWN_ACTION = 1346, + NOTIFY_SERVER_VEHICLE_REMOVE_SLOWDOWN_ACTION = 1347, + FORCE_UPDATE_ANIMATIONS = 1348, + MATCH_GET_DATA_FOR_PLAYER = 1349, + BUYBACK_FROM_VENDOR = 1350, + SET_INVENTORY_FILTER = 1351, + GET_INVENTORY_FILTER = 1352, + GET_INVENTORY_GROUPS = 1353, + GET_INVENTORY_GROUP = 1354, + UPDATE_INVENTORY_GROUP = 1355, + UPDATE_INVENTORY_UI = 1356, + UPDATE_INVENTORY_GROUP_CONTENTS = 1357, + CAN_REMOVE_ITEM_FROM_INVENTORY = 1362, + DRIVE_THIS_CAR = 1363, + VEHICLE_CAN_ADD_ACTIVE_BOOST = 1364, + VEHICLE_ADD_ACTIVE_BOOST = 1365, + SET_PROPERTY_ACCESS = 1366, ZONE_PROPERTY_MODEL_PLACED = 1369, - ZONE_PROPERTY_MODEL_ROTATED = 1370, - ZONE_PROPERTY_MODEL_REMOVED_WHILE_EQUIPPED = 1371, - ZONE_PROPERTY_MODEL_EQUIPPED = 1372, + ZONE_PROPERTY_MODEL_ROTATED = 1370, + ZONE_PROPERTY_MODEL_REMOVED_WHILE_EQUIPPED = 1371, + ZONE_PROPERTY_MODEL_EQUIPPED = 1372, ZONE_PROPERTY_MODEL_PICKED_UP = 1373, ZONE_PROPERTY_MODEL_REMOVED = 1374, - NOTIFY_RACING_CLIENT = 1390, - RACING_PLAYER_HACK_CAR = 1391, - RACING_PLAYER_LOADED = 1392, - RACING_CLIENT_READY = 1393, - UPDATE_CHAT_MODE = 1395, - VEHICLE_NOTIFY_FINISHED_RACE = 1396, - SET_CONSUMABLE_ITEM = 1409, - SET_STATUS_IMMUNITY = 1435, - SET_PET_NAME_MODERATED = 1448, - MODIFY_LEGO_SCORE = 1459, - RESTORE_TO_POST_LOAD_STATS = 1468, - SET_RAIL_MOVEMENT = 1471, - START_RAIL_MOVEMENT = 1472, - CANCEL_RAIL_MOVEMENT = 1474, - CLIENT_RAIL_MOVEMENT_READY = 1476, - PLAYER_RAIL_ARRIVED_NOTIFICATION = 1477, - UPDATE_PLAYER_STATISTIC = 1481, - MODULAR_ASSEMBLY_NIF_COMPLETED = 1498, - NOTIFY_NOT_ENOUGH_INV_SPACE = 1516, - TEAM_SET_LEADER = 1557, - TEAM_INVITE_CONFIRM = 1558, - TEAM_GET_STATUS_RESPONSE = 1559, - TEAM_ADD_PLAYER = 1562, - TEAM_REMOVE_PLAYER = 1563, - START_CELEBRATION_EFFECT = 1618, - ADD_BUFF = 1647, - SERVER_DONE_LOADING_ALL_OBJECTS = 1642, - PLACE_PROPERTY_MODEL = 1170, - VEHICLE_NOTIFY_HIT_IMAGINATION_SERVER = 1606, - ADD_RUN_SPEED_MODIFIER = 1505, - HANDLE_HOT_PROPERTY_DATA = 1511, - SEND_HOT_PROPERTY_DATA = 1510, - REMOVE_RUN_SPEED_MODIFIER = 1506, - UPDATE_PROPERTY_PERFORMANCE_COST = 1547, - PROPERTY_ENTRANCE_BEGIN = 1553, - SET_RESURRECT_RESTORE_VALUES = 1591, - VEHICLE_STOP_BOOST = 1617, - REMOVE_BUFF = 1648, - REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1666, - RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1667, - PLAYER_SET_CAMERA_CYCLING_MODE = 1676, - SET_MOUNT_INVENTORY_ID = 1726, - NOTIFY_SERVER_LEVEL_PROCESSING_COMPLETE = 1734, - NOTIFY_LEVEL_REWARDS = 1735, - DISMOUNT_COMPLETE = 1756, - MARK_INVENTORY_ITEM_AS_ACTIVE = 1767, - END + GET_VERSIONING_INFO = 1381, + OPEN_UG_BEHAVIOR_UI = 1382, + VEHICLE_NOTIFY_HIT_SMASHABLE = 1383, + GET_TETHER_RADIUS = 1384, + VEHICLE_NOTIFY_HIT_EXPLODER = 1385, + CHECK_NEAREST_ROCKET_LAUNCH_PRE_CONDITIONS = 1386, + REQUEST_NEAREST_ROCKET_LAUNCH_PRE_CONDITIONS = 1387, + CONFIGURE_RACING_CONTROL_CLIENT = 1389, + NOTIFY_RACING_CLIENT = 1390, + RACING_PLAYER_HACK_CAR = 1391, + RACING_PLAYER_LOADED = 1392, + RACING_CLIENT_READY = 1393, + POSSESSION_FINISHED_ATTACH = 1394, + UPDATE_CHAT_MODE = 1395, + VEHICLE_NOTIFY_FINISHED_RACE = 1396, + EQUIPPED_ITEM_STARTUP = 1397, + FACTION_TRIGGER_ITEM_EQUIPPED = 1400, + FACTION_TRIGGER_ITEM_UNEQUIPPED = 1401, + TOGGLE_PROPERTY_BEHAVIORS = 1402, + GET_UG_OBJECT_INFO = 1405, + RESET_PROPERTY_BEHAVIORS = 1406, + IS_PROPERTY_MODEL_RESET = 1407, + SET_UG_OBJECT_NAME_AND_DESCRIPTION = 1408, + SET_CONSUMABLE_ITEM = 1409, + VEHICLE_GET_CURRENT_LAP = 1410, + GET_UGID = 1411, + SET_UGID = 1412, + UGID_CHANGED = 1413, + RACING_GET_CURRENT_LAP_FOR_PLAYER = 1414, + SUB_ITEM_UN_EQUIPPED = 1415, + SET_CUSTOM_DROP_SHADOW_TEXTURE = 1416, + GET_PLAYER_KIT_FACTION = 1418, + USED_INFORMATION_PLAQUE = 1419, + RACING_ENABLE_WRONG_WAY_RESET = 1420, + RACING_TOGGLE_RUBBER_BANDING = 1421, + GET_RACING_CONTROL_DEBUG_INFO = 1422, + SET_PROPERTY_BOUNDS_VISIBILITY = 1423, + SET_PROPERTY_VENDOR_VISIBILITY = 1424, + SET_EQUIP_STATE = 1425, + NOTIFY_COMBAT_AI_STATE_CHANGE = 1426, + SET_PROPERTY_MODEL_INTERACTIVE = 1430, + SERVER_STATE_NOTIFY = 1431, + GET_SERVER_STATE = 1432, + GET_ICON_FOR_PROXIMITY = 1433, + GET_LEGO_CLUB_MEMBERSHIP_STATUS = 1434, + SET_STATUS_IMMUNITY = 1435, + GET_STATUS_IMMUNITY = 1436, + TEAM_IS_MEMBER = 1437, + ACTIVATE_BRICK_MODE = 1438, + GET_BUILD_OBJECT_ID = 1439, + SET_ANIMATION_ENABLED = 1444, + PAUSE_COOLDOWNS = 1446, + FORCE_UPDATE_RENDER_NODE = 1447, + SET_PET_NAME_MODERATED = 1448, + TOGGLE_STRAFE_MODE = 1449, + SET_SCHEME_SPEED_SCALE = 1450, + CANCEL_SKILL_CAST = 1451, + CHECK_PLAYER_ASSEMBLY_FOR_UNIQUE_MODULE_BY_LOT = 1454, + MODULE_ASSEMBLY_DB_DATA_TO_LUA = 1455, + IS_ALLY = 1458, + MODIFY_LEGO_SCORE = 1459, + GET_LEGO_SCORE = 1460, + GET_PLAYER_LEVEL = 1461, + NOTIFY_LEGO_SCORE_UPDATE = 1462, + SET_LEGO_SCORE = 1463, + UPDATE_BEHAVIOR_EXECUTION_DETAILS = 1466, + RESTORE_TO_POST_LOAD_STATS = 1468, + PICKUP_OBJECT_ERROR = 1469, + CHECK_AND_SHOW_INVENTORY_FULL_TIP = 1470, + SET_RAIL_MOVEMENT = 1471, + START_RAIL_MOVEMENT = 1472, + SET_UP_VECTOR = 1473, + CANCEL_RAIL_MOVEMENT = 1474, + GET_RAIL_INFO = 1475, + CLIENT_RAIL_MOVEMENT_READY = 1476, + PLAYER_RAIL_ARRIVED_NOTIFICATION = 1477, + NOTIFY_RAIL_ACTOVATOR_STATE_CHANGE = 1478, + REQUEST_RAIL_ACTIVATOR_STATE = 1479, + NOTIFY_REWARD_MAILED = 1480, + UPDATE_PLAYER_STATISTIC = 1481, + IS_IN_COMBAT = 1482, + IS_PRIMITIVE_MODEL_MSG = 1483, + SCALE_PRIMITICE_MODEL_MSG = 1484, + MODIFY_GHOSTING_DISTANCE = 1485, + PRIMITIVE_MODEL_CHANGED_MSG = 1487, + GET_PROPRTY_CLONE_ID = 1488, + REQUEST_LEAVE_PROPERTY = 1489, + REQUERY_PROPERTY_MODELS = 1491, + GET_BEHAVIOR_COUNT = 1492, + UPDATE_BEHAVIOR_CONTROLS = 1493, + MODULE_ASSEMBLY_LXFML_LOADED = 1494, + REQUEST_ASSEMBLED_LXFML = 1495, + ASSEMBLED_LXFML_LOADED = 1496, + GET_REORIENT_UP_VECTOR = 1497, + MODULAR_ASSEMBLY_NIF_COMPLETED = 1498, + CHARACTER_DISCONNECT_BEFORE_CREATE = 1499, + SEND_LAUNCH_TO_PREVIOUS_ZONE_TO_CLIENT = 1500, + ROCKETLAUNCH_REQUEST_DEFAULT_MAP_ID = 1501, + BEGIN_LAUNCH = 1502, + PROCESS_CLAIM_CODES = 1503, + GET_LAST_ZONE_ID = 1504, + ADD_RUN_SPEED_MODIFIER = 1505, + REMOVE_RUN_SPEED_MODIFIER = 1506, + SKILL_EVENT_FIRED = 1507, + SEND_HOT_PROPERTY_DATA = 1510, + GET_HOT_PROPERTY_DATA = 1511, + GET_EQUIPPED_ITEMS_IN_SET = 1512, + IS_ITEM_IN_SET = 1513, + GET_INVENTORY_TYPE_FOR_LOT = 1514, + GET_BANK_TYPE_FOR_LOT = 1515, + NOTIFY_NOT_ENOUGH_INV_SPACE = 1516, + IMPORT_MODEL_TO_BBB = 1517, + SEARCH_NEARBY_OBJECTS = 1518, + SEARCH_NEARBY_OBJECTS_REQUEST_BY_LOT = 1519, + REQUEST_OBJECT_POSITION_BY_ID = 1520, + SEARCH_NEARBY_OBJECTS_REQUEST_BY_COMPONENT = 1521, + SEARCH_NEARBY_OBJECTS_RESPONSE = 1522, + BROADCAST_NON_STANDARD_COLLISIONS = 1523, + GET_REGISTERED_NON_STANDARD_COLLISION_GROUP = 1524, + BROADCAST_CRUSHED_NOTIFICATIONS = 1525, + GET_REGISTERED_CRUSHED_COLLISION_GROUPS = 1526, + IS_BEING_CRUSHED = 1527, + GET_SUPPORTING_OBJECT = 1528, + TREAT_RIGID_BODY_COLLSIONS_AS_FIXED = 1529, + BROADCAST_TELEPORTED_WITHIN_NOTIFICATION = 1530, + GET_REGISTERED_TELEPORTED_WITHIN_OBJECT_GROUP = 1531, + GET_INTERPENTRATING_INFORMATION = 1532, + OBJECT_TELEPORTED_WITHIN = 1533, + SET_PHYSICS_SOLVER_PROPERTIES = 1534, + HAS_BEHAVIORS = 1535, + PLAY_BEHAVIOR_SOUND = 1536, + GET_PLAYER_BEHAVIOR_TIER = 1537, + GET_EMOTE_ANIMATION_TIME = 1538, + GET_CHARACTER_STAT_TRACKING = 1539, + PLAYER_INVENTORY_READY = 1540, + SET_PRECONDITIONS = 1541, + DETACH_SHADOW = 1542, + GET_LOOT_INFO = 1543, + GET_PLAYERS_ON_PROPERTY = 1544, + PROPERTY_SPAWN_BY_BEHAVIOR = 1545, + NOTIFY_PROPERTY_OF_EDIT_MODE = 1546, + UPDATE_PROPERTY_PERFORMANCE_COST = 1547, + GET_PROPERTY_PERFORMANCE_COST = 1548, + GET_INVENTORY_ITEM_WITH_SUBKEY = 1549, + DISPLAY_PROPERTY_SUMMARY_SCREEN = 1550, + VALIDATE_BBB_MODEL = 1551, + BBB_MODEL_VALIDATION = 1552, + PROPERTY_ENTRANCE_BEGIN = 1553, + CHECK_LIST_OF_PRECONDITIONS_FROM_LUA = 1554, + GET_PROPERTYIN_ZONE = 1555, + GET_ZONE_ID_FROM_MULTI_ZONE_ENTRANCE = 1556, + TEAM_SET_LEADER = 1557, + TEAM_INVITE_CONFIRM = 1558, + TEAM_GET_STATUS_RESPONSE = 1559, + MINI_GAME_ENABLE_LOCAL_TEAMS = 1560, + TEAM_INVITE_FINAL_RESPONSE = 1561, + TEAM_ADD_PLAYER = 1562, + TEAM_REMOVE_PLAYER = 1563, + TEAM_CREATE_LOCAL = 1564, + TEAM_GET_LOOT = 1565, + TEAM_SET_LOOT = 1566, + SET_ZERO_IMPULSE_AGAINST_COLLISION_GROUPS = 1567, + SET_CENTER_OF_MASS_TO_PHYSICAL_CENTER = 1568, + SET_INERTIA_INVERSE = 1569, + ADD_REMOVE_CLIMBING_LISTENER = 1570, + GET_INVENTORYITEM_DETAILS = 1571, + PERFORM_CLIENT_SIDE_DEATH = 1572, + LEGO_CLUB_ACCESS_RESULT = 1573, + VEHICLE_GET_IS_REVERSING = 1574, + CHECK_CLAIM_CODE = 1575, + GET_HOLIDAY_EVENT = 1576, + SET_EMOTES_ENABLED = 1577, + GET_EMOTES_ENABLED = 1578, + FREEZE_ANIMATION = 1579, + LOCALIZED_ANNOUNCEMENT_SERVER_TO_SINGLE_CLIENT = 1580, + ANCHOR_FX_NODE = 1581, + WS_GET_FRIEND_LIST_MESSAGE = 1582, + WS_ADD_FRIEND_RESPONSE = 1583, + WS_REMOVE_FRIEND_REPSONSE = 1584, + WS_UPDATE_FRIEND_STATUS = 1585, + WS_UPDATE_FRIEND_NAME = 1586, + IS_BEST_FRIEND = 1587, + TEAM_NOTIFY_UPDATE_MISSION_TASK = 1588, + VEHICLE_ADD_SLIPPERY_ACTION = 1589, + VEHICLE_REMOVE_SLIPPERY_ACTION = 1590, + SET_RESURRECT_RESTORE_VALUES = 1591, + GET_MASS = 1592, + SET_PROPERTY_MODERATION_STATUS = 1593, + UPDATE_PROPERTY_MODEL_DEFAULTS = 1594, + UPDATE_PROPERTYMODEL_COUNT = 1595, + GET_PROPERTY_MODEL_COUNT = 1596, + IS_PLAYER_LOADED = 1597, + ATTACH_RENDER_EFFECT_FROM_LUA = 1598, + DETACH_RENDER_EFFECT_FROM_LUA = 1599, + TEAM_IS_LOCAL = 1600, + CREATE_CAMERA_PARTICLES = 1602, + SET_SMASHABLE_GRAVITY_FACTOR = 1603, + VEHICLE_SET_SURFACE_TYPE_OVERRIDE = 1604, + VEHICLE_NOTIFY_HIT_IMAGINATION = 1605, + VEHICLE_NOTIFY_HIT_IMAGINATION_SERVER = 1606, + GET_SPAWNED_OBJECT_SPAWNER_INFO = 1607, + SAVE_PROPERTY = 1608, + SET_PROPERTY_DIRTY = 1609, + GET_PROPERTY_DIRTY = 1610, + GET_MODEL_LIST_FROM_PLAQUE = 1611, + GET_ORIGINAL_POSITION_AND_ROTATION = 1612, + VEHICLE_SET_MASS_FOR_COLLISION = 1613, + GET_INVENTORY_GROUP_COUNT = 1614, + GET_LATEST_CHAT_CHANNEL_USED = 1615, + SET_SUGGEST_LIST_LANGUAGE = 1616, + VEHICLE_STOP_BOOST = 1617, + START_CELEBRATION_EFFECT = 1618, + LOCK_PLAYER = 1619, + VEHICLE_IS_INPUT_LOCKED = 1620, + GET_MULTI_NODE = 1621, + RENEW_PROPERTY = 1622, + RENEW_PROPERTY_RESULT = 1623, + CHARGE_ACTIVITY_COST = 1624, + CAN_RECEIVE_LOOT = 1625, + JOIN_PLAYER_FACTION = 1626, + SET_PROXIMITY_UPDATE_RATE = 1627, + BBB_MODELS_TO_SAVE = 1628, + BELONGS_TO_FACTION = 1629, + MODIFY_FACTION = 1630, + FACTION_UPDATE = 1631, + CELEBRATION_COMPLETED = 1632, + PLAY_PRIMARY_MODULE_SOUNDS = 1633, + STOP_PRIMARY_MODULE_SOUNDS = 1634, + REQUEST_TEAM_PLAYER_UI_UPDATE = 1635, + SET_LOCAL_TEAM = 1636, + TEAM_GET_WORLD_MEMBERS_IN_RADIUS = 1637, + GET_PARENTAL_LEVEL = 1638, + GET_OBJECTS_MESSAGE_HANDLERS = 1639, + PROPERTY_FEATURED = 1640, + PROPERTY_NOTIFY_MODEL_SPAWNED = 1641, + SERVER_DONE_LOADING_ALL_OBJECTS = 1642, + GET_DONATION_TOTAL = 1643, + UPDATE_DONATION_VALUES = 1644, + DELAYED_DELETE_DROP_EFFECT_BRICK = 1645, + SET_CAMERA_UNLOCK_ROTATION_STATE = 1646, + ADD_BUFF = 1647, + REMOVE_BUFF = 1648, + CHECK_FOR_BUFF = 1649, + TEAM_MEMBERS_DISOWNS_LOOT = 1650, + GET_WHEEL_TEMPLATE = 1651, + ADD_SKILL_IN_PROGRESS = 1652, + REMOVE_SKILL_IN_PROGRESS = 1653, + SET_OVERHEAD_ICON_OFFSET = 1654, + SET_BILLBOARD_OFFSET = 1655, + SET_CHAT_BUBBLE_OFFSET = 1656, + SET_NO_TEAM_INVITES = 1657, + RESET_MODEL_TO_DEFAULTS = 1658, + IS_PROPERTY_IN_EDIT_MODE = 1659, + GET_OBJECTS_IN_PHYSICS_BOUNDS = 1660, + ENABLE_LU_REMOTE = 1661, + SET_IS_USING_FREE_TRIAL = 1662, + GET_IS_USING_FREE_TRIAL = 1663, + GET_ACCOUNT_FREE_TRIAL_MODE = 1664, + TOGGLE_INVENTORY_ITEM_LOCK = 1665, + REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1666, + RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1667, + REMOVE_SUB_COMPONENT = 1668, + TEAM_GET_LOOT_MEMBERS = 1669, + GET_FACTION_TOKEN_TYPE = 1670, + GET_SUBSCRIPTION_PRICING = 1671, + INFORM_AFK = 1672, + OVERHEAD_INDICATOR_CREATED = 1673, + SET_OVERHEAD_INDICATOR_GRID_LOCATION = 1674, + PLAYSTREAM_LOAD_PENDING = 1675, + PLAYER_SET_CAMERA_CYCLING_MODE = 1676, + PLAYER_GET_CAMERA_CYCLING_MODE = 1677, + FORCE_CAMERA_TARGET_CYCLE = 1678, + GET_OBJECT_CONFIG_DATA = 1679, + GET_OBJECT_CONFIG_DATA_NON_CONST = 1680, + SCOPE_CHANGED = 1681, + SET_ALLOW_JUMP_WITHOUT_SUPPORT = 1682, + GET_ALLOW_JUMP_WITHOUT_SUPPORT = 1683, + SET_JUMP_HEIGHT_SCALE = 1684, + GET_JUMP_HEIGHT_SCALE = 1685, + SET_VELOCITY_RESISTANCE = 1686, + GET_VELOCITY_RESISTANCE = 1687, + GATE_RUSH_VEHICLE_HIT_GATE = 1688, + GATE_RUSH_PLAYER_COLLECTED_GATE = 1689, + GATE_RUSH_ADD_GATE = 1690, + GATE_RUSH_REMOVE_GATE = 1691, + NOTIFY_VEHICLE_UPDATED = 1692, + VEHICLE_NOTIFY_HIT_WEAPON_POWERUP = 1693, + VEHICLE_NOTIFY_HIT_WEAPON_POWERUP_SERVER = 1694, + LOCAL_PLAYER_TARGETED = 1696, + SKILL_COUNT_CHANGED = 1697, + DO_YAW_ROTATION = 1698, + DO_PITCH_ROTATION = 1699, + DO_ROLL_ROTATION = 1700, + GET_CURRENT_LOOT_MATRIX = 1701, + SEND_MULTI_MISSION_OFFER_UPDATE_I_DS = 1702, + SET_AIR_SPEED_VALUES = 1703, + USE_LAUNCHER = 1704, + START_LAUNCHER = 1705, + STOP_LAUNCHER = 1706, + CAN_USE_JET_PACK = 1707, + JET_PACK_STATE_CHANGED = 1708, + TURN_OFF_JET_PACK = 1709, + ADD_PLAYER_JET_PACK_PAD = 1710, + SET_JET_PACK_WARNING = 1711, + JET_PACK_DISABLED = 1712, + JET_PACK_PAD_ENTERED = 1713, + UPDATE_RENDER_POSSESSION_FLAG = 1714, + POSSESSABLE_GET_ATTACH_OFFSET = 1715, + ATTEMPT_TO_CRAFT_ITEM = 1718, + CRAFT_ATTEMPT_RESPONSE = 1719, + SET_C_SCORE = 1720, + FILL_IN_RENDERER = 1721, + TOGGLE_CRAFTING_WINDOW = 1722, + REMOVE_TEAM_BUFFS = 1724, + REQUEST_FREE_TRIAL_STATUS_REFRESH = 1725, + REMOVE_BUFFS_APPLIED_BY_OBJECT = 1726, + SET_MOUNT_INVENTORY_ID = 1727, + GET_MOUNT_INVENTORY_ID = 1728, + GET_BUILD_CINEMATIC_TIME_REMAINING = 1730, + JET_PACK_FLYING = 1731, + NOTIFY_SERVER_LEVEL_PROCESSING_COMPLETE = 1734, + NOTIFY_LEVEL_REWARDS = 1735, + CHARACTER_VERSION_CHANGED = 1736, + SET_FREE_TRIAL_RENAME_AVAILABLE = 1737, + SET_PROJECTILE_LAUNCHER_PARAMS = 1738, + RACE_PRECOUNTDOWN_DONE = 1739, + CHECK_INVITE_SPAMMING = 1740, + GET_RESPAWN_VOLUME_INFO = 1741, + INVITE_ACCEPTED = 1742, + TELEPORT_TO_NEAREST_RESPAWN = 1743, + SET_SKILL_CANCEL_ON_MOVE = 1744, + CANCEL_MOVE_SKILL = 1745, + SERVER_CANCEL_MOVE_SKILL = 1746, + CLIENT_CANCEL_MOVE_SKILL = 1747, + END_LAUNCH_SEQUENCE = 1748, + CANCEL_QUEUE = 1749, + UPDATE_PROJECTILE_LAUNCHER_ROTATION = 1750, + GET_CHARACTER_VERSION_INFO = 1751, + GET_CON_INFO = 1753, + GET_SKILLS_FOR_LOT = 1755, + DISMOUNT_COMPLETE = 1756, + MOUNT_FAILURE_RESPONSE = 1757, + CLEAR_BILLBOARD_OFFSET = 1758, + GET_INVENTORY_ITEM_ANIMATION_FLAG = 1759, + SET_JET_PACK_ALLOWED = 1760, + GET_BUILD_TIME_DETAILS = 1761, + USE_SKILL_SET = 1762, + SET_SKILL_SET_POSSESSOR = 1763, + POPULATE_ACTION_BAR = 1764, + GET_COMPONENT_TEMPLATE_ID = 1765, + GET_POSSESSABLE_SKILL_SET = 1766, + MARK_INVENTORY_ITEM_AS_ACTIVE = 1767, + UPDATE_FORGED_ITEM = 1768, + CAN_ITEMS_BE_REFORGED = 1769, + NOTIFY_CLIENT_RAIL_START_FAILED = 1771, + GET_IS_ON_RAIL = 1772 }; #endif //!__EGAMEMESSAGETYPE__H__ diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 83005b6f..ba063d2d 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -73,11 +73,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System break; } - case eGameMessageType::EQUIP_ITEM: + case eGameMessageType::EQUIP_INVENTORY: GameMessages::HandleEquipItem(inStream, entity); break; - case eGameMessageType::UN_EQUIP_ITEM: + case eGameMessageType::UN_EQUIP_INVENTORY: GameMessages::HandleUnequipItem(inStream, entity); break; @@ -252,7 +252,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System }*/ break; } - case eGameMessageType::HANDLE_HOT_PROPERTY_DATA: { + case eGameMessageType::GET_HOT_PROPERTY_DATA: { GameMessages::HandleGetHotPropertyData(inStream, entity, sysAddr); break; } @@ -547,7 +547,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System GameMessages::HandleBBBSaveRequest(inStream, entity, sysAddr); break; - case eGameMessageType::CONTROL_BEHAVIOR: + case eGameMessageType::CONTROL_BEHAVIORS: GameMessages::HandleControlBehaviors(inStream, entity, sysAddr); break; @@ -596,11 +596,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System GameMessages::HandleRequestDie(inStream, entity, sysAddr); break; - case eGameMessageType::VEHICLE_NOTIFY_SERVER_ADD_PASSIVE_BOOST_ACTION: + case eGameMessageType::NOTIFY_SERVER_VEHICLE_ADD_PASSIVE_BOOST_ACTION: GameMessages::HandleVehicleNotifyServerAddPassiveBoostAction(inStream, entity, sysAddr); break; - case eGameMessageType::VEHICLE_NOTIFY_SERVER_REMOVE_PASSIVE_BOOST_ACTION: + case eGameMessageType::NOTIFY_SERVER_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION: GameMessages::HandleVehicleNotifyServerRemovePassiveBoostAction(inStream, entity, sysAddr); break; @@ -668,7 +668,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case eGameMessageType::DISMOUNT_COMPLETE: GameMessages::HandleDismountComplete(inStream, entity, sysAddr); break; - case eGameMessageType::DEACTIVATE_BUBBLE_BUFF: + case eGameMessageType::DECTIVATE_BUBBLE_BUFF: GameMessages::HandleDeactivateBubbleBuff(inStream, entity); break; case eGameMessageType::ACTIVATE_BUBBLE_BUFF: diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c3358625..e5567cfa 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -974,7 +974,7 @@ void GameMessages::SendStop2DAmbientSound(Entity* entity, bool force, std::strin CMSGHEADER; bitStream.Write(entity->GetObjectID()); - bitStream.Write((uint16_t)eGameMessageType::PLAY2_DAMBIENT_SOUND); + bitStream.Write((uint16_t)eGameMessageType::STOP2_D_AMBIENT_SOUND); uint32_t audioGUIDSize = audioGUID.size(); @@ -997,7 +997,7 @@ void GameMessages::SendPlay2DAmbientSound(Entity* entity, std::string audioGUID, CMSGHEADER; bitStream.Write(entity->GetObjectID()); - bitStream.Write((uint16_t)eGameMessageType::PLAY2_DAMBIENT_SOUND); + bitStream.Write((uint16_t)eGameMessageType::PLAY2_D_AMBIENT_SOUND); uint32_t audioGUIDSize = audioGUID.size(); @@ -1016,7 +1016,7 @@ void GameMessages::SendSetNetworkScriptVar(Entity* entity, const SystemAddress& CMSGHEADER; bitStream.Write(entity->GetObjectID()); - bitStream.Write((uint16_t)eGameMessageType::SET_NETWORK_SCRIPT_VAR); + bitStream.Write((uint16_t)eGameMessageType::SCRIPT_NETWORK_VAR_UPDATE); // FIXME: this is a bad place to need to do a conversion because we have no clue whether data is utf8 or plain ascii // an this has performance implications @@ -2115,7 +2115,7 @@ void GameMessages::SendUGCEquipPreCreateBasedOnEditMode(LWOOBJID objectId, const CMSGHEADER; bitStream.Write(objectId); - bitStream.Write(eGameMessageType::HANDLE_UGC_EQUIP_PRE_CREATE_BASED_ON_EDIT_MODE); + bitStream.Write(eGameMessageType::HANDLE_UGC_POST_CREATE_BASED_ON_EDIT_MODE); bitStream.Write(modelCount); bitStream.Write(model); @@ -2129,7 +2129,7 @@ void GameMessages::SendUGCEquipPostDeleteBasedOnEditMode(LWOOBJID objectId, cons CMSGHEADER; bitStream.Write(objectId); - bitStream.Write(eGameMessageType::HANDLE_UGC_EQUIP_POST_DELETE_BASED_ON_EDIT_MODE); + bitStream.Write(eGameMessageType::HANDLE_UGC_POST_DELETE_BASED_ON_EDIT_MODE); bitStream.Write(inventoryItem); @@ -2458,7 +2458,7 @@ void GameMessages::SendUnSmash(Entity* entity, LWOOBJID builderID, float duratio CMSGHEADER; bitStream.Write(entity->GetObjectID()); - bitStream.Write(eGameMessageType::UNSMASH); + bitStream.Write(eGameMessageType::UN_SMASH); bitStream.Write(builderID != LWOOBJID_EMPTY); if (builderID != LWOOBJID_EMPTY) bitStream.Write(builderID); @@ -3461,7 +3461,7 @@ void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, const st CMSGHEADER; bitStream.Write(objectId); - bitStream.Write(eGameMessageType::NOTIFY_PET_TAMING_PUZZLE_SELECTED); + bitStream.Write(eGameMessageType::NOTIFY_TAMING_PUZZLE_SELECTED); bitStream.Write(static_cast(bricks.size())); for (const auto& brick : bricks) { diff --git a/tests/dGameTests/dGameMessagesTests/CMakeLists.txt b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt index 54c43777..e1c4884c 100644 --- a/tests/dGameTests/dGameMessagesTests/CMakeLists.txt +++ b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt @@ -1,5 +1,6 @@ SET(DGAMEMESSAGES_TESTS - "GameMessageTests.cpp") + "GameMessageTests.cpp" + "LegacyGameMessageTests.cpp") # Get the folder name and prepend it to the files above get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME) diff --git a/tests/dGameTests/dGameMessagesTests/LegacyGameMessageTests.cpp b/tests/dGameTests/dGameMessagesTests/LegacyGameMessageTests.cpp new file mode 100644 index 00000000..0226b0ad --- /dev/null +++ b/tests/dGameTests/dGameMessagesTests/LegacyGameMessageTests.cpp @@ -0,0 +1,298 @@ +#include +#include "eGameMessageType.h" + +TEST(LegacyGameMessageTests, AssertLegacyGmValues) { + EXPECT_EQ(eGameMessageType::TELEPORT, (eGameMessageType)19); + EXPECT_EQ(eGameMessageType::SET_PLAYER_CONTROL_SCHEME, (eGameMessageType)26); + EXPECT_EQ(eGameMessageType::DROP_CLIENT_LOOT, (eGameMessageType)30); + EXPECT_EQ(eGameMessageType::DIE, (eGameMessageType)37); + EXPECT_EQ(eGameMessageType::REQUEST_DIE, (eGameMessageType)38); + EXPECT_EQ(eGameMessageType::PLAY_EMOTE, (eGameMessageType)41); + EXPECT_EQ(eGameMessageType::PLAY_ANIMATION, (eGameMessageType)43); + EXPECT_EQ(eGameMessageType::CONTROL_BEHAVIORS, (eGameMessageType)48); + EXPECT_EQ(eGameMessageType::SET_NAME, (eGameMessageType)72); + EXPECT_EQ(eGameMessageType::ECHO_START_SKILL, (eGameMessageType)118); + EXPECT_EQ(eGameMessageType::START_SKILL, (eGameMessageType)119); + EXPECT_EQ(eGameMessageType::VERIFY_ACK, (eGameMessageType)121); + EXPECT_EQ(eGameMessageType::ADD_SKILL, (eGameMessageType)127); + EXPECT_EQ(eGameMessageType::REMOVE_SKILL, (eGameMessageType)128); + EXPECT_EQ(eGameMessageType::SET_CURRENCY, (eGameMessageType)133); + EXPECT_EQ(eGameMessageType::PICKUP_CURRENCY, (eGameMessageType)137); + EXPECT_EQ(eGameMessageType::PICKUP_ITEM, (eGameMessageType)139); + EXPECT_EQ(eGameMessageType::TEAM_PICKUP_ITEM, (eGameMessageType)140); + EXPECT_EQ(eGameMessageType::PLAY_FX_EFFECT, (eGameMessageType)154); + EXPECT_EQ(eGameMessageType::STOP_FX_EFFECT, (eGameMessageType)155); + EXPECT_EQ(eGameMessageType::REQUEST_RESURRECT, (eGameMessageType)159); + EXPECT_EQ(eGameMessageType::RESURRECT, (eGameMessageType)160); + EXPECT_EQ(eGameMessageType::PUSH_EQUIPPED_ITEMS_STATE, (eGameMessageType)191); + EXPECT_EQ(eGameMessageType::POP_EQUIPPED_ITEMS_STATE, (eGameMessageType)192); + EXPECT_EQ(eGameMessageType::SET_GM_LEVEL, (eGameMessageType)193); + EXPECT_EQ(eGameMessageType::SET_STUNNED, (eGameMessageType)198); + EXPECT_EQ(eGameMessageType::SET_STUN_IMMUNITY, (eGameMessageType)200); + EXPECT_EQ(eGameMessageType::KNOCKBACK, (eGameMessageType)202); + EXPECT_EQ(eGameMessageType::REBUILD_CANCEL, (eGameMessageType)209); + EXPECT_EQ(eGameMessageType::ENABLE_REBUILD, (eGameMessageType)213); + EXPECT_EQ(eGameMessageType::MOVE_ITEM_IN_INVENTORY, (eGameMessageType)224); + EXPECT_EQ(eGameMessageType::ADD_ITEM_TO_INVENTORY_CLIENT_SYNC, (eGameMessageType)227); + EXPECT_EQ(eGameMessageType::REMOVE_ITEM_FROM_INVENTORY, (eGameMessageType)230); + EXPECT_EQ(eGameMessageType::EQUIP_INVENTORY, (eGameMessageType)231); + EXPECT_EQ(eGameMessageType::UN_EQUIP_INVENTORY, (eGameMessageType)233); + EXPECT_EQ(eGameMessageType::OFFER_MISSION, (eGameMessageType)248); + EXPECT_EQ(eGameMessageType::RESPOND_TO_MISSION, (eGameMessageType)249); + EXPECT_EQ(eGameMessageType::NOTIFY_MISSION, (eGameMessageType)254); + EXPECT_EQ(eGameMessageType::NOTIFY_MISSION_TASK, (eGameMessageType)255); + EXPECT_EQ(eGameMessageType::REBUILD_NOTIFY_STATE, (eGameMessageType)336); + EXPECT_EQ(eGameMessageType::TERMINATE_INTERACTION, (eGameMessageType)357); + EXPECT_EQ(eGameMessageType::SERVER_TERMINATE_INTERACTION, (eGameMessageType)358); + EXPECT_EQ(eGameMessageType::REQUEST_USE, (eGameMessageType)364); + EXPECT_EQ(eGameMessageType::VENDOR_OPEN_WINDOW, (eGameMessageType)369); + EXPECT_EQ(eGameMessageType::BUY_FROM_VENDOR, (eGameMessageType)373); + EXPECT_EQ(eGameMessageType::SELL_TO_VENDOR, (eGameMessageType)374); + EXPECT_EQ(eGameMessageType::TEAM_SET_OFF_WORLD_FLAG, (eGameMessageType)383); + EXPECT_EQ(eGameMessageType::SET_INVENTORY_SIZE, (eGameMessageType)389); + EXPECT_EQ(eGameMessageType::ACKNOWLEDGE_POSSESSION, (eGameMessageType)391); + EXPECT_EQ(eGameMessageType::SET_SHOOTING_GALLERY_PARAMS, (eGameMessageType)400); + EXPECT_EQ(eGameMessageType::REQUEST_ACTIVITY_START_STOP, (eGameMessageType)402); + EXPECT_EQ(eGameMessageType::REQUEST_ACTIVITY_ENTER, (eGameMessageType)403); + EXPECT_EQ(eGameMessageType::REQUEST_ACTIVITY_EXIT, (eGameMessageType)404); + EXPECT_EQ(eGameMessageType::ACTIVITY_ENTER, (eGameMessageType)405); + EXPECT_EQ(eGameMessageType::ACTIVITY_EXIT, (eGameMessageType)406); + EXPECT_EQ(eGameMessageType::ACTIVITY_START, (eGameMessageType)407); + EXPECT_EQ(eGameMessageType::ACTIVITY_STOP, (eGameMessageType)408); + EXPECT_EQ(eGameMessageType::SHOOTING_GALLERY_CLIENT_AIM_UPDATE, (eGameMessageType)409); + EXPECT_EQ(eGameMessageType::SHOOTING_GALLERY_FIRE, (eGameMessageType)411); + EXPECT_EQ(eGameMessageType::REQUEST_VENDOR_STATUS_UPDATE, (eGameMessageType)416); + EXPECT_EQ(eGameMessageType::VENDOR_STATUS_UPDATE, (eGameMessageType)417); + EXPECT_EQ(eGameMessageType::NOTIFY_CLIENT_SHOOTING_GALLERY_SCORE, (eGameMessageType)425); + EXPECT_EQ(eGameMessageType::CONSUME_CLIENT_ITEM, (eGameMessageType)427); + EXPECT_EQ(eGameMessageType::CLIENT_ITEM_CONSUMED, (eGameMessageType)428); + EXPECT_EQ(eGameMessageType::UPDATE_SHOOTING_GALLERY_ROTATION, (eGameMessageType)448); + EXPECT_EQ(eGameMessageType::SET_FLAG, (eGameMessageType)471); + EXPECT_EQ(eGameMessageType::NOTIFY_CLIENT_FLAG_CHANGE, (eGameMessageType)472); + EXPECT_EQ(eGameMessageType::VENDOR_TRANSACTION_RESULT, (eGameMessageType)476); + EXPECT_EQ(eGameMessageType::HAS_BEEN_COLLECTED, (eGameMessageType)486); + EXPECT_EQ(eGameMessageType::DISPLAY_CHAT_BUBBLE, (eGameMessageType)495); + EXPECT_EQ(eGameMessageType::SPAWN_PET, (eGameMessageType)498); + EXPECT_EQ(eGameMessageType::DESPAWN_PET, (eGameMessageType)499); + EXPECT_EQ(eGameMessageType::PLAYER_LOADED, (eGameMessageType)505); + EXPECT_EQ(eGameMessageType::PLAYER_READY, (eGameMessageType)509); + EXPECT_EQ(eGameMessageType::REQUEST_LINKED_MISSION, (eGameMessageType)515); + EXPECT_EQ(eGameMessageType::INVALID_ZONE_TRANSFER_LIST, (eGameMessageType)519); + EXPECT_EQ(eGameMessageType::MISSION_DIALOGUE_OK, (eGameMessageType)520); + EXPECT_EQ(eGameMessageType::DISPLAY_MESSAGE_BOX, (eGameMessageType)529); + EXPECT_EQ(eGameMessageType::MESSAGE_BOX_RESPOND, (eGameMessageType)530); + EXPECT_EQ(eGameMessageType::CHOICE_BOX_RESPOND, (eGameMessageType)531); + EXPECT_EQ(eGameMessageType::SMASH, (eGameMessageType)537); + EXPECT_EQ(eGameMessageType::UN_SMASH, (eGameMessageType)538); + EXPECT_EQ(eGameMessageType::PLACE_MODEL_RESPONSE, (eGameMessageType)547); + EXPECT_EQ(eGameMessageType::SET_SHOOTING_GALLERY_RETICULE_EFFECT, (eGameMessageType)546); + EXPECT_EQ(eGameMessageType::SET_JET_PACK_MODE, (eGameMessageType)561); + EXPECT_EQ(eGameMessageType::REGISTER_PET_ID, (eGameMessageType)565); + EXPECT_EQ(eGameMessageType::REGISTER_PET_DBID, (eGameMessageType)566); + EXPECT_EQ(eGameMessageType::SHOW_ACTIVITY_COUNTDOWN, (eGameMessageType)568); + EXPECT_EQ(eGameMessageType::START_ACTIVITY_TIME, (eGameMessageType)576); + EXPECT_EQ(eGameMessageType::ACTIVITY_PAUSE, (eGameMessageType)602); + EXPECT_EQ(eGameMessageType::USE_NON_EQUIPMENT_ITEM, (eGameMessageType)603); + EXPECT_EQ(eGameMessageType::USE_ITEM_RESULT, (eGameMessageType)607); + EXPECT_EQ(eGameMessageType::COMMAND_PET, (eGameMessageType)640); + EXPECT_EQ(eGameMessageType::PET_RESPONSE, (eGameMessageType)641); + EXPECT_EQ(eGameMessageType::REQUEST_ACTIVITY_SUMMARY_LEADERBOARD_DATA, (eGameMessageType)648); + EXPECT_EQ(eGameMessageType::SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA, (eGameMessageType)649); + EXPECT_EQ(eGameMessageType::NOTIFY_OBJECT, (eGameMessageType)656); + EXPECT_EQ(eGameMessageType::CLIENT_NOTIFY_PET, (eGameMessageType)659); + EXPECT_EQ(eGameMessageType::NOTIFY_PET, (eGameMessageType)660); + EXPECT_EQ(eGameMessageType::NOTIFY_PET_TAMING_MINIGAME, (eGameMessageType)661); + EXPECT_EQ(eGameMessageType::START_SERVER_PET_MINIGAME_TIMER, (eGameMessageType)662); + EXPECT_EQ(eGameMessageType::CLIENT_EXIT_TAMING_MINIGAME, (eGameMessageType)663); + EXPECT_EQ(eGameMessageType::PET_NAME_CHANGED, (eGameMessageType)686); + EXPECT_EQ(eGameMessageType::PET_TAMING_MINIGAME_RESULT, (eGameMessageType)667); + EXPECT_EQ(eGameMessageType::PET_TAMING_TRY_BUILD_RESULT, (eGameMessageType)668); + EXPECT_EQ(eGameMessageType::NOTIFY_TAMING_BUILD_SUCCESS, (eGameMessageType)673); + EXPECT_EQ(eGameMessageType::NOTIFY_TAMING_MODEL_LOADED_ON_SERVER, (eGameMessageType)674); + EXPECT_EQ(eGameMessageType::ACTIVATE_BUBBLE_BUFF, (eGameMessageType)678); + EXPECT_EQ(eGameMessageType::DECTIVATE_BUBBLE_BUFF, (eGameMessageType)679); + EXPECT_EQ(eGameMessageType::ADD_PET_TO_PLAYER, (eGameMessageType)681); + EXPECT_EQ(eGameMessageType::REQUEST_SET_PET_NAME, (eGameMessageType)683); + EXPECT_EQ(eGameMessageType::SET_PET_NAME, (eGameMessageType)684); + EXPECT_EQ(eGameMessageType::NOTIFY_TAMING_PUZZLE_SELECTED, (eGameMessageType)675); + EXPECT_EQ(eGameMessageType::SHOW_PET_ACTION_BUTTON, (eGameMessageType)692); + EXPECT_EQ(eGameMessageType::SET_EMOTE_LOCK_STATE, (eGameMessageType)693); + EXPECT_EQ(eGameMessageType::USE_ITEM_REQUIREMENTS_RESPONSE, (eGameMessageType)703); + EXPECT_EQ(eGameMessageType::PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT, (eGameMessageType)713); + EXPECT_EQ(eGameMessageType::DOWNLOAD_PROPERTY_DATA, (eGameMessageType)716); + EXPECT_EQ(eGameMessageType::QUERY_PROPERTY_DATA, (eGameMessageType)717); + EXPECT_EQ(eGameMessageType::PROPERTY_EDITOR_BEGIN, (eGameMessageType)724); + EXPECT_EQ(eGameMessageType::PROPERTY_EDITOR_END, (eGameMessageType)725); + EXPECT_EQ(eGameMessageType::IS_MINIFIG_IN_A_BUBBLE, (eGameMessageType)729); + EXPECT_EQ(eGameMessageType::START_PATHING, (eGameMessageType)733); + EXPECT_EQ(eGameMessageType::ACTIVATE_BUBBLE_BUFF_FROM_SERVER, (eGameMessageType)734); + EXPECT_EQ(eGameMessageType::DEACTIVATE_BUBBLE_BUFF_FROM_SERVER, (eGameMessageType)735); + EXPECT_EQ(eGameMessageType::NOTIFY_CLIENT_ZONE_OBJECT, (eGameMessageType)737); + EXPECT_EQ(eGameMessageType::UPDATE_REPUTATION, (eGameMessageType)746); + EXPECT_EQ(eGameMessageType::PROPERTY_RENTAL_RESPONSE, (eGameMessageType)750); + EXPECT_EQ(eGameMessageType::REQUEST_PLATFORM_RESYNC, (eGameMessageType)760); + EXPECT_EQ(eGameMessageType::PLATFORM_RESYNC, (eGameMessageType)761); + EXPECT_EQ(eGameMessageType::PLAY_CINEMATIC, (eGameMessageType)762); + EXPECT_EQ(eGameMessageType::END_CINEMATIC, (eGameMessageType)763); + EXPECT_EQ(eGameMessageType::CINEMATIC_UPDATE, (eGameMessageType)764); + EXPECT_EQ(eGameMessageType::TOGGLE_GHOST_REFERENCE_OVERRIDE, (eGameMessageType)767); + EXPECT_EQ(eGameMessageType::SET_GHOST_REFERENCE_POSITION, (eGameMessageType)768); + EXPECT_EQ(eGameMessageType::FIRE_EVENT_SERVER_SIDE, (eGameMessageType)770); + EXPECT_EQ(eGameMessageType::SCRIPT_NETWORK_VAR_UPDATE, (eGameMessageType)781); + EXPECT_EQ(eGameMessageType::UPDATE_MODEL_FROM_CLIENT, (eGameMessageType)793); + EXPECT_EQ(eGameMessageType::DELETE_MODEL_FROM_CLIENT, (eGameMessageType)794); + EXPECT_EQ(eGameMessageType::PLAY_ND_AUDIO_EMITTER, (eGameMessageType)821); + EXPECT_EQ(eGameMessageType::PLAY2_D_AMBIENT_SOUND, (eGameMessageType)831); + EXPECT_EQ(eGameMessageType::ENTER_PROPERTY1, (eGameMessageType)840); + EXPECT_EQ(eGameMessageType::ENTER_PROPERTY2, (eGameMessageType)841); + EXPECT_EQ(eGameMessageType::PROPERTY_ENTRANCE_SYNC, (eGameMessageType)842); + EXPECT_EQ(eGameMessageType::PROPERTY_SELECT_QUERY, (eGameMessageType)845); + EXPECT_EQ(eGameMessageType::PARSE_CHAT_MESSAGE, (eGameMessageType)850); + EXPECT_EQ(eGameMessageType::BROADCAST_TEXT_TO_CHATBOX, (eGameMessageType)858); + EXPECT_EQ(eGameMessageType::OPEN_PROPERTY_MANAGEMENT, (eGameMessageType)860); + EXPECT_EQ(eGameMessageType::OPEN_PROPERTY_VENDOR, (eGameMessageType)861); + EXPECT_EQ(eGameMessageType::UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK, (eGameMessageType)863); + EXPECT_EQ(eGameMessageType::CLIENT_TRADE_REQUEST, (eGameMessageType)868); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_REQUEST, (eGameMessageType)869); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_INVITE, (eGameMessageType)870); + EXPECT_EQ(eGameMessageType::CLIENT_TRADE_REPLY, (eGameMessageType)871); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_REPLY, (eGameMessageType)872); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_INITIAL_REPLY, (eGameMessageType)873); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_FINAL_REPLY, (eGameMessageType)874); + EXPECT_EQ(eGameMessageType::CLIENT_TRADE_UPDATE, (eGameMessageType)875); + EXPECT_EQ(eGameMessageType::SERVER_SIDE_TRADE_UPDATE, (eGameMessageType)876); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_UPDATE, (eGameMessageType)877); + EXPECT_EQ(eGameMessageType::CLIENT_TRADE_CANCEL, (eGameMessageType)878); + EXPECT_EQ(eGameMessageType::CLIENT_SIDE_TRADE_CANCEL, (eGameMessageType)879); + EXPECT_EQ(eGameMessageType::CLIENT_TRADE_ACCEPT, (eGameMessageType)880); + EXPECT_EQ(eGameMessageType::SERVER_SIDE_TRADE_ACCEPT, (eGameMessageType)881); + EXPECT_EQ(eGameMessageType::SERVER_SIDE_TRADE_CANCEL, (eGameMessageType)882); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_CANCEL, (eGameMessageType)883); + EXPECT_EQ(eGameMessageType::SERVER_TRADE_ACCEPT, (eGameMessageType)884); + EXPECT_EQ(eGameMessageType::READY_FOR_UPDATES, (eGameMessageType)888); + EXPECT_EQ(eGameMessageType::ORIENT_TO_OBJECT, (eGameMessageType)905); + EXPECT_EQ(eGameMessageType::ORIENT_TO_POSITION, (eGameMessageType)906); + EXPECT_EQ(eGameMessageType::ORIENT_TO_ANGLE, (eGameMessageType)907); + EXPECT_EQ(eGameMessageType::BOUNCER_ACTIVE_STATUS, (eGameMessageType)942); + EXPECT_EQ(eGameMessageType::UN_USE_BBB_MODEL, (eGameMessageType)999); + EXPECT_EQ(eGameMessageType::BBB_LOAD_ITEM_REQUEST, (eGameMessageType)1000); + EXPECT_EQ(eGameMessageType::BBB_SAVE_REQUEST, (eGameMessageType)1001); + EXPECT_EQ(eGameMessageType::BBB_SAVE_RESPONSE, (eGameMessageType)1005); + EXPECT_EQ(eGameMessageType::NOTIFY_CLIENT_OBJECT, (eGameMessageType)1042); + EXPECT_EQ(eGameMessageType::DISPLAY_ZONE_SUMMARY, (eGameMessageType)1043); + EXPECT_EQ(eGameMessageType::ZONE_SUMMARY_DISMISSED, (eGameMessageType)1044); + EXPECT_EQ(eGameMessageType::ACTIVITY_STATE_CHANGE_REQUEST, (eGameMessageType)1053); + EXPECT_EQ(eGameMessageType::MODIFY_PLAYER_ZONE_STATISTIC, (eGameMessageType)1046); + EXPECT_EQ(eGameMessageType::START_BUILDING_WITH_ITEM, (eGameMessageType)1057); + EXPECT_EQ(eGameMessageType::START_ARRANGING_WITH_ITEM, (eGameMessageType)1061); + EXPECT_EQ(eGameMessageType::FINISH_ARRANGING_WITH_ITEM, (eGameMessageType)1062); + EXPECT_EQ(eGameMessageType::DONE_ARRANGING_WITH_ITEM, (eGameMessageType)1063); + EXPECT_EQ(eGameMessageType::SET_BUILD_MODE, (eGameMessageType)1068); + EXPECT_EQ(eGameMessageType::BUILD_MODE_SET, (eGameMessageType)1069); + EXPECT_EQ(eGameMessageType::SET_BUILD_MODE_CONFIRMED, (eGameMessageType)1073); + EXPECT_EQ(eGameMessageType::NOTIFY_CLIENT_FAILED_PRECONDITION, (eGameMessageType)1081); + EXPECT_EQ(eGameMessageType::MOVE_ITEM_BETWEEN_INVENTORY_TYPES, (eGameMessageType)1093); + EXPECT_EQ(eGameMessageType::MODULAR_BUILD_BEGIN, (eGameMessageType)1094); + EXPECT_EQ(eGameMessageType::MODULAR_BUILD_END, (eGameMessageType)1095); + EXPECT_EQ(eGameMessageType::MODULAR_BUILD_MOVE_AND_EQUIP, (eGameMessageType)1096); + EXPECT_EQ(eGameMessageType::MODULAR_BUILD_FINISH, (eGameMessageType)1097); + EXPECT_EQ(eGameMessageType::REPORT_BUG, (eGameMessageType)1198); + EXPECT_EQ(eGameMessageType::MISSION_DIALOGUE_CANCELLED, (eGameMessageType)1129); + EXPECT_EQ(eGameMessageType::ECHO_SYNC_SKILL, (eGameMessageType)1144); + EXPECT_EQ(eGameMessageType::SYNC_SKILL, (eGameMessageType)1145); + EXPECT_EQ(eGameMessageType::REQUEST_SERVER_PROJECTILE_IMPACT, (eGameMessageType)1148); + EXPECT_EQ(eGameMessageType::DO_CLIENT_PROJECTILE_IMPACT, (eGameMessageType)1151); + EXPECT_EQ(eGameMessageType::MODULAR_BUILD_CONVERT_MODEL, (eGameMessageType)1155); + EXPECT_EQ(eGameMessageType::SET_PLAYER_ALLOWED_RESPAWN, (eGameMessageType)1165); + EXPECT_EQ(eGameMessageType::UI_MESSAGE_SERVER_TO_SINGLE_CLIENT, (eGameMessageType)1184); + EXPECT_EQ(eGameMessageType::UI_MESSAGE_SERVER_TO_ALL_CLIENTS, (eGameMessageType)1185); + EXPECT_EQ(eGameMessageType::PET_TAMING_TRY_BUILD, (eGameMessageType)1197); + EXPECT_EQ(eGameMessageType::REQUEST_SMASH_PLAYER, (eGameMessageType)1202); + EXPECT_EQ(eGameMessageType::FIRE_EVENT_CLIENT_SIDE, (eGameMessageType)1213); + EXPECT_EQ(eGameMessageType::TOGGLE_GM_INVIS, (eGameMessageType)1218); + EXPECT_EQ(eGameMessageType::CHANGE_OBJECT_WORLD_STATE, (eGameMessageType)1223); + EXPECT_EQ(eGameMessageType::VEHICLE_LOCK_INPUT, (eGameMessageType)1230); + EXPECT_EQ(eGameMessageType::VEHICLE_UNLOCK_INPUT, (eGameMessageType)1231); + EXPECT_EQ(eGameMessageType::RACING_RESET_PLAYER_TO_LAST_RESET, (eGameMessageType)1252); + EXPECT_EQ(eGameMessageType::RACING_SERVER_SET_PLAYER_LAP_AND_PLANE, (eGameMessageType)1253); + EXPECT_EQ(eGameMessageType::RACING_SET_PLAYER_RESET_INFO, (eGameMessageType)1254); + EXPECT_EQ(eGameMessageType::RACING_PLAYER_INFO_RESET_FINISHED, (eGameMessageType)1255); + EXPECT_EQ(eGameMessageType::LOCK_NODE_ROTATION, (eGameMessageType)1260); + EXPECT_EQ(eGameMessageType::VEHICLE_SET_WHEEL_LOCK_STATE, (eGameMessageType)1273); + EXPECT_EQ(eGameMessageType::NOTIFY_VEHICLE_OF_RACING_OBJECT, (eGameMessageType)1276); + EXPECT_EQ(eGameMessageType::SET_NAME_BILLBOARD_STATE, (eGameMessageType)1284); + EXPECT_EQ(eGameMessageType::PLAYER_REACHED_RESPAWN_CHECKPOINT, (eGameMessageType)1296); + EXPECT_EQ(eGameMessageType::HANDLE_UGC_POST_DELETE_BASED_ON_EDIT_MODE, (eGameMessageType)1300); + EXPECT_EQ(eGameMessageType::HANDLE_UGC_POST_CREATE_BASED_ON_EDIT_MODE, (eGameMessageType)1301); + EXPECT_EQ(eGameMessageType::PROPERTY_CONTENTS_FROM_CLIENT, (eGameMessageType)1305); + EXPECT_EQ(eGameMessageType::GET_MODELS_ON_PROPERTY, (eGameMessageType)1306); + EXPECT_EQ(eGameMessageType::MATCH_REQUEST, (eGameMessageType)1308); + EXPECT_EQ(eGameMessageType::MATCH_RESPONSE, (eGameMessageType)1309); + EXPECT_EQ(eGameMessageType::MATCH_UPDATE, (eGameMessageType)1310); + EXPECT_EQ(eGameMessageType::MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT, (eGameMessageType)1131); + EXPECT_EQ(eGameMessageType::MODULE_ASSEMBLY_QUERY_DATA, (eGameMessageType)1132); + EXPECT_EQ(eGameMessageType::SHOW_BILLBOARD_INTERACT_ICON, (eGameMessageType)1337); + EXPECT_EQ(eGameMessageType::CHANGE_IDLE_FLAGS, (eGameMessageType)1338); + EXPECT_EQ(eGameMessageType::VEHICLE_ADD_PASSIVE_BOOST_ACTION, (eGameMessageType)1340); + EXPECT_EQ(eGameMessageType::VEHICLE_REMOVE_PASSIVE_BOOST_ACTION, (eGameMessageType)1341); + EXPECT_EQ(eGameMessageType::NOTIFY_SERVER_VEHICLE_ADD_PASSIVE_BOOST_ACTION, (eGameMessageType)1342); + EXPECT_EQ(eGameMessageType::NOTIFY_SERVER_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION, (eGameMessageType)1343); + EXPECT_EQ(eGameMessageType::VEHICLE_ADD_SLOWDOWN_ACTION, (eGameMessageType)1344); + EXPECT_EQ(eGameMessageType::VEHICLE_REMOVE_SLOWDOWN_ACTION, (eGameMessageType)1345); + EXPECT_EQ(eGameMessageType::NOTIFY_SERVER_VEHICLE_ADD_SLOWDOWN_ACTION, (eGameMessageType)1346); + EXPECT_EQ(eGameMessageType::NOTIFY_SERVER_VEHICLE_REMOVE_SLOWDOWN_ACTION, (eGameMessageType)1347); + EXPECT_EQ(eGameMessageType::BUYBACK_FROM_VENDOR, (eGameMessageType)1350); + EXPECT_EQ(eGameMessageType::SET_PROPERTY_ACCESS, (eGameMessageType)1366); + EXPECT_EQ(eGameMessageType::ZONE_PROPERTY_MODEL_PLACED, (eGameMessageType)1369); + EXPECT_EQ(eGameMessageType::ZONE_PROPERTY_MODEL_ROTATED, (eGameMessageType)1370); + EXPECT_EQ(eGameMessageType::ZONE_PROPERTY_MODEL_REMOVED_WHILE_EQUIPPED, (eGameMessageType)1371); + EXPECT_EQ(eGameMessageType::ZONE_PROPERTY_MODEL_EQUIPPED, (eGameMessageType)1372); + EXPECT_EQ(eGameMessageType::ZONE_PROPERTY_MODEL_PICKED_UP, (eGameMessageType)1373); + EXPECT_EQ(eGameMessageType::ZONE_PROPERTY_MODEL_REMOVED, (eGameMessageType)1374); + EXPECT_EQ(eGameMessageType::NOTIFY_RACING_CLIENT, (eGameMessageType)1390); + EXPECT_EQ(eGameMessageType::RACING_PLAYER_HACK_CAR, (eGameMessageType)1391); + EXPECT_EQ(eGameMessageType::RACING_PLAYER_LOADED, (eGameMessageType)1392); + EXPECT_EQ(eGameMessageType::RACING_CLIENT_READY, (eGameMessageType)1393); + EXPECT_EQ(eGameMessageType::UPDATE_CHAT_MODE, (eGameMessageType)1395); + EXPECT_EQ(eGameMessageType::VEHICLE_NOTIFY_FINISHED_RACE, (eGameMessageType)1396); + EXPECT_EQ(eGameMessageType::SET_CONSUMABLE_ITEM, (eGameMessageType)1409); + EXPECT_EQ(eGameMessageType::SET_STATUS_IMMUNITY, (eGameMessageType)1435); + EXPECT_EQ(eGameMessageType::SET_PET_NAME_MODERATED, (eGameMessageType)1448); + EXPECT_EQ(eGameMessageType::MODIFY_LEGO_SCORE, (eGameMessageType)1459); + EXPECT_EQ(eGameMessageType::RESTORE_TO_POST_LOAD_STATS, (eGameMessageType)1468); + EXPECT_EQ(eGameMessageType::SET_RAIL_MOVEMENT, (eGameMessageType)1471); + EXPECT_EQ(eGameMessageType::START_RAIL_MOVEMENT, (eGameMessageType)1472); + EXPECT_EQ(eGameMessageType::CANCEL_RAIL_MOVEMENT, (eGameMessageType)1474); + EXPECT_EQ(eGameMessageType::CLIENT_RAIL_MOVEMENT_READY, (eGameMessageType)1476); + EXPECT_EQ(eGameMessageType::PLAYER_RAIL_ARRIVED_NOTIFICATION, (eGameMessageType)1477); + EXPECT_EQ(eGameMessageType::UPDATE_PLAYER_STATISTIC, (eGameMessageType)1481); + EXPECT_EQ(eGameMessageType::MODULAR_ASSEMBLY_NIF_COMPLETED, (eGameMessageType)1498); + EXPECT_EQ(eGameMessageType::NOTIFY_NOT_ENOUGH_INV_SPACE, (eGameMessageType)1516); + EXPECT_EQ(eGameMessageType::TEAM_SET_LEADER, (eGameMessageType)1557); + EXPECT_EQ(eGameMessageType::TEAM_INVITE_CONFIRM, (eGameMessageType)1558); + EXPECT_EQ(eGameMessageType::TEAM_GET_STATUS_RESPONSE, (eGameMessageType)1559); + EXPECT_EQ(eGameMessageType::TEAM_ADD_PLAYER, (eGameMessageType)1562); + EXPECT_EQ(eGameMessageType::TEAM_REMOVE_PLAYER, (eGameMessageType)1563); + EXPECT_EQ(eGameMessageType::START_CELEBRATION_EFFECT, (eGameMessageType)1618); + EXPECT_EQ(eGameMessageType::ADD_BUFF, (eGameMessageType)1647); + EXPECT_EQ(eGameMessageType::SERVER_DONE_LOADING_ALL_OBJECTS, (eGameMessageType)1642); + EXPECT_EQ(eGameMessageType::PLACE_PROPERTY_MODEL, (eGameMessageType)1170); + EXPECT_EQ(eGameMessageType::VEHICLE_NOTIFY_HIT_IMAGINATION_SERVER, (eGameMessageType)1606); + EXPECT_EQ(eGameMessageType::ADD_RUN_SPEED_MODIFIER, (eGameMessageType)1505); + EXPECT_EQ(eGameMessageType::GET_HOT_PROPERTY_DATA, (eGameMessageType)1511); + EXPECT_EQ(eGameMessageType::SEND_HOT_PROPERTY_DATA, (eGameMessageType)1510); + EXPECT_EQ(eGameMessageType::REMOVE_RUN_SPEED_MODIFIER, (eGameMessageType)1506); + EXPECT_EQ(eGameMessageType::UPDATE_PROPERTY_PERFORMANCE_COST, (eGameMessageType)1547); + EXPECT_EQ(eGameMessageType::PROPERTY_ENTRANCE_BEGIN, (eGameMessageType)1553); + EXPECT_EQ(eGameMessageType::SET_RESURRECT_RESTORE_VALUES, (eGameMessageType)1591); + EXPECT_EQ(eGameMessageType::VEHICLE_STOP_BOOST, (eGameMessageType)1617); + EXPECT_EQ(eGameMessageType::REMOVE_BUFF, (eGameMessageType)1648); + EXPECT_EQ(eGameMessageType::REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES, (eGameMessageType)1666); + EXPECT_EQ(eGameMessageType::RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES, (eGameMessageType)1667); + EXPECT_EQ(eGameMessageType::PLAYER_SET_CAMERA_CYCLING_MODE, (eGameMessageType)1676); + EXPECT_EQ(eGameMessageType::SET_MOUNT_INVENTORY_ID, (eGameMessageType)1727); + EXPECT_EQ(eGameMessageType::NOTIFY_SERVER_LEVEL_PROCESSING_COMPLETE, (eGameMessageType)1734); + EXPECT_EQ(eGameMessageType::NOTIFY_LEVEL_REWARDS, (eGameMessageType)1735); + EXPECT_EQ(eGameMessageType::DISMOUNT_COMPLETE, (eGameMessageType)1756); + EXPECT_EQ(eGameMessageType::MARK_INVENTORY_ITEM_AS_ACTIVE, (eGameMessageType)1767); +} From 9a07020a51949b5e76b0d0296f96c7282c21a9dc Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 3 Aug 2023 19:31:02 -0700 Subject: [PATCH 083/111] perf: Behavior Parameter memory savings (#1166) * Memory Savings Behavior Parameter table * Update CDBehaviorParameterTable.h --- dDatabase/Tables/CDBehaviorParameterTable.cpp | 45 +++++++++---------- dDatabase/Tables/CDBehaviorParameterTable.h | 11 ++--- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index 0713e740..8181245b 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -1,26 +1,30 @@ #include "CDBehaviorParameterTable.h" #include "GeneralUtils.h" -CDBehaviorParameterTable::CDBehaviorParameterTable(void) { +uint64_t GetHash(const uint32_t behaviorID, const uint32_t parameterID) { + uint64_t hash = behaviorID; + hash <<= 31U; + hash |= parameterID; + + return hash; +} + +CDBehaviorParameterTable::CDBehaviorParameterTable() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); - uint32_t uniqueParameterId = 0; - uint64_t hash = 0; while (!tableData.eof()) { - CDBehaviorParameter entry; - entry.behaviorID = tableData.getIntField("behaviorID", -1); + uint32_t behaviorID = tableData.getIntField("behaviorID", -1); auto candidateStringToAdd = std::string(tableData.getStringField("parameterID", "")); auto parameter = m_ParametersList.find(candidateStringToAdd); + uint32_t parameterId; if (parameter != m_ParametersList.end()) { - entry.parameterID = parameter; + parameterId = parameter->second; } else { - entry.parameterID = m_ParametersList.insert(std::make_pair(candidateStringToAdd, uniqueParameterId)).first; - uniqueParameterId++; + parameterId = m_ParametersList.insert(std::make_pair(candidateStringToAdd, m_ParametersList.size())).first->second; } - hash = entry.behaviorID; - hash = (hash << 31U) | entry.parameterID->second; - entry.value = tableData.getFloatField("value", -1.0f); + uint64_t hash = GetHash(behaviorID, parameterId); + float value = tableData.getFloatField("value", -1.0f); - m_Entries.insert(std::make_pair(hash, entry)); + m_Entries.insert(std::make_pair(hash, value)); tableData.nextRow(); } @@ -30,27 +34,22 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) { auto parameterID = this->m_ParametersList.find(name); if (parameterID == this->m_ParametersList.end()) return defaultValue; - - uint64_t hash = behaviorID; - - hash = (hash << 31U) | parameterID->second; + auto hash = GetHash(behaviorID, parameterID->second); // Search for specific parameter - const auto& it = m_Entries.find(hash); - return it != m_Entries.end() ? it->second.value : defaultValue; + auto it = m_Entries.find(hash); + return it != m_Entries.end() ? it->second : defaultValue; } std::map CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) { uint64_t hashBase = behaviorID; std::map returnInfo; - uint64_t hash; - for (auto& parameterCandidate : m_ParametersList) { - hash = (hashBase << 31U) | parameterCandidate.second; + for (auto& [parameterString, parameterId] : m_ParametersList) { + uint64_t hash = GetHash(hashBase, parameterId); auto infoCandidate = m_Entries.find(hash); if (infoCandidate != m_Entries.end()) { - returnInfo.insert(std::make_pair(infoCandidate->second.parameterID->first, infoCandidate->second.value)); + returnInfo.insert(std::make_pair(parameterString, infoCandidate->second)); } } return returnInfo; } - diff --git a/dDatabase/Tables/CDBehaviorParameterTable.h b/dDatabase/Tables/CDBehaviorParameterTable.h index b0715684..249caacf 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.h +++ b/dDatabase/Tables/CDBehaviorParameterTable.h @@ -5,18 +5,15 @@ #include #include -struct CDBehaviorParameter { - unsigned int behaviorID; //!< The Behavior ID - std::unordered_map::iterator parameterID; //!< The Parameter ID - float value; //!< The value of the behavior template -}; - class CDBehaviorParameterTable : public CDTable { private: - std::unordered_map m_Entries; + typedef uint64_t BehaviorParameterHash; + typedef float BehaviorParameterValue; + std::unordered_map m_Entries; std::unordered_map m_ParametersList; public: CDBehaviorParameterTable(); + float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); std::map GetParametersByBehaviorID(uint32_t behaviorID); From 952786c166796e3a1e58c990c09e752793115290 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 3 Aug 2023 21:37:09 -0500 Subject: [PATCH 084/111] chore: cleanup some vanity npc logic (#1174) * Dont setup talk for vanity npc's if they are no phrases no ghosting ldfkey for canity npc's * void, oops * formatting --- dGame/Entity.h | 1 + dGame/dUtilities/VanityUtilities.cpp | 29 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/dGame/Entity.h b/dGame/Entity.h index 90f2a34f..ca007912 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -85,6 +85,7 @@ public: bool GetPlayerReadyForUpdates() const { return m_PlayerIsReadyForUpdates; } bool GetIsGhostingCandidate() const; + void SetIsGhostingCandidate(bool value) { m_IsGhostingCandidate = value; }; int8_t GetObservers() const; diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 86fa9503..eb182e04 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -80,10 +80,10 @@ void VanityUtilities::SpawnVanity() { // Spawn the NPC auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf); - - npcEntity->SetVar>(u"chats", m_PartyPhrases); - - SetupNPCTalk(npcEntity); + if (!npc.m_Phrases.empty()) { + npcEntity->SetVar>(u"chats", m_PartyPhrases); + SetupNPCTalk(npcEntity); + } } return; @@ -114,21 +114,21 @@ void VanityUtilities::SpawnVanity() { // Spawn the NPC auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf); + if (!npc.m_Phrases.empty()){ + npcEntity->SetVar>(u"chats", npc.m_Phrases); - npcEntity->SetVar>(u"chats", npc.m_Phrases); + auto* scriptComponent = npcEntity->GetComponent(); - auto* scriptComponent = npcEntity->GetComponent(); + if (scriptComponent && !npc.m_Script.empty()) { + scriptComponent->SetScript(npc.m_Script); + scriptComponent->SetSerialized(false); - if (scriptComponent && !npc.m_Script.empty()) { - scriptComponent->SetScript(npc.m_Script); - scriptComponent->SetSerialized(false); - - for (const auto& npc : npc.m_Flags) { - npcEntity->SetVar(GeneralUtils::ASCIIToUTF16(npc.first), npc.second); + for (const auto& npc : npc.m_Flags) { + npcEntity->SetVar(GeneralUtils::ASCIIToUTF16(npc.first), npc.second); + } } + SetupNPCTalk(npcEntity); } - - SetupNPCTalk(npcEntity); } if (zoneID == 1200) { @@ -160,6 +160,7 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin auto* entity = Game::entityManager->CreateEntity(info); entity->SetVar(u"npcName", name); + if (entity->GetVar(u"noGhosting")) entity->SetIsGhostingCandidate(false); auto* inventoryComponent = entity->GetComponent(); From 208ed021582f9cb37c2c028900163230586886ea Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 3 Aug 2023 19:37:27 -0700 Subject: [PATCH 085/111] Fix incorrect kick out of rebuilds (#1120) --- dGame/dComponents/RebuildComponent.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 13854bd6..e669489d 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -180,7 +180,7 @@ void RebuildComponent::Update(float deltaTime) { { Entity* builder = GetBuilder(); - if (builder == nullptr) { + if (!builder) { ResetRebuild(false); return; @@ -198,16 +198,16 @@ void RebuildComponent::Update(float deltaTime) { if (!destComp) break; int newImagination = destComp->GetImagination(); - if (newImagination <= 0) { - CancelRebuild(builder, eQuickBuildFailReason::OUT_OF_IMAGINATION, true); - break; - } ++m_DrainedImagination; --newImagination; destComp->SetImagination(newImagination); Game::entityManager->SerializeEntity(builder); + if (newImagination <= 0) { + CancelRebuild(builder, eQuickBuildFailReason::OUT_OF_IMAGINATION, true); + break; + } } @@ -482,7 +482,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId); } } - } else{ + } else { auto* missionComponent = builder->GetComponent(); if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId); } From d8a5fd49a49864f81d316d2cbda2ada174caa55c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 3 Aug 2023 19:38:04 -0700 Subject: [PATCH 086/111] chore: Small movementAiComponent cleanup (#1145) * rename and cleanup file * more * fix broken function * Further naming fixes t Revert "Further naming fixes" This reverts commit 057189982ba56788d48f9265d815e6c562ba6328. * next step * undo all testing changes * minor tweaks --- dGame/dComponents/BaseCombatAIComponent.cpp | 20 +- dGame/dComponents/MovementAIComponent.cpp | 312 +++++------------- dGame/dComponents/MovementAIComponent.h | 72 ++-- dGame/dComponents/PetComponent.cpp | 10 +- .../02_server/Map/AM/AmShieldGenerator.cpp | 2 +- .../Map/AM/AmShieldGeneratorQuickbuild.cpp | 2 +- .../Property/AG_Small/EnemySpiderSpawner.cpp | 6 - .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 2 +- 8 files changed, 131 insertions(+), 295 deletions(-) diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 77f7a493..5df43854 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -318,7 +318,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { // Speed towards start position if (m_MovementAI != nullptr) { m_MovementAI->SetHaltDistance(0); - m_MovementAI->SetSpeed(m_PursuitSpeed); + m_MovementAI->SetMaxSpeed(m_PursuitSpeed); m_MovementAI->SetDestination(m_StartPosition); } @@ -382,8 +382,6 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { } LWOOBJID BaseCombatAIComponent::FindTarget() { - //const auto reference = m_MovementAI == nullptr ? m_StartPosition : m_MovementAI->ApproximateLocation(); - NiPoint3 reference = m_StartPosition; if (m_MovementAI) reference = m_MovementAI->ApproximateLocation(); @@ -660,17 +658,17 @@ void BaseCombatAIComponent::Wander() { destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination); } - if (Vector3::DistanceSquared(destination, m_MovementAI->GetCurrentPosition()) < 2 * 2) { + if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) { m_MovementAI->Stop(); return; } - m_MovementAI->SetSpeed(m_TetherSpeed); + m_MovementAI->SetMaxSpeed(m_TetherSpeed); m_MovementAI->SetDestination(destination); - m_Timer += (m_MovementAI->GetCurrentPosition().x - destination.x) / m_TetherSpeed; + m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / m_TetherSpeed; } void BaseCombatAIComponent::OnAggro() { @@ -685,21 +683,21 @@ void BaseCombatAIComponent::OnAggro() { m_MovementAI->SetHaltDistance(m_AttackRadius); NiPoint3 targetPos = target->GetPosition(); - NiPoint3 currentPos = m_MovementAI->GetCurrentPosition(); + NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition(); // If the player's position is within range, attack if (Vector3::DistanceSquared(currentPos, targetPos) <= m_AttackRadius * m_AttackRadius) { m_MovementAI->Stop(); } else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far { - m_MovementAI->SetSpeed(m_PursuitSpeed); + m_MovementAI->SetMaxSpeed(m_PursuitSpeed); m_MovementAI->SetDestination(m_StartPosition); } else //Chase the player's new position { if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return; - m_MovementAI->SetSpeed(m_PursuitSpeed); + m_MovementAI->SetMaxSpeed(m_PursuitSpeed); m_MovementAI->SetDestination(targetPos); @@ -725,7 +723,7 @@ void BaseCombatAIComponent::OnTether() { m_MovementAI->Stop(); } else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far { - m_MovementAI->SetSpeed(m_PursuitSpeed); + m_MovementAI->SetMaxSpeed(m_PursuitSpeed); m_MovementAI->SetDestination(m_StartPosition); @@ -733,7 +731,7 @@ void BaseCombatAIComponent::OnTether() { } else { if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return; - m_MovementAI->SetSpeed(m_PursuitSpeed); + m_MovementAI->SetMaxSpeed(m_PursuitSpeed); m_MovementAI->SetDestination(targetPos); } diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 0743e8f6..1966638d 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -10,85 +10,77 @@ #include "EntityManager.h" #include "SimplePhysicsComponent.h" #include "CDClientManager.h" +#include "Game.h" +#include "dZoneManager.h" #include "CDComponentsRegistryTable.h" #include "CDPhysicsComponentTable.h" -std::map MovementAIComponent::m_PhysicsSpeedCache = {}; +namespace { + /** + * Cache of all lots and their respective speeds + */ + std::map m_PhysicsSpeedCache; +} MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : Component(parent) { - m_Info = std::move(info); - m_Done = true; + m_Info = info; + m_AtFinalWaypoint = true; m_BaseCombatAI = nullptr; - m_BaseCombatAI = reinterpret_cast(m_Parent->GetComponent(eReplicaComponentType::BASE_COMBAT_AI)); + m_BaseCombatAI = m_Parent->GetComponent(); //Try and fix the insane values: - if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius = m_Info.wanderRadius * 0.5f; + if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius *= 0.5f; if (m_Info.wanderRadius > 8.0f) m_Info.wanderRadius = 8.0f; - if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed = m_Info.wanderSpeed * 0.5f; + if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed *= 0.5f; m_BaseSpeed = GetBaseSpeed(m_Parent->GetLOT()); - m_NextWaypoint = GetCurrentPosition(); + m_NextWaypoint = m_Parent->GetPosition(); m_Acceleration = 0.4f; - m_Interrupted = false; - m_PullPoint = {}; + m_PullingToPoint = false; + m_PullPoint = NiPoint3::ZERO; m_HaltDistance = 0; - m_Timer = 0; + m_TimeToTravel = 0; + m_TimeTravelled = 0; m_CurrentSpeed = 0; - m_Speed = 0; - m_TotalTime = 0; + m_MaxSpeed = 0; m_LockRotation = false; } -MovementAIComponent::~MovementAIComponent() = default; - void MovementAIComponent::Update(const float deltaTime) { - if (m_Interrupted) { + if (m_PullingToPoint) { const auto source = GetCurrentWaypoint(); const auto speed = deltaTime * 2.5f; - NiPoint3 velocity; - - velocity.x = (m_PullPoint.x - source.x) * speed; - velocity.y = (m_PullPoint.y - source.y) * speed; - velocity.z = (m_PullPoint.z - source.z) * speed; + NiPoint3 velocity = (m_PullPoint - source) * speed; SetPosition(source + velocity); - if (Vector3::DistanceSquared(GetCurrentPosition(), m_PullPoint) < 2 * 2) { - m_Interrupted = false; + if (Vector3::DistanceSquared(m_Parent->GetPosition(), m_PullPoint) < std::pow(2, 2)) { + m_PullingToPoint = false; } return; } - if (AtFinalWaypoint()) // Are we done? - { - return; - } + // Are we done? + if (AtFinalWaypoint()) return; if (m_HaltDistance > 0) { - if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < m_HaltDistance * m_HaltDistance) // Prevent us from hugging the target - { + // Prevent us from hugging the target + if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < std::pow(m_HaltDistance, 2)) { Stop(); - return; } } - if (m_Timer > 0) { - m_Timer -= deltaTime; - - if (m_Timer > 0) { - return; - } - - m_Timer = 0; - } + m_TimeTravelled += deltaTime; + if (m_TimeTravelled < m_TimeToTravel) return; + m_TimeTravelled = 0.0f; const auto source = GetCurrentWaypoint(); @@ -101,48 +93,44 @@ void MovementAIComponent::Update(const float deltaTime) { m_NextWaypoint = GetCurrentWaypoint(); if (m_NextWaypoint == source) { - m_Timer = 0; + m_TimeToTravel = 0.0f; goto nextAction; } - if (m_CurrentSpeed < m_Speed) { + if (m_CurrentSpeed < m_MaxSpeed) { m_CurrentSpeed += m_Acceleration; } - if (m_CurrentSpeed > m_Speed) { - m_CurrentSpeed = m_Speed; + if (m_CurrentSpeed > m_MaxSpeed) { + m_CurrentSpeed = m_MaxSpeed; } - const auto speed = m_CurrentSpeed * m_BaseSpeed; + const auto speed = m_CurrentSpeed * m_BaseSpeed; // scale speed based on base speed const auto delta = m_NextWaypoint - source; // Normalize the vector - const auto length = sqrtf(delta.x * delta.x + delta.y * delta.y + delta.z * delta.z); - + const auto length = delta.Length(); if (length > 0) { - velocity.x = (delta.x / length) * speed; - velocity.y = (delta.y / length) * speed; - velocity.z = (delta.z / length) * speed; + velocity = (delta / length) * speed; } // Calclute the time it will take to reach the next waypoint with the current speed - m_TotalTime = m_Timer = length / speed; + m_TimeTravelled = 0.0f; + m_TimeToTravel = length / speed; SetRotation(NiQuaternion::LookAt(source, m_NextWaypoint)); } else { // Check if there are more waypoints in the queue, if so set our next destination to the next waypoint - if (!m_Queue.empty()) { - SetDestination(m_Queue.top()); - - m_Queue.pop(); - } else { - // We have reached our final waypoint + if (m_CurrentPath.empty()) { Stop(); return; } + SetDestination(m_CurrentPath.top()); + + m_CurrentPath.pop(); } nextAction: @@ -157,7 +145,7 @@ const MovementAIInfo& MovementAIComponent::GetInfo() const { } bool MovementAIComponent::AdvanceWaypointIndex() { - if (m_PathIndex >= m_CurrentPath.size()) { + if (m_PathIndex >= m_InterpolatedWaypoints.size()) { return false; } @@ -167,37 +155,19 @@ bool MovementAIComponent::AdvanceWaypointIndex() { } NiPoint3 MovementAIComponent::GetCurrentWaypoint() const { - if (m_PathIndex >= m_CurrentPath.size()) { - return GetCurrentPosition(); - } - - return m_CurrentPath[m_PathIndex]; -} - -NiPoint3 MovementAIComponent::GetNextWaypoint() const { - return m_NextWaypoint; -} - -NiPoint3 MovementAIComponent::GetCurrentPosition() const { - return m_Parent->GetPosition(); + return m_PathIndex >= m_InterpolatedWaypoints.size() ? m_Parent->GetPosition() : m_InterpolatedWaypoints[m_PathIndex]; } NiPoint3 MovementAIComponent::ApproximateLocation() const { - auto source = GetCurrentPosition(); + auto source = m_Parent->GetPosition(); - if (m_Done) { - return source; - } + if (AtFinalWaypoint()) return source; auto destination = m_NextWaypoint; - auto factor = m_TotalTime > 0 ? (m_TotalTime - m_Timer) / m_TotalTime : 0; + auto percentageToWaypoint = m_TimeToTravel > 0 ? m_TimeTravelled / m_TimeToTravel : 0; - auto x = source.x + factor * (destination.x - source.x); - auto y = source.y + factor * (destination.y - source.y); - auto z = source.z + factor * (destination.z - source.z); - - NiPoint3 approximation = NiPoint3(x, y, z); + auto approximation = source + ((destination - source) * percentageToWaypoint); if (dpWorld::Instance().IsLoaded()) { approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation); @@ -226,28 +196,20 @@ bool MovementAIComponent::Warp(const NiPoint3& point) { return true; } -float MovementAIComponent::GetTimer() const { - return m_Timer; -} - -bool MovementAIComponent::AtFinalWaypoint() const { - return m_Done; -} - void MovementAIComponent::Stop() { - if (m_Done) { - return; - } + if (AtFinalWaypoint()) return; SetPosition(ApproximateLocation()); SetVelocity(NiPoint3::ZERO); - m_TotalTime = m_Timer = 0; + m_TimeToTravel = 0; + m_TimeTravelled = 0; - m_Done = true; + m_AtFinalWaypoint = true; - m_CurrentPath = {}; + m_InterpolatedWaypoints.clear(); + while (!m_CurrentPath.empty()) m_CurrentPath.pop(); m_PathIndex = 0; @@ -259,20 +221,17 @@ void MovementAIComponent::Stop() { void MovementAIComponent::PullToPoint(const NiPoint3& point) { Stop(); - m_Interrupted = true; + m_PullingToPoint = true; m_PullPoint = point; } void MovementAIComponent::SetPath(std::vector path) { - std::reverse(path.begin(), path.end()); + if (path.empty()) return; + std::for_each(path.rbegin(), path.rend() - 1, [this](const NiPoint3& point) { + this->m_CurrentPath.push(point); + }); - for (const auto& point : path) { - m_Queue.push(point); - } - - SetDestination(m_Queue.top()); - - m_Queue.pop(); + SetDestination(path.front()); } float MovementAIComponent::GetBaseSpeed(LOT lot) { @@ -291,26 +250,14 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) { componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::CONTROLLABLE_PHYSICS, -1); - if (componentID != -1) { - physicsComponent = physicsComponentTable->GetByID(componentID); - - goto foundComponent; + if (componentID == -1) { + componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1); } - componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1); - - if (componentID != -1) { - physicsComponent = physicsComponentTable->GetByID(componentID); - - goto foundComponent; - } - -foundComponent: + physicsComponent = physicsComponentTable->GetByID(componentID); // 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) speed = physicsComponent->speed; + float speed = physicsComponent != nullptr ? physicsComponent->speed : 10.0f; float delta = fabs(speed) - 1.0f; @@ -322,39 +269,11 @@ foundComponent: } void MovementAIComponent::SetPosition(const NiPoint3& value) { - auto* controllablePhysicsComponent = m_Parent->GetComponent(); - - if (controllablePhysicsComponent != nullptr) { - controllablePhysicsComponent->SetPosition(value); - - return; - } - - auto* simplePhysicsComponent = m_Parent->GetComponent(); - - if (simplePhysicsComponent != nullptr) { - simplePhysicsComponent->SetPosition(value); - } + m_Parent->SetPosition(value); } void MovementAIComponent::SetRotation(const NiQuaternion& value) { - if (m_LockRotation) { - return; - } - - auto* controllablePhysicsComponent = m_Parent->GetComponent(); - - if (controllablePhysicsComponent != nullptr) { - controllablePhysicsComponent->SetRotation(value); - - return; - } - - auto* simplePhysicsComponent = m_Parent->GetComponent(); - - if (simplePhysicsComponent != nullptr) { - simplePhysicsComponent->SetRotation(value); - } + if (!m_LockRotation) m_Parent->SetRotation(value); } void MovementAIComponent::SetVelocity(const NiPoint3& value) { @@ -373,15 +292,8 @@ void MovementAIComponent::SetVelocity(const NiPoint3& value) { } } -void MovementAIComponent::SetDestination(const NiPoint3& value) { - if (m_Interrupted) { - return; - } - - /*if (Vector3::DistanceSquared(value, GetDestination()) < 2 * 2) - { - return; - }*/ +void MovementAIComponent::SetDestination(const NiPoint3& destination) { + if (m_PullingToPoint) return; const auto location = ApproximateLocation(); @@ -390,97 +302,53 @@ void MovementAIComponent::SetDestination(const NiPoint3& value) { } std::vector computedPath; - if (dpWorld::Instance().IsLoaded()) { - computedPath = dpWorld::Instance().GetNavMesh()->GetPath(GetCurrentPosition(), value, m_Info.wanderSpeed); - } else { + computedPath = dpWorld::Instance().GetNavMesh()->GetPath(m_Parent->GetPosition(), destination, m_Info.wanderSpeed); + } + + // Somehow failed + if (computedPath.empty()) { // Than take 10 points between the current position and the destination and make that the path - auto point = location; + auto start = location; - auto delta = value - point; + auto delta = destination - start; - auto step = delta / 10; + auto step = delta / 10.0f; for (int i = 0; i < 10; i++) { - point = point + step; + // TODO: Replace this with += when the NiPoint3::operator+= is fixed + start = start + step; - computedPath.push_back(point); + computedPath.push_back(start); } } - if (computedPath.empty()) // Somehow failed - { - return; - } - - m_CurrentPath.clear(); - - m_CurrentPath.push_back(location); + m_InterpolatedWaypoints.clear(); // Simply path - for (auto point : computedPath) { + for (auto& point : computedPath) { if (dpWorld::Instance().IsLoaded()) { point.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point); } - m_CurrentPath.push_back(point); + m_InterpolatedWaypoints.push_back(point); } - m_CurrentPath.push_back(computedPath[computedPath.size() - 1]); - m_PathIndex = 0; - m_TotalTime = m_Timer = 0; + m_TimeTravelled = 0; + m_TimeToTravel = 0; - m_Done = false; + m_AtFinalWaypoint = false; } NiPoint3 MovementAIComponent::GetDestination() const { - if (m_CurrentPath.empty()) { - return GetCurrentPosition(); - } - - return m_CurrentPath[m_CurrentPath.size() - 1]; + return m_InterpolatedWaypoints.empty() ? m_Parent->GetPosition() : m_InterpolatedWaypoints.back(); } -void MovementAIComponent::SetSpeed(const float value) { - m_Speed = value; +void MovementAIComponent::SetMaxSpeed(const float value) { + if (value == m_MaxSpeed) return; + m_MaxSpeed = value; m_Acceleration = value / 5; } - -float MovementAIComponent::GetSpeed() const { - return m_Speed; -} - -void MovementAIComponent::SetAcceleration(const float value) { - m_Acceleration = value; -} - -float MovementAIComponent::GetAcceleration() const { - return m_Acceleration; -} - -void MovementAIComponent::SetHaltDistance(const float value) { - m_HaltDistance = value; -} - -float MovementAIComponent::GetHaltDistance() const { - return m_HaltDistance; -} - -void MovementAIComponent::SetCurrentSpeed(float value) { - m_CurrentSpeed = value; -} - -float MovementAIComponent::GetCurrentSpeed() const { - return m_CurrentSpeed; -} - -void MovementAIComponent::SetLockRotation(bool value) { - m_LockRotation = value; -} - -bool MovementAIComponent::GetLockRotation() const { - return m_LockRotation; -} diff --git a/dGame/dComponents/MovementAIComponent.h b/dGame/dComponents/MovementAIComponent.h index 3c9044aa..4a4e4c0a 100644 --- a/dGame/dComponents/MovementAIComponent.h +++ b/dGame/dComponents/MovementAIComponent.h @@ -1,6 +1,6 @@ /* * Darkflame Universe - * Copyright 2018 + * Copyright 2023 */ #ifndef MOVEMENTAICOMPONENT_H @@ -60,7 +60,6 @@ public: static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI; MovementAIComponent(Entity* parentEntity, MovementAIInfo info); - ~MovementAIComponent() override; void Update(float deltaTime) override; @@ -86,61 +85,55 @@ public: * Sets the max speed at which this entity may run * @param value the speed value to set */ - void SetSpeed(float value); - - /** - * Returns the max speed at which this entity may run - * @return the max speed at which this entity may run - */ - float GetSpeed() const; + void SetMaxSpeed(float value); /** * Sets how fast the entity will accelerate when not running at full speed * @param value the acceleration to set */ - void SetAcceleration(float value); + void SetAcceleration(float value) { m_Acceleration = value; }; /** * Returns the current speed at which this entity accelerates when not running at full speed * @return the current speed at which this entity accelerates when not running at full speed */ - float GetAcceleration() const; + float GetAcceleration() const { return m_Acceleration; }; /** * Sets the halting distance (the distance at which we consider the target to be reached) * @param value the halting distance to set */ - void SetHaltDistance(float value); + void SetHaltDistance(float value) { m_HaltDistance = value; } /** * Returns the current halting distance (the distance at which we consider the target to be reached) * @return the current halting distance */ - float GetHaltDistance() const; + float GetHaltDistance() const { return m_HaltDistance; } /** * Sets the speed the entity is currently running at * @param value the speed value to set */ - void SetCurrentSpeed(float value); + void SetCurrentSpeed(float value) { m_CurrentSpeed = value; } /** * Returns the speed the entity is currently running at * @return the speed the entity is currently running at */ - float GetCurrentSpeed() const; + float GetCurrentSpeed() const { return m_CurrentSpeed; } /** * Locks the rotation of this entity in place, depending on the argument * @param value if true, the entity will be rotationally locked */ - void SetLockRotation(bool value); + void SetLockRotation(bool value) { m_LockRotation = value; } /** * Returns whether this entity is currently rotationally locked * @return true if the entity is rotationally locked, false otherwise */ - bool GetLockRotation() const; + bool GetLockRotation() const { return m_LockRotation; }; /** * Attempts to update the waypoint index, making the entity move to the next waypoint @@ -158,13 +151,7 @@ public: * Returns the waypoint this entity is supposed to move towards next * @return the waypoint this entity is supposed to move towards next */ - NiPoint3 GetNextWaypoint() const; - - /** - * Returns the current position of this entity - * @return the current position of this entity - */ - NiPoint3 GetCurrentPosition() const; + NiPoint3 GetNextWaypoint() const { return m_NextWaypoint; } /** * Returns the approximate current location of the entity, including y coordinates @@ -180,17 +167,11 @@ public: */ bool Warp(const NiPoint3& point); - /** - * Returns the time it will take to reach the final waypoint according to the current speed - * @return the time it will take to reach the final waypoint according to the current speed - */ - float GetTimer() const; - /** * Returns if the entity is at its final waypoint * @return if the entity is at its final waypoint */ - bool AtFinalWaypoint() const; + bool AtFinalWaypoint() const { return m_AtFinalWaypoint; } /** * Renders the entity stationary @@ -250,17 +231,12 @@ private: /** * The max speed this entity may move at */ - float m_Speed; + float m_MaxSpeed; /** * The time it will take to reach the next waypoint using the current speed */ - float m_Timer; - - /** - * The total time it will take to reach the waypoint form its starting point - */ - float m_TotalTime; + float m_TimeTravelled; /** * The path this entity is currently traversing @@ -270,7 +246,7 @@ private: /** * If the entity has reached it last waypoint */ - bool m_Done; + bool m_AtFinalWaypoint; /** * The speed the entity is currently moving at @@ -287,6 +263,11 @@ private: */ float m_HaltDistance; + /** + * The total time it will take to reach the waypoint form its starting point + */ + float m_TimeToTravel; + /** * The base speed this entity has */ @@ -295,7 +276,7 @@ private: /** * If the AI is currently turned of (e.g. when teleporting to some location) */ - bool m_Interrupted; + bool m_PullingToPoint; /** * A position that the entity is currently moving towards while being interrupted @@ -315,17 +296,12 @@ private: /** * The path the entity is currently following */ - std::vector m_CurrentPath; + std::vector m_InterpolatedWaypoints; /** - * Queue of positions to traverse + * The path from the current position to the destination. */ - std::stack m_Queue; - - /** - * Cache of all lots and their respective speeds - */ - static std::map m_PhysicsSpeedCache; + std::stack m_CurrentPath; }; #endif // MOVEMENTAICOMPONENT_H diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 167fbb2f..7df08c60 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -395,7 +395,7 @@ void PetComponent::Update(float deltaTime) { } auto destination = owner->GetPosition(); - NiPoint3 position = m_MovementAI->GetCurrentPosition(); + NiPoint3 position = m_MovementAI->GetParent()->GetPosition(); float distanceToOwner = Vector3::DistanceSquared(position, destination); @@ -466,7 +466,7 @@ skipTresure: m_MovementAI->SetHaltDistance(haltDistance); - m_MovementAI->SetSpeed(2.5f); + m_MovementAI->SetMaxSpeed(2.5f); m_MovementAI->SetDestination(destination); @@ -822,17 +822,17 @@ void PetComponent::Wander() { destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination); } - if (Vector3::DistanceSquared(destination, m_MovementAI->GetCurrentPosition()) < 2 * 2) { + if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) { m_MovementAI->Stop(); return; } - m_MovementAI->SetSpeed(info.wanderSpeed); + m_MovementAI->SetMaxSpeed(info.wanderSpeed); m_MovementAI->SetDestination(destination); - m_Timer += (m_MovementAI->GetCurrentPosition().x - destination.x) / info.wanderSpeed; + m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / info.wanderSpeed; } void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { diff --git a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp index e39233eb..7c785c41 100644 --- a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp @@ -136,7 +136,7 @@ void AmShieldGenerator::EnemyEnteredShield(Entity* self, Entity* intruder) { // TODO: Figure out how todo knockback, I'll stun them for now - if (NiPoint3::DistanceSquared(self->GetPosition(), movementAIComponent->GetCurrentPosition()) < 20 * 20) { + if (NiPoint3::DistanceSquared(self->GetPosition(), intruder->GetPosition()) < 20 * 20) { baseCombatAIComponent->Stun(2.0f); movementAIComponent->SetDestination(baseCombatAIComponent->GetStartPosition()); } diff --git a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp index 506f5580..0c09a5da 100644 --- a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp @@ -194,7 +194,7 @@ void AmShieldGeneratorQuickbuild::EnemyEnteredShield(Entity* self, Entity* intru // TODO: Figure out how todo knockback, I'll stun them for now - if (NiPoint3::DistanceSquared(self->GetPosition(), movementAIComponent->GetCurrentPosition()) < 20 * 20) { + if (NiPoint3::DistanceSquared(self->GetPosition(), intruder->GetPosition()) < 20 * 20) { baseCombatAIComponent->Stun(2.0f); movementAIComponent->SetDestination(baseCombatAIComponent->GetStartPosition()); } diff --git a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp index 641845a9..2d526a25 100644 --- a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp @@ -52,12 +52,6 @@ void EnemySpiderSpawner::OnTimerDone(Entity* self, std::string timerName) { if (newEntity) { Game::entityManager->ConstructEntity(newEntity); newEntity->GetGroups().push_back("BabySpider"); - - /* - auto* movementAi = newEntity->GetComponent(); - - movementAi->SetDestination(newEntity->GetPosition()); - */ } self->ScheduleKillAfterUpdate(); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 4aa8d0c9..66171b95 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -291,7 +291,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); - movementAI->SetSpeed(toSpawn.initialSpeed); + movementAI->SetMaxSpeed(toSpawn.initialSpeed); movementAI->SetCurrentSpeed(toSpawn.initialSpeed); movementAI->SetHaltDistance(0.0f); From 040a78c3867e839001c95a56c2496403304640f1 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 3 Aug 2023 19:38:19 -0700 Subject: [PATCH 087/111] fix: Remove usage of rand() and seed randomness for chatserver (#1152) * Remove usage of rand(), time(0) to time(NULL) Replace it with the random engine mt19937. convert time(0) to time(NULL) * update * revert a bunch of changes --- dChatServer/ChatServer.cpp | 3 +++ dScripts/BaseSurvivalServer.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index b9fb8556..185bccbf 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -33,6 +33,7 @@ namespace Game { dChatFilter* chatFilter = nullptr; AssetManager* assetManager = nullptr; bool shouldShutdown = false; + std::mt19937 randomEngine; } @@ -114,6 +115,8 @@ int main(int argc, char** argv) { Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::shouldShutdown); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); + + Game::randomEngine = std::mt19937(time(0)); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index 0e8d0431..ffa86968 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -472,7 +472,7 @@ std::vector BaseSurvivalServer::GetRandomMobSet(SpawnerNetworkCollecti if (mobSets.sets.find(spawnerNetworkCollection.mobSetName) != mobSets.sets.end()) { auto mobSet = mobSets.sets.at(spawnerNetworkCollection.mobSetName); if (setNumber < mobSet.size()) { - return mobSet.at(setNumber).at(rand() % mobSet.at(setNumber).size()); + return mobSet.at(setNumber).at(GeneralUtils::GenerateRandomNumber(0, mobSet.at(setNumber).size() - 1)); } } @@ -487,7 +487,7 @@ SpawnerNetwork BaseSurvivalServer::GetRandomSpawner(SpawnerNetworkCollection& sp } if (!validSpawners.empty()) { - auto spawner = validSpawners.at(rand() % validSpawners.size()); + auto spawner = validSpawners.at(GeneralUtils::GenerateRandomNumber(0, validSpawners.size() - 1)); spawner.isActive = true; return spawner; } From e5b69745aa779903a6450c14a49730c7eb48e9fb Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 3 Aug 2023 19:38:33 -0700 Subject: [PATCH 088/111] feat: Remove NET_VERSION define (#1153) * Remove NET_VERSION define I get to test this on 4 different platforms. yay... * move stuff around finally fixed you docker i love this Update Dockerfile Update Dockerfile change type Update AuthPackets.cpp Update AuthServer.cpp * Update CMakeVariables.txt * Update sharedconfig.ini --- .env.example | 2 +- CMakeVariables.txt | 8 ++------ README.md | 2 +- dMasterServer/MasterServer.cpp | 11 +++++++++++ dNet/AuthPackets.cpp | 7 ++++++- docker-compose.yml | 1 + docker/Dockerfile | 13 ++++++------- docker/setup.sh | 5 ++--- resources/sharedconfig.ini | 7 +++++++ 9 files changed, 37 insertions(+), 19 deletions(-) diff --git a/.env.example b/.env.example index 15385906..462fb17f 100644 --- a/.env.example +++ b/.env.example @@ -14,4 +14,4 @@ EXTERNAL_IP=localhost MARIADB_USER=darkflame MARIADB_PASSWORD=SECRET_VALUE_CHANGE_ME MARIADB_ROOT_PASSWORD=SECRET_VALUE_CHANGE_ME -MARIADB_DATABASE=darkflame \ No newline at end of file +MARIADB_DATABASE=darkflame diff --git a/CMakeVariables.txt b/CMakeVariables.txt index 02173ba7..67b78aac 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -1,12 +1,8 @@ PROJECT_VERSION_MAJOR=1 -PROJECT_VERSION_MINOR=1 -PROJECT_VERSION_PATCH=0 +PROJECT_VERSION_MINOR=0 +PROJECT_VERSION_PATCH=1 # LICENSE LICENSE=AGPL-3.0 -# The network version. -# 171023 - Darkflame Universe client -# 171022 - Unmodded client -NET_VERSION=171022 # Debugging # Set __dynamic to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs. __dynamic=1 diff --git a/README.md b/README.md index b7e2a101..b51fa4b0 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ If you would like to build the server faster, append `-j` where number i ### Notes Depending on your operating system, you may need to adjust some pre-processor defines in [CMakeVariables.txt](./CMakeVariables.txt) before building: * If you are on MacOS, ensure OPENSSL_ROOT_DIR is pointing to the openssl root directory. -* If you are using a Darkflame Universe client, ensure NET_VERSION is changed to 171023. +* If you are using a Darkflame Universe client, ensure `client_net_version` in `build/sharedconfig.ini` is changed to 171023. ## Configuring your server This server has a few steps that need to be taken to configure the server for your use case. diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index ce237eac..f56cad7f 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -113,6 +113,17 @@ int main(int argc, char** argv) { Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + uint32_t clientNetVersion = 0; + if (!GeneralUtils::TryParse(Game::config->GetValue("client_net_version"), clientNetVersion)) { + Game::logger->Log("MasterServer", "Failed to parse (%s) as net version. Cannot start server as no clients could connect.",Game::config->GetValue("client_net_version").c_str()); + Game::logger->Log("MasterServer", "As of version 1.1.1, client_net_version is required to be defined in sharedconfig.ini as opposed to in CMakeVariables.txt as NET_VERSION."); + Game::logger->Log("MasterServer", "Rerun cmake to ensure all config values exist. If client_net_version already exists in sharedconfig.ini, please ensure it is a valid number."); + Game::logger->Log("MasterServer", "like 171022"); + return EXIT_FAILURE; + } + + Game::logger->Log("MasterServer", "Using net version %s", Game::config->GetValue("client_net_version").c_str()); + Game::logger->Log("MasterServer", "Starting Master server..."); Game::logger->Log("MasterServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("MasterServer", "Compiled on: %s", __TIMESTAMP__); diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 978540c1..4d0d2fad 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -40,7 +40,12 @@ void AuthPackets::HandleHandshake(dServer* server, Packet* packet) { void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType) { RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM); - bitStream.Write(NET_VERSION); + uint32_t netVersion; + if (!GeneralUtils::TryParse(Game::config->GetValue("client_net_version"), netVersion)) { + Game::logger->Log("AuthPackets", "Failed to parse client_net_version. Cannot authenticate to %s:%i", nextServerIP.c_str(), nextServerPort); + return; + } + bitStream.Write(netVersion); bitStream.Write(uint32_t(0x93)); if (serverType == ServerType::Auth) bitStream.Write(uint32_t(1)); //Conn: auth diff --git a/docker-compose.yml b/docker-compose.yml index 4b997e53..d8c3c40a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,7 @@ services: - DATABASE_USER=${MARIADB_USER:-darkflame} - DATABASE_PASSWORD=${MARIADB_PASSWORD:-darkflame} - EXTERNAL_IP=${EXTERNAL_IP:-darkflame} + - BUILD_VERSION=${BUILD_VERSION:?171022} volumes: - ${CLIENT_PATH:?missing_client_path}:/client - shared_configs:/docker/ diff --git a/docker/Dockerfile b/docker/Dockerfile index c5638a20..39153110 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -32,13 +32,12 @@ COPY .clang-* CMake* LICENSE /build/ ARG BUILD_THREADS=1 ARG BUILD_VERSION=171022 -RUN echo "Build server" && \ - mkdir -p cmake_build && \ - cd cmake_build && \ - sed -i -e "s/NET_VERSION=.*/NET_VERSION=${BUILD_VERSION}/g" ../CMakeVariables.txt && \ - sed -i -e "s/__maria_db_connector_compile_jobs__=.*/__maria_db_connector_compile_jobs__=${BUILD_THREADS}/g" ../CMakeVariables.txt && \ - cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \ - make -j $BUILD_THREADS +RUN echo "Build server" +RUN sed -i -e "s/__maria_db_connector_compile_jobs__=.*/__maria_db_connector_compile_jobs__=${BUILD_THREADS}/g" CMakeVariables.txt +RUN mkdir -p cmake_build +RUN cd cmake_build && \ + cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \ + make -j$BUILD_THREADS FROM gcc:12 as runtime diff --git a/docker/setup.sh b/docker/setup.sh index ade67d2e..1944bbba 100755 --- a/docker/setup.sh +++ b/docker/setup.sh @@ -17,9 +17,8 @@ function update_database_ini_values_for() { update_ini $INI_FILE mysql_database $DATABASE update_ini $INI_FILE mysql_username $DATABASE_USER update_ini $INI_FILE mysql_password $DATABASE_PASSWORD - if [[ "$INI_FILE" != "worldconfig.ini" ]]; then - update_ini $INI_FILE external_ip $EXTERNAL_IP - fi + update_ini $INI_FILE client_net_version $BUILD_VERSION + update_ini $INI_FILE external_ip $EXTERNAL_IP } function update_ini_values() { diff --git a/resources/sharedconfig.ini b/resources/sharedconfig.ini index d2c43d11..ad587b18 100644 --- a/resources/sharedconfig.ini +++ b/resources/sharedconfig.ini @@ -36,3 +36,10 @@ maximum_outgoing_bandwidth=80000 # from 512 <= maximum_mtu_size <= 1492 so make sure to keep this # value within that range. maximum_mtu_size=1228 + +# The client network version to allow to connect to this server. +# Client's that do not match this value will be kicked from the server. +# If you are using a Darkflame Universe client, set this value to 171023. +# This cannot just be any arbitrary number. This has to match the same value that is in your client. +# If you do not know what this value is, default it to 171022. +client_net_version=171022 From a29253d2f0640452a6fa41907b9e269e96c825d0 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 3 Aug 2023 21:44:03 -0500 Subject: [PATCH 089/111] feature: Donation Vendor Component (#1168) * refactor: Vendor inventory loading Implement proper delta compression dynamically determine multicostitems and standard cost items Quatantine max's custom code * WIP * progress missions * address feedback * fix newline * Cleanup * oops * fix default for nexus tower jawbox cleanup some logs * remove log * remove include that got added back --- dCommon/dEnums/eGameMessageType.h | 4 +- dGame/Entity.cpp | 9 ++ dGame/LeaderboardManager.cpp | 68 ++++++------ dGame/dComponents/CMakeLists.txt | 1 + dGame/dComponents/CharacterComponent.h | 6 + dGame/dComponents/DonationVendorComponent.cpp | 50 +++++++++ dGame/dComponents/DonationVendorComponent.h | 27 +++++ dGame/dComponents/InventoryComponent.cpp | 3 + dGame/dGameMessages/GameMessageHandler.cpp | 17 ++- dGame/dGameMessages/GameMessages.cpp | 103 ++++++++++++++++++ dGame/dGameMessages/GameMessages.h | 6 + dGame/dMission/MissionTask.cpp | 3 + 12 files changed, 259 insertions(+), 38 deletions(-) create mode 100644 dGame/dComponents/DonationVendorComponent.cpp create mode 100644 dGame/dComponents/DonationVendorComponent.h diff --git a/dCommon/dEnums/eGameMessageType.h b/dCommon/dEnums/eGameMessageType.h index 69f542e1..d5751b51 100644 --- a/dCommon/dEnums/eGameMessageType.h +++ b/dCommon/dEnums/eGameMessageType.h @@ -169,7 +169,7 @@ enum class eGameMessageType : uint16_t { MODIFY_ARMOR = 187, MODIFY_MAX_ARMOR = 188, POP_HEALTH_STATE = 190, - PUSH_EQUIPPED_ITEMS_STATE = 191, + PUSH_EQUIPPED_ITEMS_STATE = 191, POP_EQUIPPED_ITEMS_STATE = 192, SET_GM_LEVEL = 193, GET_GM_LEVEL = 194, @@ -358,7 +358,7 @@ enum class eGameMessageType : uint16_t { GET_POSSESSOR = 397, IS_POSSESSED = 398, ENABLE_ACTIVITY = 399, - SET_SHOOTING_GALLERY_PARAMS = 400, + SET_SHOOTING_GALLERY_PARAMS = 400, OPEN_ACTIVITY_START_DIALOG = 401, REQUEST_ACTIVITY_START_STOP = 402, REQUEST_ACTIVITY_ENTER = 403, diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 998541ad..e3bacb8b 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -51,6 +51,7 @@ #include "BuildBorderComponent.h" #include "MovementAIComponent.h" #include "VendorComponent.h" +#include "DonationVendorComponent.h" #include "RocketLaunchpadControlComponent.h" #include "PropertyComponent.h" #include "BaseCombatAIComponent.h" @@ -578,6 +579,9 @@ void Entity::Initialize() { if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) { VendorComponent* comp = new VendorComponent(this); m_Components.insert(std::make_pair(eReplicaComponentType::VENDOR, comp)); + } else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) { + DonationVendorComponent* comp = new DonationVendorComponent(this); + m_Components.insert(std::make_pair(eReplicaComponentType::DONATION_VENDOR, comp)); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) { @@ -1160,6 +1164,11 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType vendorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } + DonationVendorComponent* donationVendorComponent; + if (TryGetComponent(eReplicaComponentType::DONATION_VENDOR, donationVendorComponent)) { + donationVendorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + } + BouncerComponent* bouncerComponent; if (TryGetComponent(eReplicaComponentType::BOUNCER, bouncerComponent)) { bouncerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index a4c6ec1a..0e64b6b3 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -131,8 +131,8 @@ void Leaderboard::QueryToLdf(std::unique_ptr& rows) { // Time:1 break; case Type::Donations: - entry.push_back(new LDFData(u"Points", rows->getInt("primaryScore"))); - // Score:1 + entry.push_back(new LDFData(u"Score", rows->getInt("primaryScore"))); + // Score:1 break; case Type::None: // This type is included here simply to resolve a compiler warning on mac about unused enum types @@ -170,32 +170,32 @@ void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t r resultEnd++; // We need everything except 1 column so i'm selecting * from leaderboard const std::string queryBase = - R"QUERY( - WITH leaderboardsRanked AS ( - SELECT leaderboard.*, charinfo.name, - RANK() OVER - ( + 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 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 - 9) - AND - LEAST(GREATEST(myRank + 5, %i), lowestRanking.lowestRank) + ) 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 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 - 9) + AND + LEAST(GREATEST(myRank + 5, %i), lowestRanking.lowestRank) ORDER BY ranking ASC; )QUERY"; @@ -277,15 +277,15 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons if (useUpdate) { insertStatement = R"QUERY( - UPDATE leaderboard - SET primaryScore = %f, secondaryScore = %f, tertiaryScore = %f, + 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, + INSERT leaderboard SET + primaryScore = %f, secondaryScore = %f, tertiaryScore = %f, character_id = ?, game_id = ?; )QUERY"; } @@ -300,9 +300,8 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons 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)); + std::unique_ptr query(Database::CreatePreppedStmt("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;")); query->setInt(1, playerID); query->setInt(2, activityId); std::unique_ptr myScoreResult(query->executeQuery()); @@ -337,6 +336,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi case Leaderboard::Type::UnusedLeaderboard4: case Leaderboard::Type::Donations: { oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + newScore.SetPrimaryScore(oldScore.GetPrimaryScore() + newScore.GetPrimaryScore()); break; } case Leaderboard::Type::Racing: { @@ -382,7 +382,7 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi 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 = ?;")); diff --git a/dGame/dComponents/CMakeLists.txt b/dGame/dComponents/CMakeLists.txt index b396829a..67f4ece5 100644 --- a/dGame/dComponents/CMakeLists.txt +++ b/dGame/dComponents/CMakeLists.txt @@ -6,6 +6,7 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp" "Component.cpp" "ControllablePhysicsComponent.cpp" "DestroyableComponent.cpp" + "DonationVendorComponent.cpp" "InventoryComponent.cpp" "LevelProgressionComponent.cpp" "LUPExhibitComponent.cpp" diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index e5ca6da5..c367aefc 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -276,6 +276,10 @@ public: */ void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const; + void SetCurrentInteracting(LWOOBJID objectID) {m_CurrentInteracting = objectID;}; + + LWOOBJID GetCurrentInteracting() {return m_CurrentInteracting;}; + /** * Character info regarding this character, including clothing styles, etc. */ @@ -560,6 +564,8 @@ private: * ID of the last rocket used */ LWOOBJID m_LastRocketItemID = LWOOBJID_EMPTY; + + LWOOBJID m_CurrentInteracting = LWOOBJID_EMPTY; }; #endif // CHARACTERCOMPONENT_H diff --git a/dGame/dComponents/DonationVendorComponent.cpp b/dGame/dComponents/DonationVendorComponent.cpp new file mode 100644 index 00000000..f19ba9b7 --- /dev/null +++ b/dGame/dComponents/DonationVendorComponent.cpp @@ -0,0 +1,50 @@ +#include "DonationVendorComponent.h" +#include "Database.h" + +DonationVendorComponent::DonationVendorComponent(Entity* parent) : VendorComponent(parent) { + //LoadConfigData + m_PercentComplete = 0.0; + m_TotalDonated = 0; + m_TotalRemaining = 0; + + // custom attribute to calculate other values + m_Goal = m_Parent->GetVar(u"donationGoal"); + if (m_Goal == 0) m_Goal = INT32_MAX; + + // Default to the nexus tower jawbox activity and setup settings + m_ActivityId = m_Parent->GetVar(u"activityID"); + if ((m_ActivityId == 0) || (m_ActivityId == 117)) { + m_ActivityId = 117; + m_PercentComplete = 1.0; + m_TotalDonated = INT32_MAX; + m_TotalRemaining = 0; + m_Goal = INT32_MAX; + return; + } + + std::unique_ptr query(Database::CreatePreppedStmt("SELECT SUM(primaryScore) as donation_total FROM leaderboard WHERE game_id = ?;")); + query->setInt(1, m_ActivityId); + std::unique_ptr donation_total(query->executeQuery()); + if (donation_total->next()) m_TotalDonated = donation_total->getInt("donation_total"); + m_TotalRemaining = m_Goal - m_TotalDonated; + m_PercentComplete = m_TotalDonated/static_cast(m_Goal); +} + +void DonationVendorComponent::SubmitDonation(uint32_t count) { + if (count <= 0 && ((m_TotalDonated + count) > 0)) return; + m_TotalDonated += count; + m_TotalRemaining = m_Goal - m_TotalDonated; + m_PercentComplete = m_TotalDonated/static_cast(m_Goal); + m_DirtyDonationVendor = true; +} + +void DonationVendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { + VendorComponent::Serialize(outBitStream, bIsInitialUpdate, flags); + outBitStream->Write(bIsInitialUpdate || m_DirtyDonationVendor); + if (bIsInitialUpdate || m_DirtyDonationVendor) { + outBitStream->Write(m_PercentComplete); + outBitStream->Write(m_TotalDonated); + outBitStream->Write(m_TotalRemaining); + if (!bIsInitialUpdate) m_DirtyDonationVendor = false; + } +} diff --git a/dGame/dComponents/DonationVendorComponent.h b/dGame/dComponents/DonationVendorComponent.h new file mode 100644 index 00000000..6c706bf9 --- /dev/null +++ b/dGame/dComponents/DonationVendorComponent.h @@ -0,0 +1,27 @@ +#ifndef __DONATIONVENDORCOMPONENT__H__ +#define __DONATIONVENDORCOMPONENT__H__ + +#include "VendorComponent.h" +#include "eReplicaComponentType.h" + +class Entity; + +class DonationVendorComponent final : public VendorComponent { +public: + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DONATION_VENDOR; + DonationVendorComponent(Entity* parent); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + uint32_t GetActivityID() {return m_ActivityId;}; + void SubmitDonation(uint32_t count); + +private: + bool m_DirtyDonationVendor = false; + float m_PercentComplete = 0.0; + int32_t m_TotalDonated = 0; + int32_t m_TotalRemaining = 0; + uint32_t m_ActivityId = 0; + int32_t m_Goal = 0; +}; + + +#endif //!__DONATIONVENDORCOMPONENT__H__ diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 66b47e52..8689c0bc 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -116,6 +116,9 @@ Inventory* InventoryComponent::GetInventory(const eInventoryType type) { case eInventoryType::VENDOR_BUYBACK: size = 27u; break; + case eInventoryType::DONATION: + size = 24u; + break; default: break; } diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index ba063d2d..99592ed2 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -48,10 +48,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System if (!entity) { Game::logger->Log("GameMessageHandler", "Failed to find associated entity (%llu), aborting GM (%X)!", objectID, messageID); - return; } + if (messageID != eGameMessageType::READY_FOR_UPDATES) Game::logger->LogDebug("GameMessageHandler", "received game message ID: %i", messageID); + switch (messageID) { case eGameMessageType::UN_USE_BBB_MODEL: { @@ -680,8 +681,20 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case eGameMessageType::REQUEST_ACTIVITY_EXIT: GameMessages::HandleRequestActivityExit(inStream, entity); break; + case eGameMessageType::ADD_DONATION_ITEM: + GameMessages::HandleAddDonationItem(inStream, entity, sysAddr); + break; + case eGameMessageType::REMOVE_DONATION_ITEM: + GameMessages::HandleRemoveDonationItem(inStream, entity, sysAddr); + break; + case eGameMessageType::CONFIRM_DONATION_ON_PLAYER: + GameMessages::HandleConfirmDonationOnPlayer(inStream, entity); + break; + case eGameMessageType::CANCEL_DONATION_ON_PLAYER: + GameMessages::HandleCancelDonationOnPlayer(inStream, entity); + break; default: - // Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID); + Game::logger->LogDebug("GameMessageHandler", "Unknown game message ID: %i", messageID); break; } } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index e5567cfa..020e0abe 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -76,6 +76,7 @@ #include "RacingControlComponent.h" #include "RailActivatorComponent.h" #include "LevelProgressionComponent.h" +#include "DonationVendorComponent.h" // Message includes: #include "dZoneManager.h" @@ -1294,6 +1295,7 @@ void GameMessages::SendVendorStatusUpdate(Entity* entity, const SystemAddress& s bitStream.Write(bUpdateOnly); bitStream.Write(vendorItems.size()); + for (const auto& item : vendorItems) { bitStream.Write(item.lot); bitStream.Write(item.sortPriority); @@ -6207,3 +6209,104 @@ void GameMessages::HandleRequestActivityExit(RakNet::BitStream* inStream, Entity if (!entity || !player) return; entity->RequestActivityExit(entity, player_id, canceled); } + +void GameMessages::HandleAddDonationItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { + uint32_t count = 1; + bool hasCount = false; + inStream->Read(hasCount); + if (hasCount) inStream->Read(count); + LWOOBJID itemId = LWOOBJID_EMPTY; + inStream->Read(itemId); + if (!itemId) return; + + auto* donationVendorComponent = entity->GetComponent(); + if (!donationVendorComponent) return; + if (donationVendorComponent->GetActivityID() == 0) { + Game::logger->Log("GameMessages", "WARNING: Trying to dontate to a vendor with no activity"); + return; + } + User* user = UserManager::Instance()->GetUser(sysAddr); + if (!user) return; + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); + if (!player) return; + auto* characterComponent = player->GetComponent(); + if (!characterComponent) return; + auto* inventoryComponent = player->GetComponent(); + if (!inventoryComponent) return; + Item* item = inventoryComponent->FindItemById(itemId); + if (!item) return; + if (item->GetCount() < count) return; + characterComponent->SetCurrentInteracting(entity->GetObjectID()); + inventoryComponent->MoveItemToInventory(item, eInventoryType::DONATION, count, true, false, true); +} + +void GameMessages::HandleRemoveDonationItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { + bool confirmed = false; + inStream->Read(confirmed); + uint32_t count = 1; + bool hasCount = false; + inStream->Read(hasCount); + if (hasCount) inStream->Read(count); + LWOOBJID itemId = LWOOBJID_EMPTY; + inStream->Read(itemId); + if (!itemId) return; + + User* user = UserManager::Instance()->GetUser(sysAddr); + if (!user) return; + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); + if (!player) return; + + auto* inventoryComponent = player->GetComponent(); + if (!inventoryComponent) return; + + Item* item = inventoryComponent->FindItemById(itemId); + if (!item) return; + if (item->GetCount() < count) return; + inventoryComponent->MoveItemToInventory(item, eInventoryType::BRICKS, count, true, false, true); +} + +void GameMessages::HandleConfirmDonationOnPlayer(RakNet::BitStream* inStream, Entity* entity) { + auto* inventoryComponent = entity->GetComponent(); + if (!inventoryComponent) return; + auto* missionComponent = entity->GetComponent(); + if (!missionComponent) return; + auto* characterComponent = entity->GetComponent(); + if (!characterComponent || !characterComponent->GetCurrentInteracting()) return; + auto* donationEntity = Game::entityManager->GetEntity(characterComponent->GetCurrentInteracting()); + if (!donationEntity) return; + auto* donationVendorComponent = donationEntity->GetComponent(); + if(!donationVendorComponent) return; + if (donationVendorComponent->GetActivityID() == 0) { + Game::logger->Log("GameMessages", "WARNING: Trying to dontate to a vendor with no activity"); + return; + } + auto* inventory = inventoryComponent->GetInventory(eInventoryType::DONATION); + if (!inventory) return; + auto items = inventory->GetItems(); + if (!items.empty()) { + uint32_t count = 0; + for (auto& [itemID, item] : items){ + count += item->GetCount(); + item->RemoveFromInventory(); + } + missionComponent->Progress(eMissionTaskType::DONATION, 0, LWOOBJID_EMPTY, "", count); + LeaderboardManager::SaveScore(entity->GetObjectID(), donationVendorComponent->GetActivityID(), count); + donationVendorComponent->SubmitDonation(count); + Game::entityManager->SerializeEntity(donationEntity); + } + characterComponent->SetCurrentInteracting(LWOOBJID_EMPTY); +} + +void GameMessages::HandleCancelDonationOnPlayer(RakNet::BitStream* inStream, Entity* entity) { + auto* inventoryComponent = entity->GetComponent(); + if (!inventoryComponent) return; + auto* inventory = inventoryComponent->GetInventory(eInventoryType::DONATION); + if (!inventory) return; + auto items = inventory->GetItems(); + for (auto& [itemID, item] : items){ + inventoryComponent->MoveItemToInventory(item, eInventoryType::BRICKS, item->GetCount(), false, false, true); + } + auto* characterComponent = entity->GetComponent(); + if (!characterComponent) return; + characterComponent->SetCurrentInteracting(LWOOBJID_EMPTY); +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index bd1224d3..3a9963b4 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -649,6 +649,12 @@ namespace GameMessages { void HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity); void HandleRequestActivityExit(RakNet::BitStream* inStream, Entity* entity); + + // Donation vendor + void HandleAddDonationItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); + void HandleRemoveDonationItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); + void HandleConfirmDonationOnPlayer(RakNet::BitStream* inStream, Entity* entity); + void HandleCancelDonationOnPlayer(RakNet::BitStream* inStream, Entity* entity); }; #endif // GAMEMESSAGES_H diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index 6bc12b72..997fd34e 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -449,6 +449,9 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& AddProgress(count); break; } + case eMissionTaskType::DONATION: + AddProgress(count); + break; default: Game::logger->Log("MissionTask", "Invalid mission task type (%i)!", static_cast(type)); return; From 7e2747a2d2dc286cf5dcb3c90769c607b1a6c741 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 4 Aug 2023 17:48:45 -0500 Subject: [PATCH 090/111] fix: load fdbchecksum to verify, even on character selection (world 0) (#1176) --- dWorldServer/WorldServer.cpp | 81 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index f07c17e3..644e6ce8 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -262,50 +262,51 @@ int main(int argc, char** argv) { Game::zoneManager->Initialize(LWOZONEID(zoneID, instanceID, cloneID)); g_CloneID = cloneID; - // pre calculate the FDB checksum - if (Game::config->GetValue("check_fdb") == "1") { - std::ifstream fileStream; - - static const std::vector aliases = { - "CDServers.fdb", - "cdserver.fdb", - "CDClient.fdb", - "cdclient.fdb", - }; - - for (const auto& file : aliases) { - fileStream.open(Game::assetManager->GetResPath() / file, std::ios::binary | std::ios::in); - if (fileStream.is_open()) { - break; - } - } - - const int32_t bufferSize = 1024; - MD5* md5 = new MD5(); - - char fileStreamBuffer[1024] = {}; - - while (!fileStream.eof()) { - memset(fileStreamBuffer, 0, bufferSize); - fileStream.read(fileStreamBuffer, bufferSize); - md5->update(fileStreamBuffer, fileStream.gcount()); - } - - fileStream.close(); - - const char* nullTerminateBuffer = "\0"; - md5->update(nullTerminateBuffer, 1); // null terminate the data - md5->finalize(); - databaseChecksum = md5->hexdigest(); - - delete md5; - - Game::logger->Log("WorldServer", "FDB Checksum calculated as: %s", databaseChecksum.c_str()); - } } else { Game::entityManager->Initialize(); } + // pre calculate the FDB checksum + if (Game::config->GetValue("check_fdb") == "1") { + std::ifstream fileStream; + + static const std::vector aliases = { + "CDServers.fdb", + "cdserver.fdb", + "CDClient.fdb", + "cdclient.fdb", + }; + + for (const auto& file : aliases) { + fileStream.open(Game::assetManager->GetResPath() / file, std::ios::binary | std::ios::in); + if (fileStream.is_open()) { + break; + } + } + + const int32_t bufferSize = 1024; + MD5* md5 = new MD5(); + + char fileStreamBuffer[1024] = {}; + + while (!fileStream.eof()) { + memset(fileStreamBuffer, 0, bufferSize); + fileStream.read(fileStreamBuffer, bufferSize); + md5->update(fileStreamBuffer, fileStream.gcount()); + } + + fileStream.close(); + + const char* nullTerminateBuffer = "\0"; + md5->update(nullTerminateBuffer, 1); // null terminate the data + md5->finalize(); + databaseChecksum = md5->hexdigest(); + + delete md5; + + Game::logger->Log("WorldServer", "FDB Checksum calculated as: %s", databaseChecksum.c_str()); + } + uint32_t currentFrameDelta = highFrameDelta; // These values are adjust them selves to the current framerate should it update. uint32_t logFlushTime = 15 * currentFramerate; // 15 seconds in frames From cefdfc696a8c843ee53261cb45e048cff26a235a Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sun, 6 Aug 2023 15:38:12 -0500 Subject: [PATCH 091/111] fix: Implement proper Sound trigger component serialization (#1160) * cleanup * more cleanup and fully implement the sound trigger and racing sound trigger * more cleanup, and better defaults * fixes and tested * update initializor for guid and when to load sound guids * make racing sound trigger it's own component * fix type * Remove global move serializes --------- Co-authored-by: David Markowitz --- dGame/Entity.cpp | 9 ++ .../dComponents/RacingSoundTriggerComponent.h | 15 ++ dGame/dComponents/SoundTriggerComponent.cpp | 143 ++++++++++-------- dGame/dComponents/SoundTriggerComponent.h | 86 ++++++----- dGame/dUtilities/GUID.cpp | 26 ++-- dGame/dUtilities/GUID.h | 22 ++- 6 files changed, 188 insertions(+), 113 deletions(-) create mode 100644 dGame/dComponents/RacingSoundTriggerComponent.h diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index e3bacb8b..237cfa73 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -71,6 +71,7 @@ #include "ShootingGalleryComponent.h" #include "RailActivatorComponent.h" #include "LUPExhibitComponent.h" +#include "RacingSoundTriggerComponent.h" #include "TriggerComponent.h" #include "eGameMasterLevel.h" #include "eReplicaComponentType.h" @@ -318,6 +319,9 @@ void Entity::Initialize() { if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SOUND_TRIGGER, -1) != -1) { auto* comp = new SoundTriggerComponent(this); m_Components.insert(std::make_pair(eReplicaComponentType::SOUND_TRIGGER, comp)); + } else if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_SOUND_TRIGGER, -1) != -1) { + auto* comp = new RacingSoundTriggerComponent(this); + m_Components.insert(std::make_pair(eReplicaComponentType::RACING_SOUND_TRIGGER, comp)); } //Also check for the collectible id: @@ -1060,6 +1064,11 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType soundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } + RacingSoundTriggerComponent* racingSoundTriggerComponent; + if (TryGetComponent(eReplicaComponentType::RACING_SOUND_TRIGGER, racingSoundTriggerComponent)) { + racingSoundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + } + BuffComponent* buffComponent; if (TryGetComponent(eReplicaComponentType::BUFF, buffComponent)) { buffComponent->Serialize(outBitStream, bIsInitialUpdate, flags); diff --git a/dGame/dComponents/RacingSoundTriggerComponent.h b/dGame/dComponents/RacingSoundTriggerComponent.h new file mode 100644 index 00000000..0f79c67f --- /dev/null +++ b/dGame/dComponents/RacingSoundTriggerComponent.h @@ -0,0 +1,15 @@ +#ifndef __RACINGSOUNDTRIGGERCOMPONENT__H__ +#define __RACINGSOUNDTRIGGERCOMPONENT__H__ + +#include "SoundTriggerComponent.h" +#include "eReplicaComponentType.h" + +class Entity; + +class RacingSoundTriggerComponent : public SoundTriggerComponent { +public: + inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_SOUND_TRIGGER; + RacingSoundTriggerComponent(Entity* parent) : SoundTriggerComponent(parent){}; +}; + +#endif //!__RACINGSOUNDTRIGGERCOMPONENT__H__ diff --git a/dGame/dComponents/SoundTriggerComponent.cpp b/dGame/dComponents/SoundTriggerComponent.cpp index 21d30948..823d3ff4 100644 --- a/dGame/dComponents/SoundTriggerComponent.cpp +++ b/dGame/dComponents/SoundTriggerComponent.cpp @@ -1,93 +1,114 @@ #include "SoundTriggerComponent.h" -#include "EntityManager.h" #include "Game.h" +#include "dLogger.h" +void MusicCue::Serialize(RakNet::BitStream* outBitStream){ + outBitStream->Write(name.size()); + outBitStream->Write(name.c_str(), name.size()); + outBitStream->Write(result); + outBitStream->Write(boredomTime); +} + +void MusicParameter::Serialize(RakNet::BitStream* outBitStream){ + outBitStream->Write(name.size()); + outBitStream->Write(name.c_str(), name.size()); + outBitStream->Write(value); +} + +void GUIDResults::Serialize(RakNet::BitStream* outBitStream){ + guid.Serialize(outBitStream); + outBitStream->Write(result); +} + +void MixerProgram::Serialize(RakNet::BitStream* outBitStream){ + outBitStream->Write(name.size()); + outBitStream->Write(name.c_str(), name.size()); + outBitStream->Write(result); +} SoundTriggerComponent::SoundTriggerComponent(Entity* parent) : Component(parent) { + const auto musicCueName = parent->GetVar(u"NDAudioMusicCue_Name"); - const auto musicCueBoredomTime = parent->GetVar(u"NDAudioMusicCue_BoredomTime"); + if (!musicCueName.empty()) { + auto newCue = MusicCue(musicCueName); + const auto musicCueBoredomTime = parent->GetVar(u"NDAudioMusicCue_BoredomTime"); + if (musicCueBoredomTime) newCue.boredomTime = musicCueBoredomTime; + this->m_MusicCues.push_back(newCue); + } - this->musicCues.push_back({ - musicCueName, - 1, - musicCueBoredomTime - }); + const auto musicParameterName = parent->GetVar(u"NDAudioMusicParameter_Name"); + if (!musicParameterName.empty()) { + auto newParams = MusicParameter(musicParameterName); + const auto musicParameterValue = parent->GetVar(u"NDAudioMusicParameter_Value"); + if (musicParameterValue) newParams.value = musicParameterValue; + this->m_MusicParameters.push_back(newParams); + } - const auto mixerName = parent->GetVar(u"NDAudioMixerProgram_Name"); - this->mixerPrograms.push_back(mixerName); + const auto guidString = parent->GetVar(u"NDAudioEventGUID"); + if (!guidString.empty()) + this->m_2DAmbientSounds.push_back(GUIDResults(guidString)); const auto guid2String = parent->GetVar(u"NDAudioEventGUID2"); - if (!guid2String.empty()) { - this->guids.emplace_back(guid2String); - } -} + if (!guid2String.empty()) + this->m_3DAmbientSounds.push_back(GUIDResults(guid2String)); -SoundTriggerComponent::~SoundTriggerComponent() = default; + const auto mixerName = parent->GetVar(u"NDAudioMixerProgram_Name"); + if (!mixerName.empty()) this->m_MixerPrograms.push_back(MixerProgram(mixerName)); +} void SoundTriggerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - if (bIsInitialUpdate) - dirty = true; - - outBitStream->Write(dirty); - - if (dirty) { - outBitStream->Write(this->musicCues.size()); - for (const auto& musicCue : this->musicCues) { - outBitStream->Write(musicCue.name.size()); - outBitStream->Write(musicCue.name.c_str(), musicCue.name.size()); - outBitStream->Write(musicCue.result); - outBitStream->Write(musicCue.boredomTime); + outBitStream->Write(this->m_Dirty || bIsInitialUpdate); + if (this->m_Dirty || bIsInitialUpdate) { + outBitStream->Write(this->m_MusicCues.size()); + for (auto& musicCue : this->m_MusicCues) { + musicCue.Serialize(outBitStream); } - // Unknown part - outBitStream->Write(0); - - // GUID part - outBitStream->Write(this->guids.size()); - - for (const auto guid : this->guids) { - outBitStream->Write(guid.GetData1()); - outBitStream->Write(guid.GetData2()); - outBitStream->Write(guid.GetData3()); - for (const auto& guidSubPart : guid.GetData4()) { - outBitStream->Write(guidSubPart); - } - outBitStream->Write(1); // Unknown + outBitStream->Write(this->m_MusicParameters.size()); + for (auto& musicParam : this->m_MusicParameters) { + musicParam.Serialize(outBitStream); } - // Mixer program part - outBitStream->Write(this->mixerPrograms.size()); - for (const auto& mixerProgram : mixerPrograms) { - outBitStream->Write(mixerProgram.size()); - outBitStream->Write(mixerProgram.c_str(), mixerProgram.size()); - outBitStream->Write(1); // Unknown + outBitStream->Write(this->m_2DAmbientSounds.size()); + for (auto twoDAmbientSound : this->m_2DAmbientSounds) { + twoDAmbientSound.Serialize(outBitStream); } - dirty = false; + outBitStream->Write(this->m_3DAmbientSounds.size()); + for (auto threeDAmbientSound : this->m_3DAmbientSounds) { + threeDAmbientSound.Serialize(outBitStream); + } + + outBitStream->Write(this->m_MixerPrograms.size()); + for (auto& mixerProgram : this->m_MixerPrograms) { + mixerProgram.Serialize(outBitStream); + } + + if (!bIsInitialUpdate) this->m_Dirty = false; } } -void SoundTriggerComponent::ActivateMusicCue(const std::string& name) { - if (std::find_if(this->musicCues.begin(), this->musicCues.end(), [name](const MusicCue& musicCue) { +void SoundTriggerComponent::ActivateMusicCue(const std::string& name, float bordemTime) { + const auto musicCue = std::find_if(this->m_MusicCues.begin(), this->m_MusicCues.end(), [name](const MusicCue& musicCue) { return musicCue.name == name; - }) == this->musicCues.end()) { - this->musicCues.push_back({ - name, - 1, - -1.0f - }); - dirty = true; + } + ); + + if (musicCue == this->m_MusicCues.end()) { + this->m_MusicCues.push_back(MusicCue(name, bordemTime)); + this->m_Dirty = true; Game::entityManager->SerializeEntity(m_Parent); } } void SoundTriggerComponent::DeactivateMusicCue(const std::string& name) { - const auto musicCue = std::find_if(this->musicCues.begin(), this->musicCues.end(), [name](const MusicCue& musicCue) { + const auto musicCue = std::find_if(this->m_MusicCues.begin(), this->m_MusicCues.end(), [name](const MusicCue& musicCue) { return musicCue.name == name; - }); + } + ); - if (musicCue != this->musicCues.end()) { - this->musicCues.erase(musicCue); - dirty = true; + if (musicCue != this->m_MusicCues.end()) { + this->m_MusicCues.erase(musicCue); + this->m_Dirty = true; Game::entityManager->SerializeEntity(m_Parent); } } diff --git a/dGame/dComponents/SoundTriggerComponent.h b/dGame/dComponents/SoundTriggerComponent.h index 954d8495..6d42a2e3 100644 --- a/dGame/dComponents/SoundTriggerComponent.h +++ b/dGame/dComponents/SoundTriggerComponent.h @@ -5,55 +5,73 @@ #include "Component.h" #include "eReplicaComponentType.h" -/** - * Music that should be played by the client - */ struct MusicCue { std::string name; uint32_t result; float boredomTime; + + MusicCue(std::string name, float boredomTime = -1.0, uint32_t result = 1){ + this->name = name; + this->result = result; + this->boredomTime = boredomTime; + }; + + void Serialize(RakNet::BitStream* outBitStream); }; -/** - * Handles specific music triggers like the instruments in Red Block - * Credits to https://github.com/SimonNitzsche/OpCrux-Server/blob/master/src/Entity/Components/SoundTriggerComponent.hpp - */ +struct MusicParameter { + std::string name; + float value; + + MusicParameter(std::string name, float value = 0.0){ + this->name = name; + this->value = value; + } + + void Serialize(RakNet::BitStream* outBitStream); +}; + +struct GUIDResults{ + GUID guid; + uint32_t result; + + GUIDResults(std::string guidString, uint32_t result = 1){ + this->guid = GUID(guidString); + this->result = result; + } + + void Serialize(RakNet::BitStream* outBitStream); +}; + +struct MixerProgram{ + std::string name; + uint32_t result; + + MixerProgram(std::string name, uint32_t result = 0){ + this->name = name; + this->result = result; + } + + void Serialize(RakNet::BitStream* outBitStream); +}; + + class SoundTriggerComponent : public Component { public: static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER; explicit SoundTriggerComponent(Entity* parent); - ~SoundTriggerComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - - /** - * Activates a music cue, making it played by any client in range - * @param name the name of the music to play - */ - void ActivateMusicCue(const std::string& name); - - /** - * Deactivates a music cue (if active) - * @param name name of the music to deactivate - */ + void ActivateMusicCue(const std::string& name, float bordemTime = -1.0); void DeactivateMusicCue(const std::string& name); private: - /** - * Currently active cues - */ - std::vector musicCues = {}; + std::vector m_MusicCues = {}; + std::vector m_MusicParameters = {}; + std::vector m_2DAmbientSounds = {}; + std::vector m_3DAmbientSounds = {}; + std::vector m_MixerPrograms = {}; - /** - * Currently active mixer programs - */ - std::vector mixerPrograms = {}; - - /** - * GUID found in the LDF - */ - std::vector guids = {}; - bool dirty = false; + bool m_Dirty = false; }; diff --git a/dGame/dUtilities/GUID.cpp b/dGame/dUtilities/GUID.cpp index 57f76a81..50ac8b03 100644 --- a/dGame/dUtilities/GUID.cpp +++ b/dGame/dUtilities/GUID.cpp @@ -1,6 +1,11 @@ #include "GUID.h" +namespace { + const std::string EMPTY_GUID = "{00000000-0000-0000-0000-000000000000}"; +} + GUID::GUID(const std::string& guid) { + if(guid == EMPTY_GUID) return; sscanf(guid.c_str(), "{%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx}", &this->data1, &this->data2, &this->data3, @@ -8,20 +13,13 @@ GUID::GUID(const std::string& guid) { &this->data4[4], &this->data4[5], &this->data4[6], &this->data4[7]); } -uint32_t GUID::GetData1() const { - return data1; -} - -uint16_t GUID::GetData2() const { - return data2; -} - -uint16_t GUID::GetData3() const { - return data3; -} - -std::array GUID::GetData4() const { - return data4; +void GUID::Serialize(RakNet::BitStream* outBitStream) { + outBitStream->Write(GetData1()); + outBitStream->Write(GetData2()); + outBitStream->Write(GetData3()); + for (const auto& guidSubPart : GetData4()) { + outBitStream->Write(guidSubPart); + } } GUID::GUID() = default; diff --git a/dGame/dUtilities/GUID.h b/dGame/dUtilities/GUID.h index 2d958c10..38e57a6a 100644 --- a/dGame/dUtilities/GUID.h +++ b/dGame/dUtilities/GUID.h @@ -7,10 +7,24 @@ class GUID { public: explicit GUID(); explicit GUID(const std::string& guid); - uint32_t GetData1() const; - uint16_t GetData2() const; - uint16_t GetData3() const; - std::array GetData4() const; + void Serialize(RakNet::BitStream* outBitStream); + + uint32_t GetData1() const { + return data1; + } + + uint16_t GetData2() const { + return data2; + } + + uint16_t GetData3() const { + return data3; + } + + std::array GetData4() const { + return data4; + } + private: uint32_t data1 = 0; uint16_t data2 = 0; From fe6be2100803b10f7954a28df25261ef1eca6411 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 9 Aug 2023 22:08:18 -0700 Subject: [PATCH 092/111] fix raw reading --- dNavigation/dTerrain/RawFile.cpp | 24 +++++++++++++----------- dNavigation/dTerrain/RawFile.h | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/dNavigation/dTerrain/RawFile.cpp b/dNavigation/dTerrain/RawFile.cpp index d4496b2f..dfad9ca4 100644 --- a/dNavigation/dTerrain/RawFile.cpp +++ b/dNavigation/dTerrain/RawFile.cpp @@ -32,13 +32,15 @@ RawFile::RawFile(std::string fileName) { m_Chunks.push_back(chunk); } + m_FinalMesh = new RawMesh(); + this->GenerateFinalMeshFromChunks(); } RawFile::~RawFile() { - delete m_FinalMesh; + if (m_FinalMesh) delete m_FinalMesh; for (const auto* item : m_Chunks) { - delete item; + if (item) delete item; } } @@ -49,10 +51,14 @@ void RawFile::GenerateFinalMeshFromChunks() { for (const auto& vert : chunk->m_Mesh->m_Vertices) { auto tempVert = vert; - tempVert.SetX(tempVert.GetX() + (chunk->m_X / 4)); - tempVert.SetZ(tempVert.GetZ() + (chunk->m_Z / 4)); + // Scale X and Z by the chunk's position in the world + // Scale Y by the chunk's heightmap scale factor + tempVert.SetX(tempVert.GetX() + (chunk->m_X / chunk->m_HeightMap->m_ScaleFactor)); + tempVert.SetY(tempVert.GetY() / chunk->m_HeightMap->m_ScaleFactor); + tempVert.SetZ(tempVert.GetZ() + (chunk->m_Z / chunk->m_HeightMap->m_ScaleFactor)); - tempVert* chunk->m_HeightMap->m_ScaleFactor; + // Then scale it again for some reason + tempVert *= chunk->m_HeightMap->m_ScaleFactor; m_FinalMesh->m_Vertices.push_back(tempVert); } @@ -67,16 +73,12 @@ void RawFile::GenerateFinalMeshFromChunks() { void RawFile::WriteFinalMeshToOBJ(std::string path) { std::ofstream file(path); - std::string vertData; for (const auto& v : m_FinalMesh->m_Vertices) { - vertData += "v " + std::to_string(v.x) + " " + std::to_string(v.y) + " " + std::to_string(v.z) + "\n"; + file << "v " << v.x << ' ' << v.y << ' ' << v.z << '\n'; } for (int i = 0; i < m_FinalMesh->m_Triangles.size(); i += 3) { - vertData += "f " + std::to_string(*std::next(m_FinalMesh->m_Triangles.begin(), i) + 1) + " " + std::to_string(*std::next(m_FinalMesh->m_Triangles.begin(), i + 1) + 1) + " " + std::to_string(*std::next(m_FinalMesh->m_Triangles.begin(), i + 2) + 1) + "\n"; + file << "f " << *std::next(m_FinalMesh->m_Triangles.begin(), i) + 1 << ' ' << *std::next(m_FinalMesh->m_Triangles.begin(), i + 1) + 1 << ' ' << *std::next(m_FinalMesh->m_Triangles.begin(), i + 2) + 1 << '\n'; } - - file.write(vertData.c_str(), vertData.size()); - file.close(); } diff --git a/dNavigation/dTerrain/RawFile.h b/dNavigation/dTerrain/RawFile.h index 2a702c53..b1fb4024 100644 --- a/dNavigation/dTerrain/RawFile.h +++ b/dNavigation/dTerrain/RawFile.h @@ -24,5 +24,5 @@ private: uint32_t m_Height; std::vector m_Chunks; - RawMesh* m_FinalMesh; + RawMesh* m_FinalMesh = nullptr; }; From ad81e341da474cfa9209bd59c93d4d9074259878 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 9 Aug 2023 22:13:20 -0700 Subject: [PATCH 093/111] add operator *= for vectors --- dCommon/NiPoint3.cpp | 7 +++++++ dCommon/NiPoint3.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/dCommon/NiPoint3.cpp b/dCommon/NiPoint3.cpp index 20780815..5ad06f30 100644 --- a/dCommon/NiPoint3.cpp +++ b/dCommon/NiPoint3.cpp @@ -136,6 +136,13 @@ NiPoint3& NiPoint3::operator+=(const NiPoint3& point) { return *this; } +NiPoint3& NiPoint3::operator*=(const float scalar) { + this->x *= scalar; + this->y *= scalar; + this->z *= scalar; + return *this; +} + //! Operator for subtraction of vectors NiPoint3 NiPoint3::operator-(const NiPoint3& point) const { return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z); diff --git a/dCommon/NiPoint3.h b/dCommon/NiPoint3.h index c956b654..44c3c383 100644 --- a/dCommon/NiPoint3.h +++ b/dCommon/NiPoint3.h @@ -138,6 +138,8 @@ public: //! Operator for addition of vectors NiPoint3& operator+=(const NiPoint3& point); + NiPoint3& operator*=(const float scalar); + //! Operator for subtraction of vectors NiPoint3 operator-(const NiPoint3& point) const; From 2cc13c64998a63649b8e9dcd0f5ce784444bd1df Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 10 Aug 2023 14:33:15 -0700 Subject: [PATCH 094/111] chore: Make serialize actually virtual (#1156) * Make serialize actually virtual * fix serialize and make update virutal * Update VendorComponent.h * Remove flag var * Update SoundTriggerComponent.h --------- Co-authored-by: Aaron Kimbrell --- dGame/Entity.cpp | 78 +++++++++---------- dGame/Entity.h | 1 - dGame/EntityManager.cpp | 6 -- dGame/EntityManager.h | 2 - dGame/dComponents/BaseCombatAIComponent.cpp | 2 +- dGame/dComponents/BaseCombatAIComponent.h | 2 +- dGame/dComponents/BouncerComponent.cpp | 2 +- dGame/dComponents/BouncerComponent.h | 2 +- dGame/dComponents/BuffComponent.cpp | 2 +- dGame/dComponents/BuffComponent.h | 2 +- dGame/dComponents/CharacterComponent.cpp | 2 +- dGame/dComponents/CharacterComponent.h | 2 +- dGame/dComponents/Component.cpp | 4 + dGame/dComponents/Component.h | 2 + .../ControllablePhysicsComponent.cpp | 8 +- .../ControllablePhysicsComponent.h | 3 +- dGame/dComponents/DestroyableComponent.cpp | 2 +- dGame/dComponents/DestroyableComponent.h | 2 +- dGame/dComponents/DonationVendorComponent.cpp | 4 +- dGame/dComponents/DonationVendorComponent.h | 2 +- dGame/dComponents/InventoryComponent.cpp | 6 +- dGame/dComponents/InventoryComponent.h | 3 +- dGame/dComponents/LUPExhibitComponent.cpp | 2 +- dGame/dComponents/LUPExhibitComponent.h | 2 +- .../dComponents/LevelProgressionComponent.cpp | 2 +- dGame/dComponents/LevelProgressionComponent.h | 2 +- dGame/dComponents/ModelComponent.cpp | 2 +- dGame/dComponents/ModelComponent.h | 2 +- dGame/dComponents/ModuleAssemblyComponent.cpp | 2 +- dGame/dComponents/ModuleAssemblyComponent.h | 2 +- dGame/dComponents/MovingPlatformComponent.cpp | 6 +- dGame/dComponents/MovingPlatformComponent.h | 4 +- dGame/dComponents/PetComponent.cpp | 2 +- dGame/dComponents/PetComponent.h | 2 +- dGame/dComponents/PhantomPhysicsComponent.cpp | 7 +- dGame/dComponents/PhantomPhysicsComponent.h | 3 +- .../PlayerForcedMovementComponent.cpp | 2 +- .../PlayerForcedMovementComponent.h | 2 +- dGame/dComponents/PossessableComponent.cpp | 2 +- dGame/dComponents/PossessableComponent.h | 2 +- dGame/dComponents/PossessorComponent.cpp | 2 +- dGame/dComponents/PossessorComponent.h | 2 +- dGame/dComponents/RacingControlComponent.cpp | 4 +- dGame/dComponents/RacingControlComponent.h | 4 +- dGame/dComponents/RebuildComponent.cpp | 2 +- dGame/dComponents/RebuildComponent.h | 2 +- dGame/dComponents/RenderComponent.cpp | 2 +- dGame/dComponents/RenderComponent.h | 2 +- .../RigidbodyPhantomPhysicsComponent.cpp | 2 +- .../RigidbodyPhantomPhysicsComponent.h | 2 +- .../dComponents/ScriptedActivityComponent.cpp | 2 +- dGame/dComponents/ScriptedActivityComponent.h | 2 +- .../dComponents/ShootingGalleryComponent.cpp | 2 +- dGame/dComponents/ShootingGalleryComponent.h | 2 +- dGame/dComponents/SimplePhysicsComponent.cpp | 2 +- dGame/dComponents/SimplePhysicsComponent.h | 2 +- dGame/dComponents/SkillComponent.cpp | 2 +- dGame/dComponents/SkillComponent.h | 2 +- dGame/dComponents/SoundTriggerComponent.cpp | 2 +- dGame/dComponents/SoundTriggerComponent.h | 3 +- dGame/dComponents/SwitchComponent.cpp | 2 +- dGame/dComponents/SwitchComponent.h | 2 +- dGame/dComponents/VehiclePhysicsComponent.cpp | 2 +- dGame/dComponents/VehiclePhysicsComponent.h | 2 +- dGame/dComponents/VendorComponent.cpp | 2 +- dGame/dComponents/VendorComponent.h | 4 +- dScripts/ScriptComponent.cpp | 2 +- dScripts/ScriptComponent.h | 2 +- .../DestroyableComponentTests.cpp | 4 +- 69 files changed, 113 insertions(+), 141 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 237cfa73..b5abe918 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1020,62 +1020,60 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType */ bool destroyableSerialized = false; - bool bIsInitialUpdate = false; - if (packetType == eReplicaPacketType::CONSTRUCTION) bIsInitialUpdate = true; - unsigned int flags = 0; + bool bIsInitialUpdate = packetType == eReplicaPacketType::CONSTRUCTION; PossessableComponent* possessableComponent; if (TryGetComponent(eReplicaComponentType::POSSESSABLE, possessableComponent)) { - possessableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + possessableComponent->Serialize(outBitStream, bIsInitialUpdate); } ModuleAssemblyComponent* moduleAssemblyComponent; if (TryGetComponent(eReplicaComponentType::MODULE_ASSEMBLY, moduleAssemblyComponent)) { - moduleAssemblyComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + moduleAssemblyComponent->Serialize(outBitStream, bIsInitialUpdate); } ControllablePhysicsComponent* controllablePhysicsComponent; if (TryGetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS, controllablePhysicsComponent)) { - controllablePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + controllablePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate); } SimplePhysicsComponent* simplePhysicsComponent; if (TryGetComponent(eReplicaComponentType::SIMPLE_PHYSICS, simplePhysicsComponent)) { - simplePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + simplePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate); } RigidbodyPhantomPhysicsComponent* rigidbodyPhantomPhysics; if (TryGetComponent(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS, rigidbodyPhantomPhysics)) { - rigidbodyPhantomPhysics->Serialize(outBitStream, bIsInitialUpdate, flags); + rigidbodyPhantomPhysics->Serialize(outBitStream, bIsInitialUpdate); } VehiclePhysicsComponent* vehiclePhysicsComponent; if (TryGetComponent(eReplicaComponentType::VEHICLE_PHYSICS, vehiclePhysicsComponent)) { - vehiclePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + vehiclePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate); } PhantomPhysicsComponent* phantomPhysicsComponent; if (TryGetComponent(eReplicaComponentType::PHANTOM_PHYSICS, phantomPhysicsComponent)) { - phantomPhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + phantomPhysicsComponent->Serialize(outBitStream, bIsInitialUpdate); } SoundTriggerComponent* soundTriggerComponent; if (TryGetComponent(eReplicaComponentType::SOUND_TRIGGER, soundTriggerComponent)) { - soundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + soundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate); } RacingSoundTriggerComponent* racingSoundTriggerComponent; if (TryGetComponent(eReplicaComponentType::RACING_SOUND_TRIGGER, racingSoundTriggerComponent)) { - racingSoundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + racingSoundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate); } BuffComponent* buffComponent; if (TryGetComponent(eReplicaComponentType::BUFF, buffComponent)) { - buffComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + buffComponent->Serialize(outBitStream, bIsInitialUpdate); DestroyableComponent* destroyableComponent; if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent)) { - destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + destroyableComponent->Serialize(outBitStream, bIsInitialUpdate); } destroyableSerialized = true; } @@ -1083,7 +1081,7 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType if (HasComponent(eReplicaComponentType::COLLECTIBLE)) { DestroyableComponent* destroyableComponent; if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { - destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + destroyableComponent->Serialize(outBitStream, bIsInitialUpdate); } destroyableSerialized = true; outBitStream->Write(m_CollectibleID); // Collectable component @@ -1091,7 +1089,7 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType PetComponent* petComponent; if (TryGetComponent(eReplicaComponentType::PET, petComponent)) { - petComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + petComponent->Serialize(outBitStream, bIsInitialUpdate); } CharacterComponent* characterComponent; @@ -1099,7 +1097,7 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType PossessorComponent* possessorComponent; if (TryGetComponent(eReplicaComponentType::POSSESSOR, possessorComponent)) { - possessorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + possessorComponent->Serialize(outBitStream, bIsInitialUpdate); } else { // Should never happen, but just to be safe outBitStream->Write0(); @@ -1107,7 +1105,7 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType LevelProgressionComponent* levelProgressionComponent; if (TryGetComponent(eReplicaComponentType::LEVEL_PROGRESSION, levelProgressionComponent)) { - levelProgressionComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + levelProgressionComponent->Serialize(outBitStream, bIsInitialUpdate); } else { // Should never happen, but just to be safe outBitStream->Write0(); @@ -1115,13 +1113,13 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType PlayerForcedMovementComponent* playerForcedMovementComponent; if (TryGetComponent(eReplicaComponentType::PLAYER_FORCED_MOVEMENT, playerForcedMovementComponent)) { - playerForcedMovementComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + playerForcedMovementComponent->Serialize(outBitStream, bIsInitialUpdate); } else { // Should never happen, but just to be safe outBitStream->Write0(); } - characterComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + characterComponent->Serialize(outBitStream, bIsInitialUpdate); } if (HasComponent(eReplicaComponentType::ITEM)) { @@ -1130,93 +1128,93 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType InventoryComponent* inventoryComponent; if (TryGetComponent(eReplicaComponentType::INVENTORY, inventoryComponent)) { - inventoryComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + inventoryComponent->Serialize(outBitStream, bIsInitialUpdate); } ScriptComponent* scriptComponent; if (TryGetComponent(eReplicaComponentType::SCRIPT, scriptComponent)) { - scriptComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + scriptComponent->Serialize(outBitStream, bIsInitialUpdate); } SkillComponent* skillComponent; if (TryGetComponent(eReplicaComponentType::SKILL, skillComponent)) { - skillComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + skillComponent->Serialize(outBitStream, bIsInitialUpdate); } BaseCombatAIComponent* baseCombatAiComponent; if (TryGetComponent(eReplicaComponentType::BASE_COMBAT_AI, baseCombatAiComponent)) { - baseCombatAiComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + baseCombatAiComponent->Serialize(outBitStream, bIsInitialUpdate); } RebuildComponent* rebuildComponent; if (TryGetComponent(eReplicaComponentType::QUICK_BUILD, rebuildComponent)) { DestroyableComponent* destroyableComponent; if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { - destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + destroyableComponent->Serialize(outBitStream, bIsInitialUpdate); } destroyableSerialized = true; - rebuildComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + rebuildComponent->Serialize(outBitStream, bIsInitialUpdate); } MovingPlatformComponent* movingPlatformComponent; if (TryGetComponent(eReplicaComponentType::MOVING_PLATFORM, movingPlatformComponent)) { - movingPlatformComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + movingPlatformComponent->Serialize(outBitStream, bIsInitialUpdate); } SwitchComponent* switchComponent; if (TryGetComponent(eReplicaComponentType::SWITCH, switchComponent)) { - switchComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + switchComponent->Serialize(outBitStream, bIsInitialUpdate); } VendorComponent* vendorComponent; if (TryGetComponent(eReplicaComponentType::VENDOR, vendorComponent)) { - vendorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + vendorComponent->Serialize(outBitStream, bIsInitialUpdate); } DonationVendorComponent* donationVendorComponent; if (TryGetComponent(eReplicaComponentType::DONATION_VENDOR, donationVendorComponent)) { - donationVendorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + donationVendorComponent->Serialize(outBitStream, bIsInitialUpdate); } BouncerComponent* bouncerComponent; if (TryGetComponent(eReplicaComponentType::BOUNCER, bouncerComponent)) { - bouncerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + bouncerComponent->Serialize(outBitStream, bIsInitialUpdate); } ScriptedActivityComponent* scriptedActivityComponent; if (TryGetComponent(eReplicaComponentType::SCRIPTED_ACTIVITY, scriptedActivityComponent)) { - scriptedActivityComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + scriptedActivityComponent->Serialize(outBitStream, bIsInitialUpdate); } ShootingGalleryComponent* shootingGalleryComponent; if (TryGetComponent(eReplicaComponentType::SHOOTING_GALLERY, shootingGalleryComponent)) { - shootingGalleryComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + shootingGalleryComponent->Serialize(outBitStream, bIsInitialUpdate); } RacingControlComponent* racingControlComponent; if (TryGetComponent(eReplicaComponentType::RACING_CONTROL, racingControlComponent)) { - racingControlComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + racingControlComponent->Serialize(outBitStream, bIsInitialUpdate); } LUPExhibitComponent* lupExhibitComponent; if (TryGetComponent(eReplicaComponentType::LUP_EXHIBIT, lupExhibitComponent)) { - lupExhibitComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + lupExhibitComponent->Serialize(outBitStream, bIsInitialUpdate); } ModelComponent* modelComponent; if (TryGetComponent(eReplicaComponentType::MODEL, modelComponent)) { - modelComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + modelComponent->Serialize(outBitStream, bIsInitialUpdate); } RenderComponent* renderComponent; if (TryGetComponent(eReplicaComponentType::RENDER, renderComponent)) { - renderComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + renderComponent->Serialize(outBitStream, bIsInitialUpdate); } if (modelComponent) { DestroyableComponent* destroyableComponent; if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { - destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + destroyableComponent->Serialize(outBitStream, bIsInitialUpdate); destroyableSerialized = true; } } @@ -1231,10 +1229,6 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType outBitStream->Write0(); } -void Entity::ResetFlags() { - // Unused -} - void Entity::UpdateXMLDoc(tinyxml2::XMLDocument* doc) { //This function should only ever be called from within Character, meaning doc should always exist when this is called. //Naturally, we don't include any non-player components in this update function. diff --git a/dGame/Entity.h b/dGame/Entity.h index ca007912..8680653f 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -174,7 +174,6 @@ public: void WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacketType packetType); void WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType packetType); - void ResetFlags(); void UpdateXMLDoc(tinyxml2::XMLDocument* doc); void Update(float deltaTime); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 28b5f526..699cc2a1 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -583,12 +583,6 @@ bool EntityManager::GetGhostingEnabled() const { return m_GhostingEnabled; } -void EntityManager::ResetFlags() { - for (const auto& e : m_Entities) { - e.second->ResetFlags(); - } -} - void EntityManager::ScheduleForKill(Entity* entity) { // Deactivate switches if they die if (!entity) diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 9bea0618..693a4cc0 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -59,8 +59,6 @@ public: Entity* GetGhostCandidate(int32_t id); bool GetGhostingEnabled() const; - void ResetFlags(); - void ScheduleForKill(Entity* entity); void ScheduleForDeletion(LWOOBJID entity); diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 5df43854..3afd3cc9 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -520,7 +520,7 @@ bool BaseCombatAIComponent::IsMech() { } -void BaseCombatAIComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void BaseCombatAIComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_DirtyStateOrTarget || bIsInitialUpdate); if (m_DirtyStateOrTarget || bIsInitialUpdate) { outBitStream->Write(uint32_t(m_State)); diff --git a/dGame/dComponents/BaseCombatAIComponent.h b/dGame/dComponents/BaseCombatAIComponent.h index 8bf6140a..17b74e9c 100644 --- a/dGame/dComponents/BaseCombatAIComponent.h +++ b/dGame/dComponents/BaseCombatAIComponent.h @@ -53,7 +53,7 @@ public: ~BaseCombatAIComponent() override; void Update(float deltaTime) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Get the current behavioral state of the enemy diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index bbf928dc..a9a278e8 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -22,7 +22,7 @@ BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) { BouncerComponent::~BouncerComponent() { } -void BouncerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void BouncerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_PetEnabled); if (m_PetEnabled) { outBitStream->Write(m_PetBouncerEnabled); diff --git a/dGame/dComponents/BouncerComponent.h b/dGame/dComponents/BouncerComponent.h index 15665cc1..d372f5c7 100644 --- a/dGame/dComponents/BouncerComponent.h +++ b/dGame/dComponents/BouncerComponent.h @@ -17,7 +17,7 @@ public: BouncerComponent(Entity* parentEntity); ~BouncerComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; Entity* GetParentEntity() const; diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index 68b5182c..56480438 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -20,7 +20,7 @@ BuffComponent::BuffComponent(Entity* parent) : Component(parent) { BuffComponent::~BuffComponent() { } -void BuffComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void BuffComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (!bIsInitialUpdate) return; if (m_Buffs.empty()) { outBitStream->Write0(); diff --git a/dGame/dComponents/BuffComponent.h b/dGame/dComponents/BuffComponent.h index d9175883..61e7be5d 100644 --- a/dGame/dComponents/BuffComponent.h +++ b/dGame/dComponents/BuffComponent.h @@ -54,7 +54,7 @@ public: void UpdateXml(tinyxml2::XMLDocument* doc) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 10a4e9db..d5632989 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -70,7 +70,7 @@ bool CharacterComponent::LandingAnimDisabled(int zoneID) { CharacterComponent::~CharacterComponent() { } -void CharacterComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void CharacterComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (bIsInitialUpdate) { outBitStream->Write0(); diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index c367aefc..3a5c033b 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -70,7 +70,7 @@ public: void LoadFromXml(tinyxml2::XMLDocument* doc) override; void UpdateXml(tinyxml2::XMLDocument* doc) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Updates the rocket configuration using a LOT string separated by commas diff --git a/dGame/dComponents/Component.cpp b/dGame/dComponents/Component.cpp index ca018c29..1136456c 100644 --- a/dGame/dComponents/Component.cpp +++ b/dGame/dComponents/Component.cpp @@ -28,3 +28,7 @@ void Component::UpdateXml(tinyxml2::XMLDocument* doc) { void Component::LoadFromXml(tinyxml2::XMLDocument* doc) { } + +void Component::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) { + +} diff --git a/dGame/dComponents/Component.h b/dGame/dComponents/Component.h index 9b0df9fd..c0debb0b 100644 --- a/dGame/dComponents/Component.h +++ b/dGame/dComponents/Component.h @@ -43,6 +43,8 @@ public: */ virtual void LoadFromXml(tinyxml2::XMLDocument* doc); + virtual void Serialize(RakNet::BitStream* outBitStream, bool isConstruction); + protected: /** diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index a658ccd7..de27149e 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -74,7 +74,7 @@ void ControllablePhysicsComponent::Update(float deltaTime) { } -void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { //If this is a creation, then we assume the position is dirty, even when it isn't. //This is because new clients will still need to receive the position. //if (bIsInitialUpdate) m_DirtyPosition = true; @@ -181,12 +181,6 @@ void ControllablePhysicsComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { m_DirtyPosition = true; } -void ControllablePhysicsComponent::ResetFlags() { - m_DirtyAngularVelocity = false; - m_DirtyPosition = false; - m_DirtyVelocity = false; -} - void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument* doc) { tinyxml2::XMLElement* character = doc->FirstChildElement("obj")->FirstChildElement("char"); if (!character) { diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index 470a7af4..384dfdac 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -27,9 +27,8 @@ public: ~ControllablePhysicsComponent() override; void Update(float deltaTime) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void LoadFromXml(tinyxml2::XMLDocument* doc) override; - void ResetFlags(); void UpdateXml(tinyxml2::XMLDocument* doc) override; /** diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 4c726bad..0adf62f3 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -119,7 +119,7 @@ void DestroyableComponent::Reinitialize(LOT templateID) { } } -void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags) { +void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (bIsInitialUpdate) { outBitStream->Write1(); // always write these on construction outBitStream->Write(m_ImmuneToBasicAttackCount); diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 5e5133b7..ed091066 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -24,7 +24,7 @@ public: DestroyableComponent(Entity* parentEntity); ~DestroyableComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void LoadFromXml(tinyxml2::XMLDocument* doc) override; void UpdateXml(tinyxml2::XMLDocument* doc) override; diff --git a/dGame/dComponents/DonationVendorComponent.cpp b/dGame/dComponents/DonationVendorComponent.cpp index f19ba9b7..7f85ea97 100644 --- a/dGame/dComponents/DonationVendorComponent.cpp +++ b/dGame/dComponents/DonationVendorComponent.cpp @@ -38,8 +38,8 @@ void DonationVendorComponent::SubmitDonation(uint32_t count) { m_DirtyDonationVendor = true; } -void DonationVendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - VendorComponent::Serialize(outBitStream, bIsInitialUpdate, flags); +void DonationVendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { + VendorComponent::Serialize(outBitStream, bIsInitialUpdate); outBitStream->Write(bIsInitialUpdate || m_DirtyDonationVendor); if (bIsInitialUpdate || m_DirtyDonationVendor) { outBitStream->Write(m_PercentComplete); diff --git a/dGame/dComponents/DonationVendorComponent.h b/dGame/dComponents/DonationVendorComponent.h index 6c706bf9..d1743118 100644 --- a/dGame/dComponents/DonationVendorComponent.h +++ b/dGame/dComponents/DonationVendorComponent.h @@ -10,7 +10,7 @@ class DonationVendorComponent final : public VendorComponent { public: inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DONATION_VENDOR; DonationVendorComponent(Entity* parent); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; uint32_t GetActivityID() {return m_ActivityId;}; void SubmitDonation(uint32_t count); diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 8689c0bc..3625defc 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -712,7 +712,7 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) { } } -void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool bIsInitialUpdate, unsigned& flags) { +void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool bIsInitialUpdate) { if (bIsInitialUpdate || m_Dirty) { outBitStream->Write(true); @@ -770,10 +770,6 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b outBitStream->Write(false); } -void InventoryComponent::ResetFlags() { - m_Dirty = false; -} - void InventoryComponent::Update(float deltaTime) { for (auto* set : m_Itemsets) { set->Update(deltaTime); diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index 801f9f51..ffb7a360 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -42,10 +42,9 @@ public: explicit InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document = nullptr); void Update(float deltaTime) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void LoadXml(tinyxml2::XMLDocument* document); void UpdateXml(tinyxml2::XMLDocument* document) override; - void ResetFlags(); /** * Returns an inventory of the specified type, if it exists diff --git a/dGame/dComponents/LUPExhibitComponent.cpp b/dGame/dComponents/LUPExhibitComponent.cpp index deb3cc8c..151f2897 100644 --- a/dGame/dComponents/LUPExhibitComponent.cpp +++ b/dGame/dComponents/LUPExhibitComponent.cpp @@ -38,7 +38,7 @@ void LUPExhibitComponent::NextExhibit() { Game::entityManager->SerializeEntity(m_Parent); } -void LUPExhibitComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags) { +void LUPExhibitComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write1(); // Dirty flag? outBitStream->Write(m_Exhibit); } diff --git a/dGame/dComponents/LUPExhibitComponent.h b/dGame/dComponents/LUPExhibitComponent.h index 587d1b2f..510c42fe 100644 --- a/dGame/dComponents/LUPExhibitComponent.h +++ b/dGame/dComponents/LUPExhibitComponent.h @@ -16,7 +16,7 @@ public: LUPExhibitComponent(Entity* parent); ~LUPExhibitComponent(); void Update(float deltaTime) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * After the timer runs out, this changes the currently exhibited LOT to the next one diff --git a/dGame/dComponents/LevelProgressionComponent.cpp b/dGame/dComponents/LevelProgressionComponent.cpp index 8163e736..265dd8e6 100644 --- a/dGame/dComponents/LevelProgressionComponent.cpp +++ b/dGame/dComponents/LevelProgressionComponent.cpp @@ -37,7 +37,7 @@ void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { m_CharacterVersion = static_cast(characterVersion); } -void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(bIsInitialUpdate || m_DirtyLevelInfo); if (bIsInitialUpdate || m_DirtyLevelInfo) outBitStream->Write(m_Level); m_DirtyLevelInfo = false; diff --git a/dGame/dComponents/LevelProgressionComponent.h b/dGame/dComponents/LevelProgressionComponent.h index 06908a81..17ca8117 100644 --- a/dGame/dComponents/LevelProgressionComponent.h +++ b/dGame/dComponents/LevelProgressionComponent.h @@ -21,7 +21,7 @@ public: */ LevelProgressionComponent(Entity* parent); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Save data from this componennt to character XML diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 74f614d1..ccdad281 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -8,7 +8,7 @@ ModelComponent::ModelComponent(Entity* parent) : Component(parent) { m_userModelID = m_Parent->GetVarAs(u"userModelID"); } -void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { // ItemComponent Serialization. Pets do not get this serialization. if (!m_Parent->HasComponent(eReplicaComponentType::PET)) { outBitStream->Write1(); diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index b5224869..c961bff0 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -17,7 +17,7 @@ public: ModelComponent(Entity* parent); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Returns the original position of the model diff --git a/dGame/dComponents/ModuleAssemblyComponent.cpp b/dGame/dComponents/ModuleAssemblyComponent.cpp index 8e197f0c..9089c14c 100644 --- a/dGame/dComponents/ModuleAssemblyComponent.cpp +++ b/dGame/dComponents/ModuleAssemblyComponent.cpp @@ -46,7 +46,7 @@ const std::u16string& ModuleAssemblyComponent::GetAssemblyPartsLOTs() const { return m_AssemblyPartsLOTs; } -void ModuleAssemblyComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void ModuleAssemblyComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (bIsInitialUpdate) { outBitStream->Write1(); diff --git a/dGame/dComponents/ModuleAssemblyComponent.h b/dGame/dComponents/ModuleAssemblyComponent.h index 39670c9a..6ee5f505 100644 --- a/dGame/dComponents/ModuleAssemblyComponent.h +++ b/dGame/dComponents/ModuleAssemblyComponent.h @@ -17,7 +17,7 @@ public: ModuleAssemblyComponent(Entity* parent); ~ModuleAssemblyComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; /** diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index f4dcdbe9..60d320f4 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -32,7 +32,7 @@ MoverSubComponent::MoverSubComponent(const NiPoint3& startPos) { MoverSubComponent::~MoverSubComponent() = default; -void MoverSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) const { +void MoverSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(true); outBitStream->Write(static_cast(mState)); @@ -71,7 +71,7 @@ MovingPlatformComponent::~MovingPlatformComponent() { delete static_cast(m_MoverSubComponent); } -void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { // Here we don't serialize the moving platform to let the client simulate the movement if (!m_Serialize) { @@ -112,7 +112,7 @@ void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bI if (m_MoverSubComponentType == eMoverSubComponentType::simpleMover) { // TODO } else { - mover->Serialize(outBitStream, bIsInitialUpdate, flags); + mover->Serialize(outBitStream, bIsInitialUpdate); } } } diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 9e4c1ecf..bb83a538 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -38,7 +38,7 @@ public: MoverSubComponent(const NiPoint3& startPos); ~MoverSubComponent(); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) const; + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate); /** * The state the platform is currently in @@ -111,7 +111,7 @@ public: MovingPlatformComponent(Entity* parent, const std::string& pathName); ~MovingPlatformComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Stops all pathing, called when an entity starts a quick build associated with this platform diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 7df08c60..5132af08 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -107,7 +107,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare result.finalize(); } -void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { const bool tamed = m_Owner != LWOOBJID_EMPTY; outBitStream->Write1(); // Always serialize as dirty for now diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index b3d089a9..4ca6a49e 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -26,7 +26,7 @@ public: explicit PetComponent(Entity* parentEntity, uint32_t componentId); ~PetComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; /** diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index 640281f8..866543b3 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -306,7 +306,7 @@ void PhantomPhysicsComponent::CreatePhysics() { m_HasCreatedPhysics = true; } -void PhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void PhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_PositionInfoDirty || bIsInitialUpdate); if (m_PositionInfoDirty || bIsInitialUpdate) { outBitStream->Write(m_Position.x); @@ -348,11 +348,6 @@ void PhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI } } -void PhantomPhysicsComponent::ResetFlags() { - m_EffectInfoDirty = false; - m_PositionInfoDirty = false; -} - void PhantomPhysicsComponent::Update(float deltaTime) { if (!m_dpEntity) return; diff --git a/dGame/dComponents/PhantomPhysicsComponent.h b/dGame/dComponents/PhantomPhysicsComponent.h index cc0d1844..e5769f40 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.h +++ b/dGame/dComponents/PhantomPhysicsComponent.h @@ -32,8 +32,7 @@ public: PhantomPhysicsComponent(Entity* parent); ~PhantomPhysicsComponent() override; void Update(float deltaTime) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - void ResetFlags(); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Creates the physics shape for this entity based on LDF data diff --git a/dGame/dComponents/PlayerForcedMovementComponent.cpp b/dGame/dComponents/PlayerForcedMovementComponent.cpp index 76993507..d511ad78 100644 --- a/dGame/dComponents/PlayerForcedMovementComponent.cpp +++ b/dGame/dComponents/PlayerForcedMovementComponent.cpp @@ -6,7 +6,7 @@ PlayerForcedMovementComponent::PlayerForcedMovementComponent(Entity* parent) : C PlayerForcedMovementComponent::~PlayerForcedMovementComponent() {} -void PlayerForcedMovementComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void PlayerForcedMovementComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_DirtyInfo || bIsInitialUpdate); if (m_DirtyInfo || bIsInitialUpdate) { outBitStream->Write(m_PlayerOnRail); diff --git a/dGame/dComponents/PlayerForcedMovementComponent.h b/dGame/dComponents/PlayerForcedMovementComponent.h index 90708c9a..43781bab 100644 --- a/dGame/dComponents/PlayerForcedMovementComponent.h +++ b/dGame/dComponents/PlayerForcedMovementComponent.h @@ -19,7 +19,7 @@ public: PlayerForcedMovementComponent(Entity* parent); ~PlayerForcedMovementComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * @brief Set the Player On Rail object diff --git a/dGame/dComponents/PossessableComponent.cpp b/dGame/dComponents/PossessableComponent.cpp index 5c45a6c1..509b1a07 100644 --- a/dGame/dComponents/PossessableComponent.cpp +++ b/dGame/dComponents/PossessableComponent.cpp @@ -27,7 +27,7 @@ PossessableComponent::PossessableComponent(Entity* parent, uint32_t componentId) result.finalize(); } -void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_DirtyPossessable || bIsInitialUpdate); if (m_DirtyPossessable || bIsInitialUpdate) { m_DirtyPossessable = false; // reset flag diff --git a/dGame/dComponents/PossessableComponent.h b/dGame/dComponents/PossessableComponent.h index 2026c11e..be60bb77 100644 --- a/dGame/dComponents/PossessableComponent.h +++ b/dGame/dComponents/PossessableComponent.h @@ -18,7 +18,7 @@ public: PossessableComponent(Entity* parentEntity, uint32_t componentId); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * @brief mounts the Entity diff --git a/dGame/dComponents/PossessorComponent.cpp b/dGame/dComponents/PossessorComponent.cpp index 8019f91c..0cb64956 100644 --- a/dGame/dComponents/PossessorComponent.cpp +++ b/dGame/dComponents/PossessorComponent.cpp @@ -26,7 +26,7 @@ PossessorComponent::~PossessorComponent() { } } -void PossessorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void PossessorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_DirtyPossesor || bIsInitialUpdate); if (m_DirtyPossesor || bIsInitialUpdate) { m_DirtyPossesor = false; diff --git a/dGame/dComponents/PossessorComponent.h b/dGame/dComponents/PossessorComponent.h index 4456af27..d21695f0 100644 --- a/dGame/dComponents/PossessorComponent.h +++ b/dGame/dComponents/PossessorComponent.h @@ -23,7 +23,7 @@ public: PossessorComponent(Entity* parent); ~PossessorComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * @brief Mounts the entity diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 5de24445..7a4d98ea 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -424,9 +424,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu } } -void RacingControlComponent::Serialize(RakNet::BitStream* outBitStream, - bool bIsInitialUpdate, - unsigned int& flags) { +void RacingControlComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { // BEGIN Scripted Activity outBitStream->Write1(); diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index a81121e1..c713a759 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -110,8 +110,8 @@ public: RacingControlComponent(Entity* parentEntity); ~RacingControlComponent(); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - void Update(float deltaTime); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; + void Update(float deltaTime) override; /** * Invoked when a player loads into the zone. diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index e669489d..3f38c275 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -57,7 +57,7 @@ RebuildComponent::~RebuildComponent() { DespawnActivator(); } -void RebuildComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void RebuildComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (m_Parent->GetComponent(eReplicaComponentType::DESTROYABLE) == nullptr) { if (bIsInitialUpdate) { outBitStream->Write(false); diff --git a/dGame/dComponents/RebuildComponent.h b/dGame/dComponents/RebuildComponent.h index 09dd0465..cd266c1f 100644 --- a/dGame/dComponents/RebuildComponent.h +++ b/dGame/dComponents/RebuildComponent.h @@ -27,7 +27,7 @@ public: RebuildComponent(Entity* entity); ~RebuildComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; /** diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index 94f5fb5d..44663a17 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -54,7 +54,7 @@ RenderComponent::~RenderComponent() { m_Effects.clear(); } -void RenderComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void RenderComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (!bIsInitialUpdate) return; outBitStream->Write(m_Effects.size()); diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index cdf32160..24cfd16d 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -61,7 +61,7 @@ public: RenderComponent(Entity* entity, int32_t componentId = -1); ~RenderComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; /** diff --git a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.cpp b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.cpp index babd1974..5390db3a 100644 --- a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.cpp +++ b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.cpp @@ -15,7 +15,7 @@ RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* paren RigidbodyPhantomPhysicsComponent::~RigidbodyPhantomPhysicsComponent() { } -void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_IsDirty || bIsInitialUpdate); if (m_IsDirty || bIsInitialUpdate) { outBitStream->Write(m_Position.x); diff --git a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h index 480f9b81..ba6a54a0 100644 --- a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h +++ b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h @@ -24,7 +24,7 @@ public: RigidbodyPhantomPhysicsComponent(Entity* parent); ~RigidbodyPhantomPhysicsComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Returns the position of this entity diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 81b3e9a9..e971aa30 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -82,7 +82,7 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit ScriptedActivityComponent::~ScriptedActivityComponent() = default; -void ScriptedActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) const { +void ScriptedActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(true); outBitStream->Write(m_ActivityPlayers.size()); diff --git a/dGame/dComponents/ScriptedActivityComponent.h b/dGame/dComponents/ScriptedActivityComponent.h index 1d49a62d..455ac667 100644 --- a/dGame/dComponents/ScriptedActivityComponent.h +++ b/dGame/dComponents/ScriptedActivityComponent.h @@ -162,7 +162,7 @@ public: ~ScriptedActivityComponent() override; void Update(float deltaTime) override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) const; + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Makes some entity join the minigame, if it's a lobbied one, the entity will be placed in the lobby diff --git a/dGame/dComponents/ShootingGalleryComponent.cpp b/dGame/dComponents/ShootingGalleryComponent.cpp index ed91ac96..92208598 100644 --- a/dGame/dComponents/ShootingGalleryComponent.cpp +++ b/dGame/dComponents/ShootingGalleryComponent.cpp @@ -17,7 +17,7 @@ void ShootingGalleryComponent::SetDynamicParams(const DynamicShootingGalleryPara Game::entityManager->SerializeEntity(m_Parent); } -void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate, uint32_t& flags) const { +void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate) { // Start ScriptedActivityComponent outBitStream->Write(true); if (m_CurrentPlayerID == LWOOBJID_EMPTY) { diff --git a/dGame/dComponents/ShootingGalleryComponent.h b/dGame/dComponents/ShootingGalleryComponent.h index c31575f1..bc1aa090 100644 --- a/dGame/dComponents/ShootingGalleryComponent.h +++ b/dGame/dComponents/ShootingGalleryComponent.h @@ -77,7 +77,7 @@ public: explicit ShootingGalleryComponent(Entity* parent); ~ShootingGalleryComponent(); - void Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate, uint32_t& flags) const; + void Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate) override; /** * Returns the static params for the shooting gallery diff --git a/dGame/dComponents/SimplePhysicsComponent.cpp b/dGame/dComponents/SimplePhysicsComponent.cpp index 54a2e616..3cd95169 100644 --- a/dGame/dComponents/SimplePhysicsComponent.cpp +++ b/dGame/dComponents/SimplePhysicsComponent.cpp @@ -33,7 +33,7 @@ SimplePhysicsComponent::SimplePhysicsComponent(uint32_t componentID, Entity* par SimplePhysicsComponent::~SimplePhysicsComponent() { } -void SimplePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void SimplePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (bIsInitialUpdate) { outBitStream->Write(m_ClimbableType != eClimbableType::CLIMBABLE_TYPE_NOT); outBitStream->Write(m_ClimbableType); diff --git a/dGame/dComponents/SimplePhysicsComponent.h b/dGame/dComponents/SimplePhysicsComponent.h index 51356710..4908c8ef 100644 --- a/dGame/dComponents/SimplePhysicsComponent.h +++ b/dGame/dComponents/SimplePhysicsComponent.h @@ -33,7 +33,7 @@ public: SimplePhysicsComponent(uint32_t componentID, Entity* parent); ~SimplePhysicsComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Returns the position of this entity diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 5c1d221a..c32e1b43 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -485,7 +485,7 @@ SkillComponent::~SkillComponent() { Reset(); } -void SkillComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void SkillComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (bIsInitialUpdate) outBitStream->Write0(); } diff --git a/dGame/dComponents/SkillComponent.h b/dGame/dComponents/SkillComponent.h index 034e65ce..b157ad3d 100644 --- a/dGame/dComponents/SkillComponent.h +++ b/dGame/dComponents/SkillComponent.h @@ -64,7 +64,7 @@ public: explicit SkillComponent(Entity* parent); ~SkillComponent() override; - static void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Computes skill updates. Invokes CalculateUpdate. diff --git a/dGame/dComponents/SoundTriggerComponent.cpp b/dGame/dComponents/SoundTriggerComponent.cpp index 823d3ff4..dc7355db 100644 --- a/dGame/dComponents/SoundTriggerComponent.cpp +++ b/dGame/dComponents/SoundTriggerComponent.cpp @@ -55,7 +55,7 @@ SoundTriggerComponent::SoundTriggerComponent(Entity* parent) : Component(parent) if (!mixerName.empty()) this->m_MixerPrograms.push_back(MixerProgram(mixerName)); } -void SoundTriggerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void SoundTriggerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(this->m_Dirty || bIsInitialUpdate); if (this->m_Dirty || bIsInitialUpdate) { outBitStream->Write(this->m_MusicCues.size()); diff --git a/dGame/dComponents/SoundTriggerComponent.h b/dGame/dComponents/SoundTriggerComponent.h index 6d42a2e3..3873d6ed 100644 --- a/dGame/dComponents/SoundTriggerComponent.h +++ b/dGame/dComponents/SoundTriggerComponent.h @@ -59,9 +59,8 @@ struct MixerProgram{ class SoundTriggerComponent : public Component { public: static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER; - explicit SoundTriggerComponent(Entity* parent); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void ActivateMusicCue(const std::string& name, float bordemTime = -1.0); void DeactivateMusicCue(const std::string& name); diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index eee54342..41dff9f5 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -21,7 +21,7 @@ SwitchComponent::~SwitchComponent() { } } -void SwitchComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void SwitchComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_Active); } diff --git a/dGame/dComponents/SwitchComponent.h b/dGame/dComponents/SwitchComponent.h index fde3cfc0..f262f44c 100644 --- a/dGame/dComponents/SwitchComponent.h +++ b/dGame/dComponents/SwitchComponent.h @@ -25,7 +25,7 @@ public: Entity* GetParentEntity() const; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Sets whether the switch is on or off. diff --git a/dGame/dComponents/VehiclePhysicsComponent.cpp b/dGame/dComponents/VehiclePhysicsComponent.cpp index 684b135b..79b6cc82 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.cpp +++ b/dGame/dComponents/VehiclePhysicsComponent.cpp @@ -72,7 +72,7 @@ void VehiclePhysicsComponent::SetDirtyAngularVelocity(bool val) { m_DirtyAngularVelocity = val; } -void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(bIsInitialUpdate || m_DirtyPosition); if (bIsInitialUpdate || m_DirtyPosition) { diff --git a/dGame/dComponents/VehiclePhysicsComponent.h b/dGame/dComponents/VehiclePhysicsComponent.h index e314bef1..602fc135 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.h +++ b/dGame/dComponents/VehiclePhysicsComponent.h @@ -33,7 +33,7 @@ public: VehiclePhysicsComponent(Entity* parentEntity); ~VehiclePhysicsComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index 245ea9b1..e5e0f3d8 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -16,7 +16,7 @@ VendorComponent::VendorComponent(Entity* parent) : Component(parent) { RefreshInventory(true); } -void VendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void VendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(bIsInitialUpdate || m_DirtyVendor); if (bIsInitialUpdate || m_DirtyVendor) { outBitStream->Write(m_HasStandardCostItems); diff --git a/dGame/dComponents/VendorComponent.h b/dGame/dComponents/VendorComponent.h index 4a9b582e..7924a928 100644 --- a/dGame/dComponents/VendorComponent.h +++ b/dGame/dComponents/VendorComponent.h @@ -22,7 +22,9 @@ class VendorComponent : public Component { public: inline static const eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR; VendorComponent(Entity* parent); - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; + void OnUse(Entity* originator) override; void RefreshInventory(bool isCreation = false); void SetupConstants(); diff --git a/dScripts/ScriptComponent.cpp b/dScripts/ScriptComponent.cpp index 272de5ab..2079d67a 100644 --- a/dScripts/ScriptComponent.cpp +++ b/dScripts/ScriptComponent.cpp @@ -17,7 +17,7 @@ ScriptComponent::~ScriptComponent() { } -void ScriptComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { +void ScriptComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { if (bIsInitialUpdate) { const auto& networkSettings = m_Parent->GetNetworkSettings(); auto hasNetworkSettings = !networkSettings.empty(); diff --git a/dScripts/ScriptComponent.h b/dScripts/ScriptComponent.h index 77dff5bf..98925eb4 100644 --- a/dScripts/ScriptComponent.h +++ b/dScripts/ScriptComponent.h @@ -24,7 +24,7 @@ public: ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client = false); ~ScriptComponent() override; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; /** * Returns the script that's attached to this entity diff --git a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp index db9c033a..85507b4e 100644 --- a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp @@ -41,7 +41,7 @@ protected: * Test Construction of a DestroyableComponent */ TEST_F(DestroyableTest, DestroyableComponentSerializeConstructionTest) { - destroyableComponent->Serialize(&bitStream, true, flags); + destroyableComponent->Serialize(&bitStream, true); // Assert that the full number of bits are present ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 748); { @@ -171,7 +171,7 @@ TEST_F(DestroyableTest, DestroyableComponentSerializeTest) { destroyableComponent->SetMaxHealth(1233.0f); // Now we test a serialization for correctness. - destroyableComponent->Serialize(&bitStream, false, flags); + destroyableComponent->Serialize(&bitStream, false); ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 422); { // Now read in the full serialized BitStream From beaceb947b74836def684448ab1a6d766c52a866 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 10 Aug 2023 16:35:12 -0500 Subject: [PATCH 095/111] fix: Properly read in scene metadata (#1170) * fix: Properly read in scene metadata * Fix reading in rental time and period from property path * remove useless name in var change hex to decimal so it's readable fix scene transistion loop logic * fix typoe and remove whitespace --- dZoneManager/Zone.cpp | 57 ++++++++++++++++++++++++------------------- dZoneManager/Zone.h | 36 ++++++++++++++++----------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 6b153706..99fbd6ff 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -54,22 +54,22 @@ void Zone::LoadZoneIntoMemory() { std::istream file(&buffer); if (file) { - BinaryIO::BinaryRead(file, m_ZoneFileFormatVersion); + BinaryIO::BinaryRead(file, m_FileFormatVersion); uint32_t mapRevision = 0; - if (m_ZoneFileFormatVersion >= Zone::ZoneFileFormatVersion::Alpha) BinaryIO::BinaryRead(file, mapRevision); + if (m_FileFormatVersion >= Zone::FileFormatVersion::Alpha) BinaryIO::BinaryRead(file, mapRevision); BinaryIO::BinaryRead(file, m_WorldID); if ((uint16_t)m_WorldID != m_ZoneID.GetMapID()) Game::logger->Log("Zone", "WorldID: %i doesn't match MapID %i! Is this intended?", m_WorldID, m_ZoneID.GetMapID()); AddRevision(LWOSCENEID_INVALID, mapRevision); - if (m_ZoneFileFormatVersion >= Zone::ZoneFileFormatVersion::Beta) { + if (m_FileFormatVersion >= Zone::FileFormatVersion::Beta) { BinaryIO::BinaryRead(file, m_Spawnpoint); BinaryIO::BinaryRead(file, m_SpawnpointRotation); } - if (m_ZoneFileFormatVersion <= Zone::ZoneFileFormatVersion::LateAlpha) { + if (m_FileFormatVersion <= Zone::FileFormatVersion::LateAlpha) { uint8_t sceneCount; BinaryIO::BinaryRead(file, sceneCount); m_SceneCount = sceneCount; @@ -93,14 +93,14 @@ void Zone::LoadZoneIntoMemory() { BinaryIO::BinaryRead(file, stringLength); m_ZoneDesc = BinaryIO::ReadString(file, stringLength); - if (m_ZoneFileFormatVersion >= Zone::ZoneFileFormatVersion::PreAlpha) { + if (m_FileFormatVersion >= Zone::FileFormatVersion::PreAlpha) { BinaryIO::BinaryRead(file, m_NumberOfSceneTransitionsLoaded); for (uint32_t i = 0; i < m_NumberOfSceneTransitionsLoaded; ++i) { LoadSceneTransition(file); } } - if (m_ZoneFileFormatVersion >= Zone::ZoneFileFormatVersion::EarlyAlpha) { + if (m_FileFormatVersion >= Zone::FileFormatVersion::EarlyAlpha) { BinaryIO::BinaryRead(file, m_PathDataLength); BinaryIO::BinaryRead(file, m_PathChunkVersion); // always should be 1 @@ -244,16 +244,29 @@ void Zone::LoadScene(std::istream& file) { scene.triggers.insert({ trigger->id, trigger }); } - BinaryIO::BinaryRead(file, scene.id); - BinaryIO::BinaryRead(file, scene.sceneType); - lwoSceneID.SetSceneID(scene.id); + if (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha || m_FileFormatVersion < Zone::FileFormatVersion::PrePreAlpha) { + BinaryIO::BinaryRead(file, scene.id); + lwoSceneID.SetSceneID(scene.id); + } + if (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha) { + BinaryIO::BinaryRead(file, scene.sceneType); + lwoSceneID.SetLayerID(scene.sceneType); - uint8_t sceneNameLength; - BinaryIO::BinaryRead(file, sceneNameLength); - scene.name = BinaryIO::ReadString(file, sceneNameLength); - file.ignore(3); + uint8_t sceneNameLength; + BinaryIO::BinaryRead(file, sceneNameLength); + scene.name = BinaryIO::ReadString(file, sceneNameLength); + } - lwoSceneID.SetLayerID(scene.sceneType); + if (m_FileFormatVersion == Zone::FileFormatVersion::LatePreAlpha){ + BinaryIO::BinaryRead(file, scene.unknown1); + BinaryIO::BinaryRead(file, scene.unknown2); + } + + if (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha) { + BinaryIO::BinaryRead(file, scene.color_r); + BinaryIO::BinaryRead(file, scene.color_b); + BinaryIO::BinaryRead(file, scene.color_g); + } m_Scenes.insert(std::make_pair(lwoSceneID, scene)); m_NumberOfScenesLoaded++; @@ -345,7 +358,7 @@ const Path* Zone::GetPath(std::string name) const { void Zone::LoadSceneTransition(std::istream& file) { SceneTransition sceneTrans; - if (m_ZoneFileFormatVersion < Zone::ZoneFileFormatVersion::Auramar) { + if (m_FileFormatVersion < Zone::FileFormatVersion::Auramar) { uint8_t length; BinaryIO::BinaryRead(file, length); sceneTrans.name = BinaryIO::ReadString(file, length); @@ -353,7 +366,7 @@ void Zone::LoadSceneTransition(std::istream& file) { } //BR�THER MAY I HAVE SOME L��PS? - uint8_t loops = (m_ZoneFileFormatVersion < Zone::ZoneFileFormatVersion::EarlyAlpha || m_ZoneFileFormatVersion >= Zone::ZoneFileFormatVersion::Launch) ? 2 : 5; + uint8_t loops = (m_FileFormatVersion <= Zone::FileFormatVersion::LatePreAlpha || m_FileFormatVersion >= Zone::FileFormatVersion::Launch) ? 2 : 5; for (uint8_t i = 0; i < loops; ++i) { sceneTrans.points.push_back(LoadSceneTransitionInfo(file)); @@ -401,7 +414,7 @@ void Zone::LoadPath(std::istream& file) { } else if (path.pathType == PathType::Property) { BinaryIO::BinaryRead(file, path.property.pathType); BinaryIO::BinaryRead(file, path.property.price); - BinaryIO::BinaryRead(file, path.property.rentalTimeUnit); + BinaryIO::BinaryRead(file, path.property.rentalTime); BinaryIO::BinaryRead(file, path.property.associatedZone); if (path.pathVersion >= 5) { @@ -426,14 +439,12 @@ void Zone::LoadPath(std::istream& file) { if (path.pathVersion >= 7) { BinaryIO::BinaryRead(file, path.property.cloneLimit); BinaryIO::BinaryRead(file, path.property.repMultiplier); - BinaryIO::BinaryRead(file, path.property.rentalTimeUnit); + BinaryIO::BinaryRead(file, path.property.rentalPeriod); } if (path.pathVersion >= 8) { BinaryIO::BinaryRead(file, path.property.achievementRequired); - BinaryIO::BinaryRead(file, path.property.playerZoneCoords.x); - BinaryIO::BinaryRead(file, path.property.playerZoneCoords.y); - BinaryIO::BinaryRead(file, path.property.playerZoneCoords.z); + BinaryIO::BinaryRead(file, path.property.playerZoneCoords); BinaryIO::BinaryRead(file, path.property.maxBuildHeight); } } else if (path.pathType == PathType::Camera) { @@ -543,11 +554,7 @@ void Zone::LoadPath(std::istream& file) { if (ldfConfig) waypoint.config.push_back(ldfConfig); } } - path.pathWaypoints.push_back(waypoint); } - - - m_Paths.push_back(path); } diff --git a/dZoneManager/Zone.h b/dZoneManager/Zone.h index b3e72036..af9f6b55 100644 --- a/dZoneManager/Zone.h +++ b/dZoneManager/Zone.h @@ -18,6 +18,11 @@ struct SceneRef { uint32_t id; uint32_t sceneType; //0 = general, 1 = audio? std::string name; + NiPoint3 unknown1; + float unknown2; + uint8_t color_r; + uint8_t color_g; + uint8_t color_b; Level* level; std::map triggers; }; @@ -101,7 +106,7 @@ enum class PropertyType : int32_t { Headspace = 3 }; -enum class PropertyRentalTimeUnit : int32_t { +enum class PropertyRentalPeriod : uint32_t { Forever = 0, Seconds = 1, Minutes = 2, @@ -112,7 +117,7 @@ enum class PropertyRentalTimeUnit : int32_t { Years = 7 }; -enum class PropertyAchievmentRequired : int32_t { +enum class PropertyAchievmentRequired : uint32_t { None = 0, Builder = 1, Craftsman = 2, @@ -134,13 +139,14 @@ struct MovingPlatformPath { struct PropertyPath { PropertyPathType pathType; int32_t price; - PropertyRentalTimeUnit rentalTimeUnit; + uint32_t rentalTime; uint64_t associatedZone; std::string displayName; std::string displayDesc; PropertyType type; - int32_t cloneLimit; + uint32_t cloneLimit; float repMultiplier; + PropertyRentalPeriod rentalPeriod; PropertyAchievmentRequired achievementRequired; NiPoint3 playerZoneCoords; float maxBuildHeight; @@ -177,15 +183,17 @@ struct Path { class Zone { public: - enum class ZoneFileFormatVersion : uint32_t { //Times are guessed. - PreAlpha = 0x20, - EarlyAlpha = 0x23, - Alpha = 0x24, - LateAlpha = 0x25, - Beta = 0x26, - Launch = 0x27, - Auramar = 0x28, - Latest = 0x29 + enum class FileFormatVersion : uint32_t { //Times are guessed. + PrePreAlpha = 30, + PreAlpha = 32, + LatePreAlpha = 33, + EarlyAlpha = 35, + Alpha = 36, + LateAlpha = 37, + Beta = 38, + Launch = 39, + Auramar = 40, + Latest = 41 }; public: @@ -221,7 +229,7 @@ private: uint32_t m_NumberOfScenesLoaded; uint32_t m_NumberOfObjectsLoaded; uint32_t m_NumberOfSceneTransitionsLoaded; - ZoneFileFormatVersion m_ZoneFileFormatVersion; + FileFormatVersion m_FileFormatVersion; uint32_t m_CheckSum; uint32_t m_WorldID; //should be equal to the MapID NiPoint3 m_Spawnpoint; From 5eca25e42a41129641169f6b45e94abba9bb9dbe Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 10 Aug 2023 21:27:40 -0700 Subject: [PATCH 096/111] refactor: Move CDClient Database away from constructor queries (#1164) * Move away from constructor queries Fix up other large tables to have proper backup lookups Revert "idk im just dumb ig" This reverts commit 5d5be5df53b8959b42b291613d7db749a65a3585. idk im just dumb ig * Fix slow components registry lookup * add define for cdclient cache all * Update CDBehaviorParameterTable.cpp --- CMakeVariables.txt | 2 + dDatabase/CDClientDatabase.h | 10 +- dDatabase/CDClientManager.cpp | 86 ++++++++------ dDatabase/Tables/CDActivitiesTable.cpp | 8 +- dDatabase/Tables/CDActivitiesTable.h | 5 +- dDatabase/Tables/CDActivityRewardsTable.cpp | 7 +- dDatabase/Tables/CDActivityRewardsTable.h | 4 +- dDatabase/Tables/CDAnimationsTable.cpp | 29 +++++ dDatabase/Tables/CDAnimationsTable.h | 1 + dDatabase/Tables/CDBehaviorParameterTable.cpp | 18 +-- dDatabase/Tables/CDBehaviorParameterTable.h | 2 +- dDatabase/Tables/CDBehaviorTemplateTable.cpp | 5 +- dDatabase/Tables/CDBehaviorTemplateTable.h | 5 +- dDatabase/Tables/CDBrickIDTableTable.cpp | 4 +- dDatabase/Tables/CDBrickIDTableTable.h | 4 +- .../Tables/CDComponentsRegistryTable.cpp | 109 ++++++------------ dDatabase/Tables/CDComponentsRegistryTable.h | 4 +- dDatabase/Tables/CDCurrencyTableTable.cpp | 4 +- dDatabase/Tables/CDCurrencyTableTable.h | 4 +- .../Tables/CDDestructibleComponentTable.cpp | 6 +- .../Tables/CDDestructibleComponentTable.h | 4 +- dDatabase/Tables/CDEmoteTable.cpp | 40 +++---- dDatabase/Tables/CDEmoteTable.h | 5 +- dDatabase/Tables/CDFeatureGatingTable.cpp | 5 +- dDatabase/Tables/CDFeatureGatingTable.h | 5 +- .../Tables/CDInventoryComponentTable.cpp | 5 +- dDatabase/Tables/CDInventoryComponentTable.h | 4 +- dDatabase/Tables/CDItemComponentTable.cpp | 22 ++-- dDatabase/Tables/CDItemComponentTable.h | 2 +- dDatabase/Tables/CDItemSetSkillsTable.cpp | 5 +- dDatabase/Tables/CDItemSetSkillsTable.h | 4 +- dDatabase/Tables/CDItemSetsTable.cpp | 5 +- dDatabase/Tables/CDItemSetsTable.h | 4 +- .../Tables/CDLevelProgressionLookupTable.cpp | 7 +- .../Tables/CDLevelProgressionLookupTable.h | 6 +- dDatabase/Tables/CDLootMatrixTable.cpp | 5 +- dDatabase/Tables/CDLootMatrixTable.h | 4 +- dDatabase/Tables/CDLootTableTable.cpp | 5 +- dDatabase/Tables/CDLootTableTable.h | 4 +- dDatabase/Tables/CDMissionEmailTable.cpp | 5 +- dDatabase/Tables/CDMissionEmailTable.h | 4 +- .../Tables/CDMissionNPCComponentTable.cpp | 5 +- dDatabase/Tables/CDMissionNPCComponentTable.h | 4 +- dDatabase/Tables/CDMissionTasksTable.cpp | 9 +- dDatabase/Tables/CDMissionTasksTable.h | 4 +- dDatabase/Tables/CDMissionsTable.cpp | 3 +- dDatabase/Tables/CDMissionsTable.h | 4 +- .../Tables/CDMovementAIComponentTable.cpp | 7 +- dDatabase/Tables/CDMovementAIComponentTable.h | 4 +- dDatabase/Tables/CDObjectSkillsTable.cpp | 7 +- dDatabase/Tables/CDObjectSkillsTable.h | 4 +- dDatabase/Tables/CDObjectsTable.cpp | 34 +++--- dDatabase/Tables/CDObjectsTable.h | 2 +- dDatabase/Tables/CDPackageComponentTable.cpp | 5 +- dDatabase/Tables/CDPackageComponentTable.h | 4 +- dDatabase/Tables/CDPhysicsComponentTable.cpp | 37 +++--- dDatabase/Tables/CDPhysicsComponentTable.h | 5 +- .../CDPropertyEntranceComponentTable.cpp | 3 +- .../Tables/CDPropertyEntranceComponentTable.h | 4 +- dDatabase/Tables/CDPropertyTemplateTable.cpp | 2 +- dDatabase/Tables/CDPropertyTemplateTable.h | 2 +- .../CDProximityMonitorComponentTable.cpp | 7 +- .../Tables/CDProximityMonitorComponentTable.h | 4 +- dDatabase/Tables/CDRailActivatorComponent.cpp | 4 +- dDatabase/Tables/CDRailActivatorComponent.h | 4 +- dDatabase/Tables/CDRarityTableTable.cpp | 5 +- dDatabase/Tables/CDRarityTableTable.h | 2 +- dDatabase/Tables/CDRebuildComponentTable.cpp | 7 +- dDatabase/Tables/CDRebuildComponentTable.h | 4 +- dDatabase/Tables/CDRewardsTable.cpp | 32 ++--- dDatabase/Tables/CDRewardsTable.h | 7 +- dDatabase/Tables/CDScriptComponentTable.cpp | 3 +- dDatabase/Tables/CDScriptComponentTable.h | 2 +- dDatabase/Tables/CDSkillBehaviorTable.cpp | 11 +- dDatabase/Tables/CDSkillBehaviorTable.h | 4 +- dDatabase/Tables/CDVendorComponentTable.cpp | 5 +- dDatabase/Tables/CDVendorComponentTable.h | 4 +- dDatabase/Tables/CDZoneTableTable.cpp | 3 +- dDatabase/Tables/CDZoneTableTable.h | 2 +- .../dComponents/LevelProgressionComponent.cpp | 10 +- 80 files changed, 312 insertions(+), 424 deletions(-) diff --git a/CMakeVariables.txt b/CMakeVariables.txt index 67b78aac..732a615b 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -18,3 +18,5 @@ __maria_db_connector_compile_jobs__=1 __enable_testing__=1 # The path to OpenSSL. Change this if your OpenSSL install path is different than the default. OPENSSL_ROOT_DIR=/usr/local/opt/openssl@3/ +# Uncomment the below line to cache the entire CDClient into memory +# CDCLIENT_CACHE_ALL=1 diff --git a/dDatabase/CDClientDatabase.h b/dDatabase/CDClientDatabase.h index 59f69b7d..7f42918d 100644 --- a/dDatabase/CDClientDatabase.h +++ b/dDatabase/CDClientDatabase.h @@ -13,15 +13,7 @@ #include #include - // Enable this to cache all entries in each table for fast access, comes with more memory cost - //#define CDCLIENT_CACHE_ALL - -/*! - \file CDClientDatabase.hpp - \brief An interface between the CDClient.sqlite file and the server - */ - - //! The CDClient Database namespace +//! The CDClient Database namespace namespace CDClientDatabase { //! Opens a connection with the CDClient diff --git a/dDatabase/CDClientManager.cpp b/dDatabase/CDClientManager.cpp index 9df6ff31..32a6a5b1 100644 --- a/dDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientManager.cpp @@ -38,43 +38,53 @@ #include "CDFeatureGatingTable.h" #include "CDRailActivatorComponent.h" +// Uncomment this to cache the full cdclient database into memory. This will make the server load faster, but will use more memory. +// A vanilla CDClient takes about 46MB of memory + the regular world data. +// #define CDCLIENT_CACHE_ALL + +#ifdef CDCLIENT_CACHE_ALL + #define CDCLIENT_DONT_CACHE_TABLE(x) x +#else + #define CDCLIENT_DONT_CACHE_TABLE(x) +#endif + CDClientManager::CDClientManager() { - CDActivityRewardsTable::Instance(); - CDAnimationsTable::Instance(); - CDBehaviorParameterTable::Instance(); - CDBehaviorTemplateTable::Instance(); - CDComponentsRegistryTable::Instance(); - CDCurrencyTableTable::Instance(); - CDDestructibleComponentTable::Instance(); - CDEmoteTableTable::Instance(); - CDInventoryComponentTable::Instance(); - CDItemComponentTable::Instance(); - CDItemSetsTable::Instance(); - CDItemSetSkillsTable::Instance(); - CDLevelProgressionLookupTable::Instance(); - CDLootMatrixTable::Instance(); - CDLootTableTable::Instance(); - CDMissionNPCComponentTable::Instance(); - CDMissionTasksTable::Instance(); - CDMissionsTable::Instance(); - CDObjectSkillsTable::Instance(); - CDObjectsTable::Instance(); - CDPhysicsComponentTable::Instance(); - CDRebuildComponentTable::Instance(); - CDScriptComponentTable::Instance(); - CDSkillBehaviorTable::Instance(); - CDZoneTableTable::Instance(); - CDVendorComponentTable::Instance(); - CDActivitiesTable::Instance(); - CDPackageComponentTable::Instance(); - CDProximityMonitorComponentTable::Instance(); - CDMovementAIComponentTable::Instance(); - CDBrickIDTableTable::Instance(); - CDRarityTableTable::Instance(); - CDMissionEmailTable::Instance(); - CDRewardsTable::Instance(); - CDPropertyEntranceComponentTable::Instance(); - CDPropertyTemplateTable::Instance(); - CDFeatureGatingTable::Instance(); - CDRailActivatorComponentTable::Instance(); + CDActivityRewardsTable::Instance().LoadValuesFromDatabase(); + CDActivitiesTable::Instance().LoadValuesFromDatabase(); + CDCLIENT_DONT_CACHE_TABLE(CDAnimationsTable::Instance().LoadValuesFromDatabase()); + CDBehaviorParameterTable::Instance().LoadValuesFromDatabase(); + CDBehaviorTemplateTable::Instance().LoadValuesFromDatabase(); + CDBrickIDTableTable::Instance().LoadValuesFromDatabase(); + CDComponentsRegistryTable::Instance().LoadValuesFromDatabase(); + CDCurrencyTableTable::Instance().LoadValuesFromDatabase(); + CDDestructibleComponentTable::Instance().LoadValuesFromDatabase(); + CDEmoteTableTable::Instance().LoadValuesFromDatabase(); + CDFeatureGatingTable::Instance().LoadValuesFromDatabase(); + CDInventoryComponentTable::Instance().LoadValuesFromDatabase(); + CDCLIENT_DONT_CACHE_TABLE(CDItemComponentTable::Instance().LoadValuesFromDatabase()); + CDItemSetSkillsTable::Instance().LoadValuesFromDatabase(); + CDItemSetsTable::Instance().LoadValuesFromDatabase(); + CDLevelProgressionLookupTable::Instance().LoadValuesFromDatabase(); + CDLootMatrixTable::Instance().LoadValuesFromDatabase(); + CDLootTableTable::Instance().LoadValuesFromDatabase(); + CDMissionEmailTable::Instance().LoadValuesFromDatabase(); + CDMissionNPCComponentTable::Instance().LoadValuesFromDatabase(); + CDMissionTasksTable::Instance().LoadValuesFromDatabase(); + CDMissionsTable::Instance().LoadValuesFromDatabase(); + CDMovementAIComponentTable::Instance().LoadValuesFromDatabase(); + CDObjectSkillsTable::Instance().LoadValuesFromDatabase(); + CDCLIENT_DONT_CACHE_TABLE(CDObjectsTable::Instance().LoadValuesFromDatabase()); + CDPhysicsComponentTable::Instance().LoadValuesFromDatabase(); + CDPackageComponentTable::Instance().LoadValuesFromDatabase(); + CDProximityMonitorComponentTable::Instance().LoadValuesFromDatabase(); + CDPropertyEntranceComponentTable::Instance().LoadValuesFromDatabase(); + CDPropertyTemplateTable::Instance().LoadValuesFromDatabase(); + CDRailActivatorComponentTable::Instance().LoadValuesFromDatabase(); + CDRarityTableTable::Instance().LoadValuesFromDatabase(); + CDRebuildComponentTable::Instance().LoadValuesFromDatabase(); + CDRewardsTable::Instance().LoadValuesFromDatabase(); + CDScriptComponentTable::Instance().LoadValuesFromDatabase(); + CDSkillBehaviorTable::Instance().LoadValuesFromDatabase(); + CDVendorComponentTable::Instance().LoadValuesFromDatabase(); + CDZoneTableTable::Instance().LoadValuesFromDatabase(); } diff --git a/dDatabase/Tables/CDActivitiesTable.cpp b/dDatabase/Tables/CDActivitiesTable.cpp index e1660d66..c967f724 100644 --- a/dDatabase/Tables/CDActivitiesTable.cpp +++ b/dDatabase/Tables/CDActivitiesTable.cpp @@ -1,7 +1,6 @@ #include "CDActivitiesTable.h" -CDActivitiesTable::CDActivitiesTable(void) { - +void CDActivitiesTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Activities"); @@ -55,8 +54,3 @@ std::vector CDActivitiesTable::Query(std::function CDActivitiesTable::GetEntries(void) const { - return this->entries; -} - diff --git a/dDatabase/Tables/CDActivitiesTable.h b/dDatabase/Tables/CDActivitiesTable.h index 4b60afbd..2e39d595 100644 --- a/dDatabase/Tables/CDActivitiesTable.h +++ b/dDatabase/Tables/CDActivitiesTable.h @@ -30,9 +30,10 @@ private: std::vector entries; public: - CDActivitiesTable(); + void LoadValuesFromDatabase(); + // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const { return this->entries; } }; diff --git a/dDatabase/Tables/CDActivityRewardsTable.cpp b/dDatabase/Tables/CDActivityRewardsTable.cpp index 65ef1101..a2434d19 100644 --- a/dDatabase/Tables/CDActivityRewardsTable.cpp +++ b/dDatabase/Tables/CDActivityRewardsTable.cpp @@ -1,6 +1,6 @@ #include "CDActivityRewardsTable.h" -CDActivityRewardsTable::CDActivityRewardsTable(void) { +void CDActivityRewardsTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -43,8 +43,3 @@ std::vector CDActivityRewardsTable::Query(std::function CDActivityRewardsTable::GetEntries(void) const { - return this->entries; -} - diff --git a/dDatabase/Tables/CDActivityRewardsTable.h b/dDatabase/Tables/CDActivityRewardsTable.h index b5503fb6..a177a3c0 100644 --- a/dDatabase/Tables/CDActivityRewardsTable.h +++ b/dDatabase/Tables/CDActivityRewardsTable.h @@ -18,10 +18,10 @@ private: std::vector entries; public: - CDActivityRewardsTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + std::vector GetEntries() const; }; diff --git a/dDatabase/Tables/CDAnimationsTable.cpp b/dDatabase/Tables/CDAnimationsTable.cpp index 76ce0e5a..7244ddee 100644 --- a/dDatabase/Tables/CDAnimationsTable.cpp +++ b/dDatabase/Tables/CDAnimationsTable.cpp @@ -2,6 +2,35 @@ #include "GeneralUtils.h" #include "Game.h" + +void CDAnimationsTable::LoadValuesFromDatabase() { + auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations"); + while (!tableData.eof()) { + std::string animation_type = tableData.getStringField("animation_type", ""); + DluAssert(!animation_type.empty()); + AnimationGroupID animationGroupID = tableData.getIntField("animationGroupID", -1); + DluAssert(animationGroupID != -1); + + CDAnimation entry; + entry.animation_name = tableData.getStringField("animation_name", ""); + entry.chance_to_play = tableData.getFloatField("chance_to_play", 1.0f); + 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); + 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(); + } + + tableData.finalize(); +} + 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. diff --git a/dDatabase/Tables/CDAnimationsTable.h b/dDatabase/Tables/CDAnimationsTable.h index 65f54d98..494d5cde 100644 --- a/dDatabase/Tables/CDAnimationsTable.h +++ b/dDatabase/Tables/CDAnimationsTable.h @@ -27,6 +27,7 @@ class CDAnimationsTable : public CDTable { typedef std::string AnimationID; typedef std::pair CDAnimationKey; public: + void LoadValuesFromDatabase(); /** * 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 diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index 8181245b..708bec4c 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -1,15 +1,15 @@ #include "CDBehaviorParameterTable.h" #include "GeneralUtils.h" -uint64_t GetHash(const uint32_t behaviorID, const uint32_t parameterID) { - uint64_t hash = behaviorID; - hash <<= 31U; - hash |= parameterID; +uint64_t GetKey(const uint32_t behaviorID, const uint32_t parameterID) { + uint64_t key = behaviorID; + key <<= 31U; + key |= parameterID; - return hash; + return key; } -CDBehaviorParameterTable::CDBehaviorParameterTable() { +void CDBehaviorParameterTable::LoadValuesFromDatabase() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); while (!tableData.eof()) { uint32_t behaviorID = tableData.getIntField("behaviorID", -1); @@ -21,7 +21,7 @@ CDBehaviorParameterTable::CDBehaviorParameterTable() { } else { parameterId = m_ParametersList.insert(std::make_pair(candidateStringToAdd, m_ParametersList.size())).first->second; } - uint64_t hash = GetHash(behaviorID, parameterId); + uint64_t hash = GetKey(behaviorID, parameterId); float value = tableData.getFloatField("value", -1.0f); m_Entries.insert(std::make_pair(hash, value)); @@ -34,7 +34,7 @@ CDBehaviorParameterTable::CDBehaviorParameterTable() { float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) { auto parameterID = this->m_ParametersList.find(name); if (parameterID == this->m_ParametersList.end()) return defaultValue; - auto hash = GetHash(behaviorID, parameterID->second); + auto hash = GetKey(behaviorID, parameterID->second); // Search for specific parameter auto it = m_Entries.find(hash); @@ -45,7 +45,7 @@ std::map CDBehaviorParameterTable::GetParametersByBehaviorID uint64_t hashBase = behaviorID; std::map returnInfo; for (auto& [parameterString, parameterId] : m_ParametersList) { - uint64_t hash = GetHash(hashBase, parameterId); + uint64_t hash = GetKey(hashBase, parameterId); auto infoCandidate = m_Entries.find(hash); if (infoCandidate != m_Entries.end()) { returnInfo.insert(std::make_pair(parameterString, infoCandidate->second)); diff --git a/dDatabase/Tables/CDBehaviorParameterTable.h b/dDatabase/Tables/CDBehaviorParameterTable.h index 249caacf..3daa3aa3 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.h +++ b/dDatabase/Tables/CDBehaviorParameterTable.h @@ -12,7 +12,7 @@ private: std::unordered_map m_Entries; std::unordered_map m_ParametersList; public: - CDBehaviorParameterTable(); + void LoadValuesFromDatabase(); float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.cpp b/dDatabase/Tables/CDBehaviorTemplateTable.cpp index 08bc86d1..c343ef85 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.cpp +++ b/dDatabase/Tables/CDBehaviorTemplateTable.cpp @@ -1,6 +1,6 @@ #include "CDBehaviorTemplateTable.h" -CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) { +void CDBehaviorTemplateTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -48,7 +48,7 @@ std::vector CDBehaviorTemplateTable::Query(std::function CDBehaviorTemplateTable::GetEntries(void) const { +const std::vector& CDBehaviorTemplateTable::GetEntries() const { return this->entries; } @@ -64,4 +64,3 @@ const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behav return entry->second; } } - diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.h b/dDatabase/Tables/CDBehaviorTemplateTable.h index f9ac9a09..49ce11f2 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.h +++ b/dDatabase/Tables/CDBehaviorTemplateTable.h @@ -19,11 +19,12 @@ private: std::unordered_map entriesMappedByBehaviorID; std::unordered_set m_EffectHandles; public: - CDBehaviorTemplateTable(); + void LoadValuesFromDatabase(); + // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries(void) const; const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID); }; diff --git a/dDatabase/Tables/CDBrickIDTableTable.cpp b/dDatabase/Tables/CDBrickIDTableTable.cpp index 9ad24d39..9be75f0b 100644 --- a/dDatabase/Tables/CDBrickIDTableTable.cpp +++ b/dDatabase/Tables/CDBrickIDTableTable.cpp @@ -1,6 +1,6 @@ #include "CDBrickIDTableTable.h" -CDBrickIDTableTable::CDBrickIDTableTable(void) { +void CDBrickIDTableTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -39,7 +39,7 @@ std::vector CDBrickIDTableTable::Query(std::function CDBrickIDTableTable::GetEntries(void) const { +const std::vector& CDBrickIDTableTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDBrickIDTableTable.h b/dDatabase/Tables/CDBrickIDTableTable.h index e2084caf..68c0b1b6 100644 --- a/dDatabase/Tables/CDBrickIDTableTable.h +++ b/dDatabase/Tables/CDBrickIDTableTable.h @@ -21,9 +21,9 @@ private: std::vector entries; public: - CDBrickIDTableTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDComponentsRegistryTable.cpp b/dDatabase/Tables/CDComponentsRegistryTable.cpp index 32012f6c..ac547a24 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.cpp +++ b/dDatabase/Tables/CDComponentsRegistryTable.cpp @@ -1,27 +1,37 @@ #include "CDComponentsRegistryTable.h" #include "eReplicaComponentType.h" -#define CDCLIENT_CACHE_ALL - -CDComponentsRegistryTable::CDComponentsRegistryTable(void) { - -#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); - - tableSize.nextRow(); - } - - tableSize.finalize(); - - // Reserve the size - //this->entries.reserve(size); - +void CDComponentsRegistryTable::LoadValuesFromDatabase() { // Now get the data 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); + this->mappedEntries.insert_or_assign(entry.id, 0); + + tableData.nextRow(); + } + + tableData.finalize(); +} + +int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) { + auto exists = mappedEntries.find(id); + if (exists != mappedEntries.end()) { + auto iter = mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); + return iter == mappedEntries.end() ? defaultValue : iter->second; + } + + // Now get the data. Get all components of this entity so we dont do a query for each component + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM ComponentsRegistry WHERE id = ?;"); + query.bind(1, static_cast(id)); + + auto tableData = query.execQuery(); + while (!tableData.eof()) { CDComponentsRegistry entry; entry.id = tableData.getIntField("id", -1); @@ -33,61 +43,10 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) { 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 + mappedEntries.insert_or_assign(id, 0); + + auto iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); + + return iter == this->mappedEntries.end() ? defaultValue : iter->second; } diff --git a/dDatabase/Tables/CDComponentsRegistryTable.h b/dDatabase/Tables/CDComponentsRegistryTable.h index 990072c9..fc461989 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.h +++ b/dDatabase/Tables/CDComponentsRegistryTable.h @@ -13,9 +13,9 @@ struct CDComponentsRegistry { class CDComponentsRegistryTable : public CDTable { private: - std::map mappedEntries; //id, component_type, component_id + std::unordered_map mappedEntries; //id, component_type, component_id public: - CDComponentsRegistryTable(); + void LoadValuesFromDatabase(); int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0); }; diff --git a/dDatabase/Tables/CDCurrencyTableTable.cpp b/dDatabase/Tables/CDCurrencyTableTable.cpp index 78a716f9..58c517f2 100644 --- a/dDatabase/Tables/CDCurrencyTableTable.cpp +++ b/dDatabase/Tables/CDCurrencyTableTable.cpp @@ -1,7 +1,7 @@ #include "CDCurrencyTableTable.h" //! Constructor -CDCurrencyTableTable::CDCurrencyTableTable(void) { +void CDCurrencyTableTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -43,7 +43,7 @@ std::vector CDCurrencyTableTable::Query(std::function CDCurrencyTableTable::GetEntries(void) const { +const std::vector& CDCurrencyTableTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDCurrencyTableTable.h b/dDatabase/Tables/CDCurrencyTableTable.h index ec700320..fd70a968 100644 --- a/dDatabase/Tables/CDCurrencyTableTable.h +++ b/dDatabase/Tables/CDCurrencyTableTable.h @@ -23,9 +23,9 @@ private: std::vector entries; public: - CDCurrencyTableTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDDestructibleComponentTable.cpp b/dDatabase/Tables/CDDestructibleComponentTable.cpp index 4bbc8242..f92aec94 100644 --- a/dDatabase/Tables/CDDestructibleComponentTable.cpp +++ b/dDatabase/Tables/CDDestructibleComponentTable.cpp @@ -1,8 +1,6 @@ #include "CDDestructibleComponentTable.h" -//! Constructor -CDDestructibleComponentTable::CDDestructibleComponentTable(void) { - +void CDDestructibleComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent"); @@ -52,7 +50,7 @@ std::vector CDDestructibleComponentTable::Query(std::fu return data; } -std::vector CDDestructibleComponentTable::GetEntries(void) const { +const std::vector& CDDestructibleComponentTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDDestructibleComponentTable.h b/dDatabase/Tables/CDDestructibleComponentTable.h index e42cf486..fb6ee4cd 100644 --- a/dDatabase/Tables/CDDestructibleComponentTable.h +++ b/dDatabase/Tables/CDDestructibleComponentTable.h @@ -25,9 +25,9 @@ private: std::vector entries; public: - CDDestructibleComponentTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDEmoteTable.cpp b/dDatabase/Tables/CDEmoteTable.cpp index aacbdd55..77aa226c 100644 --- a/dDatabase/Tables/CDEmoteTable.cpp +++ b/dDatabase/Tables/CDEmoteTable.cpp @@ -1,40 +1,26 @@ #include "CDEmoteTable.h" -//! Constructor -CDEmoteTableTable::CDEmoteTableTable(void) { +void CDEmoteTableTable::LoadValuesFromDatabase() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Emotes"); while (!tableData.eof()) { - CDEmoteTable* entry = new CDEmoteTable(); - entry->ID = tableData.getIntField("id", -1); - entry->animationName = tableData.getStringField("animationName", ""); - entry->iconFilename = tableData.getStringField("iconFilename", ""); - entry->channel = tableData.getIntField("channel", -1); - entry->locked = tableData.getIntField("locked", -1) != 0; - entry->localize = tableData.getIntField("localize", -1) != 0; - entry->locState = tableData.getIntField("locStatus", -1); - entry->gateVersion = tableData.getStringField("gate_version", ""); + CDEmoteTable entry; + entry.ID = tableData.getIntField("id", -1); + entry.animationName = tableData.getStringField("animationName", ""); + entry.iconFilename = tableData.getStringField("iconFilename", ""); + entry.channel = tableData.getIntField("channel", -1); + entry.locked = tableData.getIntField("locked", -1) != 0; + entry.localize = tableData.getIntField("localize", -1) != 0; + entry.locState = tableData.getIntField("locStatus", -1); + entry.gateVersion = tableData.getStringField("gate_version", ""); - entries.insert(std::make_pair(entry->ID, entry)); + entries.insert(std::make_pair(entry.ID, entry)); tableData.nextRow(); } tableData.finalize(); } -//! Destructor -CDEmoteTableTable::~CDEmoteTableTable(void) { - for (auto e : entries) { - if (e.second) delete e.second; - } - - entries.clear(); -} - CDEmoteTable* CDEmoteTableTable::GetEmote(int id) { - for (auto e : entries) { - if (e.first == id) return e.second; - } - - return nullptr; + auto itr = entries.find(id); + return itr != entries.end() ? &itr->second : nullptr; } - diff --git a/dDatabase/Tables/CDEmoteTable.h b/dDatabase/Tables/CDEmoteTable.h index be40c86f..a49d1c45 100644 --- a/dDatabase/Tables/CDEmoteTable.h +++ b/dDatabase/Tables/CDEmoteTable.h @@ -28,11 +28,10 @@ struct CDEmoteTable { class CDEmoteTableTable : public CDTable { private: - std::map entries; + std::map entries; public: - CDEmoteTableTable(); - ~CDEmoteTableTable(); + void LoadValuesFromDatabase(); // Returns an emote by ID CDEmoteTable* GetEmote(int id); }; diff --git a/dDatabase/Tables/CDFeatureGatingTable.cpp b/dDatabase/Tables/CDFeatureGatingTable.cpp index 05fe69bf..5013dd13 100644 --- a/dDatabase/Tables/CDFeatureGatingTable.cpp +++ b/dDatabase/Tables/CDFeatureGatingTable.cpp @@ -1,7 +1,6 @@ #include "CDFeatureGatingTable.h" -//! Constructor -CDFeatureGatingTable::CDFeatureGatingTable(void) { +void CDFeatureGatingTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -53,7 +52,7 @@ bool CDFeatureGatingTable::FeatureUnlocked(const std::string& feature) const { return false; } -std::vector CDFeatureGatingTable::GetEntries(void) const { +const std::vector& CDFeatureGatingTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDFeatureGatingTable.h b/dDatabase/Tables/CDFeatureGatingTable.h index 7f536db5..9a978218 100644 --- a/dDatabase/Tables/CDFeatureGatingTable.h +++ b/dDatabase/Tables/CDFeatureGatingTable.h @@ -16,11 +16,12 @@ private: std::vector entries; public: - CDFeatureGatingTable(); + void LoadValuesFromDatabase(); + // Queries the table with a custom "where" clause std::vector Query(std::function predicate); bool FeatureUnlocked(const std::string& feature) const; - std::vector GetEntries(void) const; + const std::vector& GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDInventoryComponentTable.cpp b/dDatabase/Tables/CDInventoryComponentTable.cpp index 2dc375ab..ffc8fee6 100644 --- a/dDatabase/Tables/CDInventoryComponentTable.cpp +++ b/dDatabase/Tables/CDInventoryComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDInventoryComponentTable.h" -//! Constructor -CDInventoryComponentTable::CDInventoryComponentTable(void) { +void CDInventoryComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -42,7 +41,7 @@ std::vector CDInventoryComponentTable::Query(std::function return data; } -std::vector CDInventoryComponentTable::GetEntries(void) const { +const std::vector& CDInventoryComponentTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDInventoryComponentTable.h b/dDatabase/Tables/CDInventoryComponentTable.h index cbc04d99..26d47ffe 100644 --- a/dDatabase/Tables/CDInventoryComponentTable.h +++ b/dDatabase/Tables/CDInventoryComponentTable.h @@ -15,9 +15,9 @@ private: std::vector entries; public: - CDInventoryComponentTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDItemComponentTable.cpp b/dDatabase/Tables/CDItemComponentTable.cpp index 54afc417..5d6722f9 100644 --- a/dDatabase/Tables/CDItemComponentTable.cpp +++ b/dDatabase/Tables/CDItemComponentTable.cpp @@ -3,11 +3,7 @@ CDItemComponent CDItemComponentTable::Default = {}; -//! Constructor -CDItemComponentTable::CDItemComponentTable(void) { - Default = CDItemComponent(); - -#ifdef CDCLIENT_CACHE_ALL +void CDItemComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ItemComponent"); @@ -55,13 +51,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); @@ -71,7 +67,6 @@ CDItemComponentTable::CDItemComponentTable(void) { } tableData.finalize(); -#endif } const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int skillID) { @@ -80,12 +75,10 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s return it->second; } -#ifndef CDCLIENT_CACHE_ALL - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM ItemComponent WHERE id = ?;"); + query.bind(1, static_cast(skillID)); - query << "SELECT * FROM ItemComponent WHERE id = " << std::to_string(skillID); - - auto tableData = CDClientDatabase::ExecuteQuery(query.str()); + auto tableData = query.execQuery(); if (tableData.eof()) { entries.insert(std::make_pair(skillID, Default)); return Default; @@ -144,7 +137,6 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s if (it2 != this->entries.end()) { return it2->second; } -#endif return Default; } diff --git a/dDatabase/Tables/CDItemComponentTable.h b/dDatabase/Tables/CDItemComponentTable.h index 11c34dd6..685e5acd 100644 --- a/dDatabase/Tables/CDItemComponentTable.h +++ b/dDatabase/Tables/CDItemComponentTable.h @@ -54,7 +54,7 @@ private: std::map entries; public: - CDItemComponentTable(); + void LoadValuesFromDatabase(); static std::map ParseCraftingCurrencies(const CDItemComponent& itemComponent); // Gets an entry by ID diff --git a/dDatabase/Tables/CDItemSetSkillsTable.cpp b/dDatabase/Tables/CDItemSetSkillsTable.cpp index f6b412ff..6fb1689e 100644 --- a/dDatabase/Tables/CDItemSetSkillsTable.cpp +++ b/dDatabase/Tables/CDItemSetSkillsTable.cpp @@ -1,7 +1,6 @@ #include "CDItemSetSkillsTable.h" -//! Constructor -CDItemSetSkillsTable::CDItemSetSkillsTable(void) { +void CDItemSetSkillsTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -41,7 +40,7 @@ std::vector CDItemSetSkillsTable::Query(std::function CDItemSetSkillsTable::GetEntries(void) const { +const std::vector& CDItemSetSkillsTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDItemSetSkillsTable.h b/dDatabase/Tables/CDItemSetSkillsTable.h index 8328c66b..07321a7f 100644 --- a/dDatabase/Tables/CDItemSetSkillsTable.h +++ b/dDatabase/Tables/CDItemSetSkillsTable.h @@ -14,11 +14,11 @@ private: std::vector entries; public: - CDItemSetSkillsTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; std::vector GetBySkillID(unsigned int SkillSetID); }; diff --git a/dDatabase/Tables/CDItemSetsTable.cpp b/dDatabase/Tables/CDItemSetsTable.cpp index 0632ef13..de70e180 100644 --- a/dDatabase/Tables/CDItemSetsTable.cpp +++ b/dDatabase/Tables/CDItemSetsTable.cpp @@ -1,7 +1,6 @@ #include "CDItemSetsTable.h" -//! Constructor -CDItemSetsTable::CDItemSetsTable(void) { +void CDItemSetsTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -53,7 +52,7 @@ std::vector CDItemSetsTable::Query(std::function p return data; } -std::vector CDItemSetsTable::GetEntries(void) const { +const std::vector& CDItemSetsTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDItemSetsTable.h b/dDatabase/Tables/CDItemSetsTable.h index 6756e7fa..a3a738b1 100644 --- a/dDatabase/Tables/CDItemSetsTable.h +++ b/dDatabase/Tables/CDItemSetsTable.h @@ -26,10 +26,10 @@ private: std::vector entries; public: - CDItemSetsTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDLevelProgressionLookupTable.cpp b/dDatabase/Tables/CDLevelProgressionLookupTable.cpp index 47a8fc0e..d0a6ca93 100644 --- a/dDatabase/Tables/CDLevelProgressionLookupTable.cpp +++ b/dDatabase/Tables/CDLevelProgressionLookupTable.cpp @@ -1,7 +1,6 @@ #include "CDLevelProgressionLookupTable.h" -//! Constructor -CDLevelProgressionLookupTable::CDLevelProgressionLookupTable(void) { +void CDLevelProgressionLookupTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -32,7 +31,6 @@ CDLevelProgressionLookupTable::CDLevelProgressionLookupTable(void) { tableData.finalize(); } -//! Queries the table with a custom "where" clause std::vector CDLevelProgressionLookupTable::Query(std::function predicate) { std::vector data = cpplinq::from(this->entries) @@ -42,8 +40,7 @@ std::vector CDLevelProgressionLookupTable::Query(std:: return data; } -//! Gets all the entries in the table -std::vector CDLevelProgressionLookupTable::GetEntries(void) const { +const std::vector& CDLevelProgressionLookupTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDLevelProgressionLookupTable.h b/dDatabase/Tables/CDLevelProgressionLookupTable.h index 070b2e0c..6b68bd0d 100644 --- a/dDatabase/Tables/CDLevelProgressionLookupTable.h +++ b/dDatabase/Tables/CDLevelProgressionLookupTable.h @@ -14,10 +14,10 @@ private: std::vector entries; public: - CDLevelProgressionLookupTable(); + void LoadValuesFromDatabase(); + // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - // Gets all the entries in the table - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDLootMatrixTable.cpp b/dDatabase/Tables/CDLootMatrixTable.cpp index 8f25e8a3..27c01b30 100644 --- a/dDatabase/Tables/CDLootMatrixTable.cpp +++ b/dDatabase/Tables/CDLootMatrixTable.cpp @@ -1,7 +1,6 @@ #include "CDLootMatrixTable.h" -//! Constructor -CDLootMatrixTable::CDLootMatrixTable(void) { +void CDLootMatrixTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -47,7 +46,7 @@ std::vector CDLootMatrixTable::Query(std::function& CDLootMatrixTable::GetEntries(void) const { +const std::vector& CDLootMatrixTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDLootMatrixTable.h b/dDatabase/Tables/CDLootMatrixTable.h index c6035841..6ea012cb 100644 --- a/dDatabase/Tables/CDLootMatrixTable.h +++ b/dDatabase/Tables/CDLootMatrixTable.h @@ -20,10 +20,10 @@ private: std::vector entries; public: - CDLootMatrixTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - const std::vector& GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDLootTableTable.cpp b/dDatabase/Tables/CDLootTableTable.cpp index 0a46784a..17dfd641 100644 --- a/dDatabase/Tables/CDLootTableTable.cpp +++ b/dDatabase/Tables/CDLootTableTable.cpp @@ -1,7 +1,6 @@ #include "CDLootTableTable.h" -//! Constructor -CDLootTableTable::CDLootTableTable(void) { +void CDLootTableTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -46,7 +45,7 @@ std::vector CDLootTableTable::Query(std::function& CDLootTableTable::GetEntries(void) const { +const std::vector& CDLootTableTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDLootTableTable.h b/dDatabase/Tables/CDLootTableTable.h index ba6f207e..baa300b0 100644 --- a/dDatabase/Tables/CDLootTableTable.h +++ b/dDatabase/Tables/CDLootTableTable.h @@ -16,10 +16,10 @@ private: std::vector entries; public: - CDLootTableTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - const std::vector& GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDMissionEmailTable.cpp b/dDatabase/Tables/CDMissionEmailTable.cpp index ed855d8a..207d3815 100644 --- a/dDatabase/Tables/CDMissionEmailTable.cpp +++ b/dDatabase/Tables/CDMissionEmailTable.cpp @@ -1,7 +1,6 @@ #include "CDMissionEmailTable.h" -//! Constructor -CDMissionEmailTable::CDMissionEmailTable(void) { +void CDMissionEmailTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -48,7 +47,7 @@ std::vector CDMissionEmailTable::Query(std::function CDMissionEmailTable::GetEntries(void) const { +const std::vector& CDMissionEmailTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDMissionEmailTable.h b/dDatabase/Tables/CDMissionEmailTable.h index db2310d4..954da78e 100644 --- a/dDatabase/Tables/CDMissionEmailTable.h +++ b/dDatabase/Tables/CDMissionEmailTable.h @@ -20,9 +20,9 @@ private: std::vector entries; public: - CDMissionEmailTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDMissionNPCComponentTable.cpp b/dDatabase/Tables/CDMissionNPCComponentTable.cpp index 5672ed67..59ea40b7 100644 --- a/dDatabase/Tables/CDMissionNPCComponentTable.cpp +++ b/dDatabase/Tables/CDMissionNPCComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDMissionNPCComponentTable.h" -//! Constructor -CDMissionNPCComponentTable::CDMissionNPCComponentTable(void) { +void CDMissionNPCComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -45,7 +44,7 @@ std::vector CDMissionNPCComponentTable::Query(std::functi } //! Gets all the entries in the table -std::vector CDMissionNPCComponentTable::GetEntries(void) const { +const std::vector& CDMissionNPCComponentTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDMissionNPCComponentTable.h b/dDatabase/Tables/CDMissionNPCComponentTable.h index a7aeb145..2b2b3303 100644 --- a/dDatabase/Tables/CDMissionNPCComponentTable.h +++ b/dDatabase/Tables/CDMissionNPCComponentTable.h @@ -16,12 +16,12 @@ private: std::vector entries; public: - CDMissionNPCComponentTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); // Gets all the entries in the table - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDMissionTasksTable.cpp b/dDatabase/Tables/CDMissionTasksTable.cpp index f32dca1b..9795ea8f 100644 --- a/dDatabase/Tables/CDMissionTasksTable.cpp +++ b/dDatabase/Tables/CDMissionTasksTable.cpp @@ -1,7 +1,6 @@ #include "CDMissionTasksTable.h" -//! Constructor -CDMissionTasksTable::CDMissionTasksTable(void) { +void CDMissionTasksTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -56,16 +55,14 @@ std::vector CDMissionTasksTable::GetByMissionID(uint32_t missio for (auto& entry : this->entries) { if (entry.id == missionID) { - CDMissionTasks* task = const_cast(&entry); - - tasks.push_back(task); + tasks.push_back(&entry); } } return tasks; } -const std::vector& CDMissionTasksTable::GetEntries(void) const { +const std::vector& CDMissionTasksTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDMissionTasksTable.h b/dDatabase/Tables/CDMissionTasksTable.h index fa213faf..0b169db8 100644 --- a/dDatabase/Tables/CDMissionTasksTable.h +++ b/dDatabase/Tables/CDMissionTasksTable.h @@ -24,12 +24,12 @@ private: std::vector entries; public: - CDMissionTasksTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); std::vector GetByMissionID(uint32_t missionID); - const std::vector& GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDMissionsTable.cpp b/dDatabase/Tables/CDMissionsTable.cpp index d4ee40ae..37f0c81c 100644 --- a/dDatabase/Tables/CDMissionsTable.cpp +++ b/dDatabase/Tables/CDMissionsTable.cpp @@ -2,8 +2,7 @@ CDMissions CDMissionsTable::Default = {}; -//! Constructor -CDMissionsTable::CDMissionsTable(void) { +void CDMissionsTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; diff --git a/dDatabase/Tables/CDMissionsTable.h b/dDatabase/Tables/CDMissionsTable.h index e6a44b02..c8ddc2a3 100644 --- a/dDatabase/Tables/CDMissionsTable.h +++ b/dDatabase/Tables/CDMissionsTable.h @@ -65,12 +65,12 @@ private: std::vector entries; public: - CDMissionsTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); // Gets all the entries in the table - const std::vector& GetEntries(void) const; + const std::vector& GetEntries() const; const CDMissions* GetPtrByMissionID(uint32_t missionID) const; diff --git a/dDatabase/Tables/CDMovementAIComponentTable.cpp b/dDatabase/Tables/CDMovementAIComponentTable.cpp index 3b9cc4f4..35b46416 100644 --- a/dDatabase/Tables/CDMovementAIComponentTable.cpp +++ b/dDatabase/Tables/CDMovementAIComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDMovementAIComponentTable.h" -//! Constructor -CDMovementAIComponentTable::CDMovementAIComponentTable(void) { +void CDMovementAIComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -37,7 +36,6 @@ CDMovementAIComponentTable::CDMovementAIComponentTable(void) { tableData.finalize(); } -//! Queries the table with a custom "where" clause std::vector CDMovementAIComponentTable::Query(std::function predicate) { std::vector data = cpplinq::from(this->entries) @@ -47,8 +45,7 @@ std::vector CDMovementAIComponentTable::Query(std::functi return data; } -//! Gets all the entries in the table -std::vector CDMovementAIComponentTable::GetEntries(void) const { +const std::vector& CDMovementAIComponentTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDMovementAIComponentTable.h b/dDatabase/Tables/CDMovementAIComponentTable.h index 84896e2c..b40694bd 100644 --- a/dDatabase/Tables/CDMovementAIComponentTable.h +++ b/dDatabase/Tables/CDMovementAIComponentTable.h @@ -19,10 +19,10 @@ private: std::vector entries; public: - CDMovementAIComponentTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); // Gets all the entries in the table - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDObjectSkillsTable.cpp b/dDatabase/Tables/CDObjectSkillsTable.cpp index 2e8b3fb2..2439622c 100644 --- a/dDatabase/Tables/CDObjectSkillsTable.cpp +++ b/dDatabase/Tables/CDObjectSkillsTable.cpp @@ -1,7 +1,6 @@ #include "CDObjectSkillsTable.h" -//! Constructor -CDObjectSkillsTable::CDObjectSkillsTable(void) { +void CDObjectSkillsTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -33,7 +32,6 @@ CDObjectSkillsTable::CDObjectSkillsTable(void) { tableData.finalize(); } -//! Queries the table with a custom "where" clause std::vector CDObjectSkillsTable::Query(std::function predicate) { std::vector data = cpplinq::from(this->entries) @@ -43,7 +41,6 @@ std::vector CDObjectSkillsTable::Query(std::function CDObjectSkillsTable::GetEntries(void) const { +const std::vector& CDObjectSkillsTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDObjectSkillsTable.h b/dDatabase/Tables/CDObjectSkillsTable.h index 4ceaa447..bd9929e2 100644 --- a/dDatabase/Tables/CDObjectSkillsTable.h +++ b/dDatabase/Tables/CDObjectSkillsTable.h @@ -15,12 +15,12 @@ private: std::vector entries; public: - CDObjectSkillsTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); // Gets all the entries in the table - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDObjectsTable.cpp b/dDatabase/Tables/CDObjectsTable.cpp index c68c3e6a..d3094b68 100644 --- a/dDatabase/Tables/CDObjectsTable.cpp +++ b/dDatabase/Tables/CDObjectsTable.cpp @@ -1,8 +1,6 @@ #include "CDObjectsTable.h" -//! Constructor -CDObjectsTable::CDObjectsTable(void) { -#ifdef CDCLIENT_CACHE_ALL +void CDObjectsTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Objects"); @@ -20,25 +18,24 @@ CDObjectsTable::CDObjectsTable(void) { CDObjects entry; entry.id = tableData.getIntField("id", -1); entry.name = tableData.getStringField("name", ""); - entry.placeable = tableData.getIntField("placeable", -1); + UNUSED_COLUMN(entry.placeable = tableData.getIntField("placeable", -1);) entry.type = tableData.getStringField("type", ""); - entry.description = tableData.getStringField("description", ""); - entry.localize = tableData.getIntField("localize", -1); - entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1); - entry.displayName = tableData.getStringField("displayName", ""); + UNUSED_COLUMN(entry.description = tableData.getStringField("description", "");) + 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); - entry.nametag = tableData.getIntField("nametag", -1); - entry._internalNotes = tableData.getStringField("_internalNotes", ""); - entry.locStatus = tableData.getIntField("locStatus", -1); - entry.gate_version = tableData.getStringField("gate_version", ""); - 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(); } tableData.finalize(); -#endif m_default.id = 0; } @@ -49,12 +46,10 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) { return it->second; } -#ifndef CDCLIENT_CACHE_ALL - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Objects WHERE id = ?;"); + query.bind(1, static_cast(LOT)); - query << "SELECT * FROM Objects WHERE id = " << std::to_string(LOT); - - auto tableData = CDClientDatabase::ExecuteQuery(query.str()); + auto tableData = query.execQuery(); if (tableData.eof()) { this->entries.insert(std::make_pair(LOT, m_default)); return m_default; @@ -88,7 +83,6 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) { if (it2 != entries.end()) { return it2->second; } -#endif return m_default; } diff --git a/dDatabase/Tables/CDObjectsTable.h b/dDatabase/Tables/CDObjectsTable.h index 171eddef..3a776684 100644 --- a/dDatabase/Tables/CDObjectsTable.h +++ b/dDatabase/Tables/CDObjectsTable.h @@ -26,7 +26,7 @@ private: CDObjects m_default; public: - CDObjectsTable(); + void LoadValuesFromDatabase(); // Gets an entry by ID const CDObjects& GetByID(unsigned int LOT); }; diff --git a/dDatabase/Tables/CDPackageComponentTable.cpp b/dDatabase/Tables/CDPackageComponentTable.cpp index efb85eeb..8b955162 100644 --- a/dDatabase/Tables/CDPackageComponentTable.cpp +++ b/dDatabase/Tables/CDPackageComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDPackageComponentTable.h" -//! Constructor -CDPackageComponentTable::CDPackageComponentTable(void) { +void CDPackageComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -43,7 +42,7 @@ std::vector CDPackageComponentTable::Query(std::function CDPackageComponentTable::GetEntries(void) const { +const std::vector& CDPackageComponentTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDPackageComponentTable.h b/dDatabase/Tables/CDPackageComponentTable.h index 6c11ab39..7ee58761 100644 --- a/dDatabase/Tables/CDPackageComponentTable.h +++ b/dDatabase/Tables/CDPackageComponentTable.h @@ -14,9 +14,9 @@ private: std::vector entries; public: - CDPackageComponentTable(void); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDPhysicsComponentTable.cpp b/dDatabase/Tables/CDPhysicsComponentTable.cpp index bb21ed7f..e17be4df 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.cpp +++ b/dDatabase/Tables/CDPhysicsComponentTable.cpp @@ -1,46 +1,35 @@ #include "CDPhysicsComponentTable.h" -CDPhysicsComponentTable::CDPhysicsComponentTable(void) { +void CDPhysicsComponentTable::LoadValuesFromDatabase() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent"); while (!tableData.eof()) { - CDPhysicsComponent* entry = new CDPhysicsComponent(); - entry->id = tableData.getIntField("id", -1); - entry->bStatic = tableData.getIntField("static", -1) != 0; - entry->physicsAsset = tableData.getStringField("physics_asset", ""); + CDPhysicsComponent entry; + 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); - entry->speed = tableData.getFloatField("speed", -1); + entry.speed = tableData.getFloatField("speed", -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"); + 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")); - m_entries.insert(std::make_pair(entry->id, entry)); + m_entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); } tableData.finalize(); } -CDPhysicsComponentTable::~CDPhysicsComponentTable() { - for (auto e : m_entries) { - if (e.second) delete e.second; - } - - m_entries.clear(); -} - CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) { - for (auto e : m_entries) { - if (e.first == componentID) return e.second; - } - - return nullptr; + auto itr = m_entries.find(componentID); + return itr != m_entries.end() ? &itr->second : nullptr; } diff --git a/dDatabase/Tables/CDPhysicsComponentTable.h b/dDatabase/Tables/CDPhysicsComponentTable.h index e63d337d..49f3b4c3 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.h +++ b/dDatabase/Tables/CDPhysicsComponentTable.h @@ -23,12 +23,11 @@ struct CDPhysicsComponent { class CDPhysicsComponentTable : public CDTable { public: - CDPhysicsComponentTable(); - ~CDPhysicsComponentTable(); + void LoadValuesFromDatabase(); static const std::string GetTableName() { return "PhysicsComponent"; }; CDPhysicsComponent* GetByID(unsigned int componentID); private: - std::map m_entries; + std::map m_entries; }; diff --git a/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp b/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp index 1fead45e..c1532c86 100644 --- a/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp +++ b/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp @@ -1,7 +1,6 @@ - #include "CDPropertyEntranceComponentTable.h" -CDPropertyEntranceComponentTable::CDPropertyEntranceComponentTable() { +void CDPropertyEntranceComponentTable::LoadValuesFromDatabase() { // First, get the size of the table size_t size = 0; diff --git a/dDatabase/Tables/CDPropertyEntranceComponentTable.h b/dDatabase/Tables/CDPropertyEntranceComponentTable.h index 925fd1be..5c7d0965 100644 --- a/dDatabase/Tables/CDPropertyEntranceComponentTable.h +++ b/dDatabase/Tables/CDPropertyEntranceComponentTable.h @@ -11,12 +11,12 @@ struct CDPropertyEntranceComponent { class CDPropertyEntranceComponentTable : public CDTable { public: - CDPropertyEntranceComponentTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause CDPropertyEntranceComponent GetByID(uint32_t id); // Gets all the entries in the table - [[nodiscard]] std::vector GetEntries() const { return entries; } + [[nodiscard]] const std::vector& GetEntries() const { return entries; } private: std::vector entries{}; CDPropertyEntranceComponent defaultEntry{}; diff --git a/dDatabase/Tables/CDPropertyTemplateTable.cpp b/dDatabase/Tables/CDPropertyTemplateTable.cpp index 4caa6dc5..4a1d666e 100644 --- a/dDatabase/Tables/CDPropertyTemplateTable.cpp +++ b/dDatabase/Tables/CDPropertyTemplateTable.cpp @@ -1,6 +1,6 @@ #include "CDPropertyTemplateTable.h" -CDPropertyTemplateTable::CDPropertyTemplateTable() { +void CDPropertyTemplateTable::LoadValuesFromDatabase() { // First, get the size of the table size_t size = 0; diff --git a/dDatabase/Tables/CDPropertyTemplateTable.h b/dDatabase/Tables/CDPropertyTemplateTable.h index cb075dbf..7261bdf9 100644 --- a/dDatabase/Tables/CDPropertyTemplateTable.h +++ b/dDatabase/Tables/CDPropertyTemplateTable.h @@ -10,7 +10,7 @@ struct CDPropertyTemplate { class CDPropertyTemplateTable : public CDTable { public: - CDPropertyTemplateTable(); + void LoadValuesFromDatabase(); static const std::string GetTableName() { return "PropertyTemplate"; }; CDPropertyTemplate GetByMapID(uint32_t mapID); diff --git a/dDatabase/Tables/CDProximityMonitorComponentTable.cpp b/dDatabase/Tables/CDProximityMonitorComponentTable.cpp index 688de056..ae0abac8 100644 --- a/dDatabase/Tables/CDProximityMonitorComponentTable.cpp +++ b/dDatabase/Tables/CDProximityMonitorComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDProximityMonitorComponentTable.h" -//! Constructor -CDProximityMonitorComponentTable::CDProximityMonitorComponentTable(void) { +void CDProximityMonitorComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -33,7 +32,6 @@ CDProximityMonitorComponentTable::CDProximityMonitorComponentTable(void) { tableData.finalize(); } -//! Queries the table with a custom "where" clause std::vector CDProximityMonitorComponentTable::Query(std::function predicate) { std::vector data = cpplinq::from(this->entries) @@ -43,8 +41,7 @@ std::vector CDProximityMonitorComponentTable::Query return data; } -//! Gets all the entries in the table -std::vector CDProximityMonitorComponentTable::GetEntries(void) const { +const std::vector& CDProximityMonitorComponentTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDProximityMonitorComponentTable.h b/dDatabase/Tables/CDProximityMonitorComponentTable.h index 38b7d43b..a50dd37e 100644 --- a/dDatabase/Tables/CDProximityMonitorComponentTable.h +++ b/dDatabase/Tables/CDProximityMonitorComponentTable.h @@ -15,9 +15,9 @@ private: std::vector entries; public: - CDProximityMonitorComponentTable(void); + void LoadValuesFromDatabase(); //! Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDRailActivatorComponent.cpp b/dDatabase/Tables/CDRailActivatorComponent.cpp index 2ff8990d..34ec5826 100644 --- a/dDatabase/Tables/CDRailActivatorComponent.cpp +++ b/dDatabase/Tables/CDRailActivatorComponent.cpp @@ -1,7 +1,7 @@ #include "CDRailActivatorComponent.h" #include "GeneralUtils.h" -CDRailActivatorComponentTable::CDRailActivatorComponentTable() { +void CDRailActivatorComponentTable::LoadValuesFromDatabase() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RailActivatorComponent;"); while (!tableData.eof()) { CDRailActivatorComponent entry; @@ -52,7 +52,7 @@ CDRailActivatorComponent CDRailActivatorComponentTable::GetEntryByID(int32_t id) return {}; } -std::vector CDRailActivatorComponentTable::GetEntries() const { +const std::vector& CDRailActivatorComponentTable::GetEntries() const { return m_Entries; } diff --git a/dDatabase/Tables/CDRailActivatorComponent.h b/dDatabase/Tables/CDRailActivatorComponent.h index 03dd0525..d06b2d36 100644 --- a/dDatabase/Tables/CDRailActivatorComponent.h +++ b/dDatabase/Tables/CDRailActivatorComponent.h @@ -22,10 +22,10 @@ struct CDRailActivatorComponent { class CDRailActivatorComponentTable : public CDTable { public: - CDRailActivatorComponentTable(); + void LoadValuesFromDatabase(); static const std::string GetTableName() { return "RailActivatorComponent"; }; [[nodiscard]] CDRailActivatorComponent GetEntryByID(int32_t id) const; - [[nodiscard]] std::vector GetEntries() const; + [[nodiscard]] const std::vector& GetEntries() const; private: static std::pair EffectPairFromString(std::string& str); std::vector m_Entries{}; diff --git a/dDatabase/Tables/CDRarityTableTable.cpp b/dDatabase/Tables/CDRarityTableTable.cpp index 0b1212c0..b0295a59 100644 --- a/dDatabase/Tables/CDRarityTableTable.cpp +++ b/dDatabase/Tables/CDRarityTableTable.cpp @@ -1,7 +1,6 @@ #include "CDRarityTableTable.h" -//! Constructor -CDRarityTableTable::CDRarityTableTable(void) { +void CDRarityTableTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -44,7 +43,7 @@ std::vector CDRarityTableTable::Query(std::function& CDRarityTableTable::GetEntries(void) const { +const std::vector& CDRarityTableTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDRarityTableTable.h b/dDatabase/Tables/CDRarityTableTable.h index 592346ed..2d28e4a5 100644 --- a/dDatabase/Tables/CDRarityTableTable.h +++ b/dDatabase/Tables/CDRarityTableTable.h @@ -31,7 +31,7 @@ private: std::vector entries; public: - CDRarityTableTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); diff --git a/dDatabase/Tables/CDRebuildComponentTable.cpp b/dDatabase/Tables/CDRebuildComponentTable.cpp index d5c386d1..f5706a28 100644 --- a/dDatabase/Tables/CDRebuildComponentTable.cpp +++ b/dDatabase/Tables/CDRebuildComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDRebuildComponentTable.h" -//! Constructor -CDRebuildComponentTable::CDRebuildComponentTable(void) { +void CDRebuildComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -39,7 +38,6 @@ CDRebuildComponentTable::CDRebuildComponentTable(void) { tableData.finalize(); } -//! Queries the table with a custom "where" clause std::vector CDRebuildComponentTable::Query(std::function predicate) { std::vector data = cpplinq::from(this->entries) @@ -49,8 +47,7 @@ std::vector CDRebuildComponentTable::Query(std::function CDRebuildComponentTable::GetEntries(void) const { +const std::vector& CDRebuildComponentTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDRebuildComponentTable.h b/dDatabase/Tables/CDRebuildComponentTable.h index db70a47d..fc78e904 100644 --- a/dDatabase/Tables/CDRebuildComponentTable.h +++ b/dDatabase/Tables/CDRebuildComponentTable.h @@ -21,10 +21,10 @@ private: std::vector entries; public: - CDRebuildComponentTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries() const; + const std::vector& GetEntries() const; }; diff --git a/dDatabase/Tables/CDRewardsTable.cpp b/dDatabase/Tables/CDRewardsTable.cpp index 55672add..27c2344a 100644 --- a/dDatabase/Tables/CDRewardsTable.cpp +++ b/dDatabase/Tables/CDRewardsTable.cpp @@ -1,35 +1,27 @@ #include "CDRewardsTable.h" -CDRewardsTable::CDRewardsTable(void) { +void CDRewardsTable::LoadValuesFromDatabase() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Rewards"); while (!tableData.eof()) { - CDRewards* entry = new CDRewards(); - entry->id = tableData.getIntField("id", -1); - entry->levelID = tableData.getIntField("LevelID", -1); - entry->missionID = tableData.getIntField("MissionID", -1); - entry->rewardType = tableData.getIntField("RewardType", -1); - entry->value = tableData.getIntField("value", -1); - entry->count = tableData.getIntField("count", -1); + CDRewards entry; + entry.id = tableData.getIntField("id", -1); + entry.levelID = tableData.getIntField("LevelID", -1); + entry.missionID = tableData.getIntField("MissionID", -1); + entry.rewardType = tableData.getIntField("RewardType", -1); + entry.value = tableData.getIntField("value", -1); + entry.count = tableData.getIntField("count", -1); - m_entries.insert(std::make_pair(entry->id, entry)); + m_entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); } tableData.finalize(); } -CDRewardsTable::~CDRewardsTable(void) { - for (auto e : m_entries) { - if (e.second) delete e.second; - } - - m_entries.clear(); -} - -std::vector CDRewardsTable::GetByLevelID(uint32_t levelID) { - std::vector result{}; +std::vector CDRewardsTable::GetByLevelID(uint32_t levelID) { + std::vector result{}; for (const auto& e : m_entries) { - if (e.second->levelID == levelID) result.push_back(e.second); + if (e.second.levelID == levelID) result.push_back(e.second); } return result; diff --git a/dDatabase/Tables/CDRewardsTable.h b/dDatabase/Tables/CDRewardsTable.h index 2e079a83..9c24397b 100644 --- a/dDatabase/Tables/CDRewardsTable.h +++ b/dDatabase/Tables/CDRewardsTable.h @@ -13,12 +13,11 @@ struct CDRewards { class CDRewardsTable : public CDTable { public: - CDRewardsTable(); - ~CDRewardsTable(); + void LoadValuesFromDatabase(); static const std::string GetTableName() { return "Rewards"; }; - std::vector GetByLevelID(uint32_t levelID); + std::vector GetByLevelID(uint32_t levelID); private: - std::map m_entries; + std::map m_entries; }; diff --git a/dDatabase/Tables/CDScriptComponentTable.cpp b/dDatabase/Tables/CDScriptComponentTable.cpp index 8050c139..1a922199 100644 --- a/dDatabase/Tables/CDScriptComponentTable.cpp +++ b/dDatabase/Tables/CDScriptComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDScriptComponentTable.h" -//! Constructor -CDScriptComponentTable::CDScriptComponentTable(void) { +void CDScriptComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; diff --git a/dDatabase/Tables/CDScriptComponentTable.h b/dDatabase/Tables/CDScriptComponentTable.h index 77453939..d2b7e7ae 100644 --- a/dDatabase/Tables/CDScriptComponentTable.h +++ b/dDatabase/Tables/CDScriptComponentTable.h @@ -15,7 +15,7 @@ private: CDScriptComponent m_ToReturnWhenNoneFound; public: - CDScriptComponentTable(); + void LoadValuesFromDatabase(); // Gets an entry by scriptID const CDScriptComponent& GetByID(unsigned int id); }; diff --git a/dDatabase/Tables/CDSkillBehaviorTable.cpp b/dDatabase/Tables/CDSkillBehaviorTable.cpp index c5df78ef..8ffbb5ce 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.cpp +++ b/dDatabase/Tables/CDSkillBehaviorTable.cpp @@ -1,8 +1,6 @@ #include "CDSkillBehaviorTable.h" -//#include "Logger.hpp" -//! Constructor -CDSkillBehaviorTable::CDSkillBehaviorTable(void) { +void CDSkillBehaviorTable::LoadValuesFromDatabase() { m_empty = CDSkillBehavior(); // First, get the size of the table @@ -51,13 +49,6 @@ CDSkillBehaviorTable::CDSkillBehaviorTable(void) { tableData.finalize(); } -//! Queries the table with a custom "where" clause -std::vector CDSkillBehaviorTable::Query(std::function predicate) { - std::vector data; //So MSVC shuts up - return data; -} - -//! Gets an entry by ID const CDSkillBehavior& CDSkillBehaviorTable::GetSkillByID(unsigned int skillID) { std::map::iterator it = this->entries.find(skillID); if (it != this->entries.end()) { diff --git a/dDatabase/Tables/CDSkillBehaviorTable.h b/dDatabase/Tables/CDSkillBehaviorTable.h index eb3094e0..5b1081cd 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.h +++ b/dDatabase/Tables/CDSkillBehaviorTable.h @@ -31,9 +31,7 @@ private: CDSkillBehavior m_empty; public: - CDSkillBehaviorTable(); - // Queries the table with a custom "where" clause - std::vector Query(std::function predicate); + void LoadValuesFromDatabase(); // Gets an entry by skillID const CDSkillBehavior& GetSkillByID(unsigned int skillID); diff --git a/dDatabase/Tables/CDVendorComponentTable.cpp b/dDatabase/Tables/CDVendorComponentTable.cpp index 17989dfb..0f963b04 100644 --- a/dDatabase/Tables/CDVendorComponentTable.cpp +++ b/dDatabase/Tables/CDVendorComponentTable.cpp @@ -1,7 +1,6 @@ #include "CDVendorComponentTable.h" -//! Constructor -CDVendorComponentTable::CDVendorComponentTable(void) { +void CDVendorComponentTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; @@ -45,7 +44,7 @@ std::vector CDVendorComponentTable::Query(std::function CDVendorComponentTable::GetEntries(void) const { +const std::vector& CDVendorComponentTable::GetEntries() const { return this->entries; } diff --git a/dDatabase/Tables/CDVendorComponentTable.h b/dDatabase/Tables/CDVendorComponentTable.h index f2666d7e..29854d49 100644 --- a/dDatabase/Tables/CDVendorComponentTable.h +++ b/dDatabase/Tables/CDVendorComponentTable.h @@ -16,10 +16,10 @@ private: std::vector entries; public: - CDVendorComponentTable(); + void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause std::vector Query(std::function predicate); - std::vector GetEntries(void) const; + const std::vector& GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDZoneTableTable.cpp b/dDatabase/Tables/CDZoneTableTable.cpp index bafbf8fe..1030593e 100644 --- a/dDatabase/Tables/CDZoneTableTable.cpp +++ b/dDatabase/Tables/CDZoneTableTable.cpp @@ -1,7 +1,6 @@ #include "CDZoneTableTable.h" -//! Constructor -CDZoneTableTable::CDZoneTableTable(void) { +void CDZoneTableTable::LoadValuesFromDatabase() { // First, get the size of the table unsigned int size = 0; diff --git a/dDatabase/Tables/CDZoneTableTable.h b/dDatabase/Tables/CDZoneTableTable.h index f844fd25..fef8096f 100644 --- a/dDatabase/Tables/CDZoneTableTable.h +++ b/dDatabase/Tables/CDZoneTableTable.h @@ -38,7 +38,7 @@ private: std::map m_Entries; public: - CDZoneTableTable(); + void LoadValuesFromDatabase(); // Queries the table with a zoneID to find. const CDZoneTable* Query(unsigned int zoneID); diff --git a/dGame/dComponents/LevelProgressionComponent.cpp b/dGame/dComponents/LevelProgressionComponent.cpp index 265dd8e6..9930bdef 100644 --- a/dGame/dComponents/LevelProgressionComponent.cpp +++ b/dGame/dComponents/LevelProgressionComponent.cpp @@ -56,19 +56,19 @@ void LevelProgressionComponent::HandleLevelUp() { // Tell the client we beginning to send level rewards. if (rewardingItem) GameMessages::NotifyLevelRewards(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), m_Level, rewardingItem); - for (auto* reward : rewards) { - switch (reward->rewardType) { + for (const auto& reward : rewards) { + switch (reward.rewardType) { case 0: - inventoryComponent->AddItem(reward->value, reward->count, eLootSourceType::LEVEL_REWARD); + inventoryComponent->AddItem(reward.value, reward.count, eLootSourceType::LEVEL_REWARD); break; case 4: { auto* items = inventoryComponent->GetInventory(eInventoryType::ITEMS); - items->SetSize(items->GetSize() + reward->value); + items->SetSize(items->GetSize() + reward.value); } break; case 9: - SetSpeedBase(static_cast(reward->value) ); + SetSpeedBase(static_cast(reward.value) ); controllablePhysicsComponent->SetSpeedMultiplier(GetSpeedBase() / 500.0f); break; case 11: From 598f4e16637900c83bc3ed6dc31c80050cd470bb Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 12 Aug 2023 02:11:25 -0700 Subject: [PATCH 097/111] Fix dangling pointer --- dGame/dMission/Mission.cpp | 107 +++++++++++++++++++------------------ dGame/dMission/Mission.h | 2 +- 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 34641335..085fc38b 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -42,9 +42,10 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { auto* missionsTable = CDClientManager::Instance().GetTable(); - info = missionsTable->GetPtrByMissionID(missionId); + auto* mis = missionsTable->GetPtrByMissionID(missionId); + info = *mis; - if (info == &CDMissionsTable::Default) { + if (mis == &CDMissionsTable::Default) { Game::logger->Log("Missions", "Failed to find mission (%i)!", missionId); return; @@ -137,7 +138,7 @@ void Mission::UpdateXml(tinyxml2::XMLElement* element) { element->DeleteChildren(); - element->SetAttribute("id", static_cast(info->id)); + element->SetAttribute("id", static_cast(info.id)); if (m_Completions > 0) { element->SetAttribute("cct", static_cast(m_Completions)); @@ -212,11 +213,11 @@ User* Mission::GetUser() const { } uint32_t Mission::GetMissionId() const { - return info->id; + return info.id; } const CDMissions& Mission::GetClientInfo() const { - return *info; + return info; } uint32_t Mission::GetCompletions() const { @@ -240,15 +241,15 @@ eMissionState Mission::GetMissionState() const { } bool Mission::IsAchievement() const { - return !info->isMission; + return !info.isMission; } bool Mission::IsMission() const { - return info->isMission; + return info.isMission; } bool Mission::IsRepeatable() const { - return info->repeatable; + return info.repeatable; } bool Mission::IsComplete() const { @@ -284,7 +285,7 @@ void Mission::MakeAvalible() { } void Mission::Accept() { - SetMissionTypeState(eMissionLockState::NEW, info->defined_type, info->defined_subtype); + SetMissionTypeState(eMissionLockState::NEW, info.defined_type, info.defined_subtype); SetMissionState(m_Completions > 0 ? eMissionState::COMPLETE_ACTIVE : eMissionState::ACTIVE); @@ -321,16 +322,16 @@ void Mission::Complete(const bool yieldRewards) { auto* characterComponent = entity->GetComponent(); if (characterComponent != nullptr) { - characterComponent->TrackMissionCompletion(!info->isMission); + characterComponent->TrackMissionCompletion(!info.isMission); } auto* missionComponent = entity->GetComponent(); - missionComponent->Progress(eMissionTaskType::META, info->id); + missionComponent->Progress(eMissionTaskType::META, info.id); - missionComponent->Progress(eMissionTaskType::RACING, info->id, (LWOOBJID)eRacingTaskParam::COMPLETE_ANY_RACING_TASK); + missionComponent->Progress(eMissionTaskType::RACING, info.id, (LWOOBJID)eRacingTaskParam::COMPLETE_ANY_RACING_TASK); - missionComponent->Progress(eMissionTaskType::RACING, info->id, (LWOOBJID)eRacingTaskParam::COMPLETE_TRACK_TASKS); + missionComponent->Progress(eMissionTaskType::RACING, info.id, (LWOOBJID)eRacingTaskParam::COMPLETE_TRACK_TASKS); auto* missionEmailTable = CDClientManager::Instance().GetTable(); @@ -441,24 +442,24 @@ void Mission::YieldRewards() { } int32_t coinsToSend = 0; - if (info->LegoScore > 0) { - eLootSourceType lootSource = info->isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; + if (info.LegoScore > 0) { + eLootSourceType lootSource = info.isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; 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 * Game::zoneManager->GetWorldConfig()->levelCapCurrencyConversion; + coinsToSend += info.LegoScore * Game::zoneManager->GetWorldConfig()->levelCapCurrencyConversion; } else { - characterComponent->SetUScore(characterComponent->GetUScore() + info->LegoScore); - GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), info->LegoScore, lootSource); + characterComponent->SetUScore(characterComponent->GetUScore() + info.LegoScore); + GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), info.LegoScore, lootSource); } } if (m_Completions > 0) { std::vector> items; - items.emplace_back(info->reward_item1_repeatable, info->reward_item1_repeat_count); - items.emplace_back(info->reward_item2_repeatable, info->reward_item2_repeat_count); - items.emplace_back(info->reward_item3_repeatable, info->reward_item3_repeat_count); - items.emplace_back(info->reward_item4_repeatable, info->reward_item4_repeat_count); + items.emplace_back(info.reward_item1_repeatable, info.reward_item1_repeat_count); + items.emplace_back(info.reward_item2_repeatable, info.reward_item2_repeat_count); + items.emplace_back(info.reward_item3_repeatable, info.reward_item3_repeat_count); + items.emplace_back(info.reward_item4_repeatable, info.reward_item4_repeat_count); for (const auto& pair : items) { // Some missions reward zero of an item and so they must be allowed through this clause, @@ -478,9 +479,9 @@ void Mission::YieldRewards() { inventoryComponent->AddItem(pair.first, count, IsMission() ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT); } - if (info->reward_currency_repeatable > 0 || coinsToSend > 0) { - eLootSourceType lootSource = info->isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; - character->SetCoins(character->GetCoins() + info->reward_currency_repeatable + coinsToSend, lootSource); + if (info.reward_currency_repeatable > 0 || coinsToSend > 0) { + eLootSourceType lootSource = info.isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; + character->SetCoins(character->GetCoins() + info.reward_currency_repeatable + coinsToSend, lootSource); } return; @@ -488,10 +489,10 @@ void Mission::YieldRewards() { std::vector> items; - items.emplace_back(info->reward_item1, info->reward_item1_count); - items.emplace_back(info->reward_item2, info->reward_item2_count); - items.emplace_back(info->reward_item3, info->reward_item3_count); - items.emplace_back(info->reward_item4, info->reward_item4_count); + items.emplace_back(info.reward_item1, info.reward_item1_count); + items.emplace_back(info.reward_item2, info.reward_item2_count); + items.emplace_back(info.reward_item3, info.reward_item3_count); + items.emplace_back(info.reward_item4, info.reward_item4_count); for (const auto& pair : items) { // Some missions reward zero of an item and so they must be allowed through this clause, @@ -511,58 +512,58 @@ void Mission::YieldRewards() { inventoryComponent->AddItem(pair.first, count, IsMission() ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT); } - if (info->reward_currency > 0 || coinsToSend > 0) { - eLootSourceType lootSource = info->isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; - character->SetCoins(character->GetCoins() + info->reward_currency + coinsToSend, lootSource); + if (info.reward_currency > 0 || coinsToSend > 0) { + eLootSourceType lootSource = info.isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; + character->SetCoins(character->GetCoins() + info.reward_currency + coinsToSend, lootSource); } - if (info->reward_maxinventory > 0) { + if (info.reward_maxinventory > 0) { auto* inventory = inventoryComponent->GetInventory(ITEMS); - inventory->SetSize(inventory->GetSize() + info->reward_maxinventory); + inventory->SetSize(inventory->GetSize() + info.reward_maxinventory); } - if (info->reward_bankinventory > 0) { + if (info.reward_bankinventory > 0) { auto* inventory = inventoryComponent->GetInventory(eInventoryType::VAULT_ITEMS); auto modelInventory = inventoryComponent->GetInventory(eInventoryType::VAULT_MODELS); - inventory->SetSize(inventory->GetSize() + info->reward_bankinventory); - modelInventory->SetSize(modelInventory->GetSize() + info->reward_bankinventory); + inventory->SetSize(inventory->GetSize() + info.reward_bankinventory); + modelInventory->SetSize(modelInventory->GetSize() + info.reward_bankinventory); } - if (info->reward_reputation > 0) { - missionComponent->Progress(eMissionTaskType::EARN_REPUTATION, 0, 0L, "", info->reward_reputation); + if (info.reward_reputation > 0) { + missionComponent->Progress(eMissionTaskType::EARN_REPUTATION, 0, 0L, "", info.reward_reputation); auto character = entity->GetComponent(); if (character) { - character->SetReputation(character->GetReputation() + info->reward_reputation); + character->SetReputation(character->GetReputation() + info.reward_reputation); GameMessages::SendUpdateReputation(entity->GetObjectID(), character->GetReputation(), entity->GetSystemAddress()); } } - if (info->reward_maxhealth > 0) { - destroyableComponent->SetMaxHealth(destroyableComponent->GetMaxHealth() + static_cast(info->reward_maxhealth), true); + if (info.reward_maxhealth > 0) { + destroyableComponent->SetMaxHealth(destroyableComponent->GetMaxHealth() + static_cast(info.reward_maxhealth), true); } - if (info->reward_maximagination > 0) { - destroyableComponent->SetMaxImagination(destroyableComponent->GetMaxImagination() + static_cast(info->reward_maximagination), true); + if (info.reward_maximagination > 0) { + destroyableComponent->SetMaxImagination(destroyableComponent->GetMaxImagination() + static_cast(info.reward_maximagination), true); } Game::entityManager->SerializeEntity(entity); - if (info->reward_emote > 0) { - character->UnlockEmote(info->reward_emote); + if (info.reward_emote > 0) { + character->UnlockEmote(info.reward_emote); } - if (info->reward_emote2 > 0) { - character->UnlockEmote(info->reward_emote2); + if (info.reward_emote2 > 0) { + character->UnlockEmote(info.reward_emote2); } - if (info->reward_emote3 > 0) { - character->UnlockEmote(info->reward_emote3); + if (info.reward_emote3 > 0) { + character->UnlockEmote(info.reward_emote3); } - if (info->reward_emote4 > 0) { - character->UnlockEmote(info->reward_emote4); + if (info.reward_emote4 > 0) { + character->UnlockEmote(info.reward_emote4); } } @@ -599,7 +600,7 @@ void Mission::SetMissionState(const eMissionState state, const bool sendingRewar return; } - GameMessages::SendNotifyMission(entity, entity->GetParentUser()->GetSystemAddress(), info->id, static_cast(state), sendingRewards); + GameMessages::SendNotifyMission(entity, entity->GetParentUser()->GetSystemAddress(), info.id, static_cast(state), sendingRewards); } void Mission::SetMissionTypeState(eMissionLockState state, const std::string& type, const std::string& subType) { diff --git a/dGame/dMission/Mission.h b/dGame/dMission/Mission.h index b04c3548..f7c17003 100644 --- a/dGame/dMission/Mission.h +++ b/dGame/dMission/Mission.h @@ -245,7 +245,7 @@ private: /** * The database information that corresponds to this mission */ - const CDMissions* info; + CDMissions info; /** * The current state this mission is in From c26086aff5ef186ea38e485363d6c32112225c0b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 12 Aug 2023 07:20:00 -0700 Subject: [PATCH 098/111] perf: Add path height correction on world load (#1178) * Add path height correction on world load * Increase height because Nexus Tower is tall * Update height checker - Only go up and down, do not deviate from the point you are on - As a backup, use the nearestPoint on the nearestPoly, should detour be able to find one. - Add a debug assert to fail the program should toReturn differ from nearestPoint[1]. Update dNavMesh.cpp Update dNavMesh.cpp * Fix if condition to actually return the value... --------- Co-authored-by: Aaron Kimbrell --- dNavigation/dNavMesh.cpp | 25 +++++++++++++++++++------ dNavigation/dNavMesh.h | 10 +++++++++- dZoneManager/CMakeLists.txt | 3 ++- dZoneManager/Zone.cpp | 9 +++++++++ 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/dNavigation/dNavMesh.cpp b/dNavigation/dNavMesh.cpp index fdba4a2d..14b59055 100644 --- a/dNavigation/dNavMesh.cpp +++ b/dNavigation/dNavMesh.cpp @@ -10,6 +10,7 @@ #include "BinaryPathFinder.h" #include "dZoneManager.h" +#include "DluAssert.h" dNavMesh::dNavMesh(uint32_t zoneId) { m_ZoneId = zoneId; @@ -118,7 +119,7 @@ void dNavMesh::LoadNavmesh() { m_NavMesh = mesh; } -float dNavMesh::GetHeightAtPoint(const NiPoint3& location) { +float dNavMesh::GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight) const { if (m_NavMesh == nullptr) { return location.y; } @@ -130,15 +131,27 @@ float dNavMesh::GetHeightAtPoint(const NiPoint3& location) { pos[2] = location.z; dtPolyRef nearestRef = 0; - float polyPickExt[3] = { 32.0f, 32.0f, 32.0f }; + float polyPickExt[3] = { 0.0f, halfExtentsHeight, 0.0f }; + float nearestPoint[3] = { 0.0f, 0.0f, 0.0f }; dtQueryFilter filter{}; - m_NavQuery->findNearestPoly(pos, polyPickExt, &filter, &nearestRef, 0); + auto hasPoly = m_NavQuery->findNearestPoly(pos, polyPickExt, &filter, &nearestRef, nearestPoint); m_NavQuery->getPolyHeight(nearestRef, pos, &toReturn); - - if (toReturn == 0.0f) { - toReturn = location.y; +#ifdef _DEBUG + if (toReturn != 0.0f) { + DluAssert(toReturn == nearestPoint[1]); } +#endif + if (toReturn == 0.0f) { + // If we were unable to get the poly height, but the query returned a success, just use the height of the nearest point. + // This is what seems to happen anyways and it is better than returning zero. + if (hasPoly == DT_SUCCESS) { + toReturn = nearestPoint[1]; + } else { + toReturn = location.y; + } + } + // If we failed to even find a poly, do not change the height since we have no idea what it should be. return toReturn; } diff --git a/dNavigation/dNavMesh.h b/dNavigation/dNavMesh.h index dc3db854..600b8b86 100644 --- a/dNavigation/dNavMesh.h +++ b/dNavigation/dNavMesh.h @@ -15,7 +15,15 @@ public: dNavMesh(uint32_t zoneId); ~dNavMesh(); - float GetHeightAtPoint(const NiPoint3& location); + /** + * Get the height at a point + * + * @param location The location to check for height at. This is the center of the search area. + * @param halfExtentsHeight The half extents height of the search area. This is the distance from the center to the top and bottom of the search area. + * The larger the value of halfExtentsHeight is, the larger the performance cost of the query. + * @return float The height at the point. If the point is not on the navmesh, the height of the point is returned. + */ + float GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight = 32.0f) const; std::vector GetPath(const NiPoint3& startPos, const NiPoint3& endPos, float speed = 10.0f); class dtNavMesh* GetdtNavMesh() { return m_NavMesh; } diff --git a/dZoneManager/CMakeLists.txt b/dZoneManager/CMakeLists.txt index 1dd3841b..bbb22ba7 100644 --- a/dZoneManager/CMakeLists.txt +++ b/dZoneManager/CMakeLists.txt @@ -3,4 +3,5 @@ set(DZONEMANAGER_SOURCES "dZoneManager.cpp" "Spawner.cpp" "Zone.cpp") -add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES}) +add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES}) +target_link_libraries(dZoneManager dPhysics) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 99fbd6ff..07b3d72c 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -13,6 +13,7 @@ #include "CDZoneTableTable.h" #include "Spawner.h" #include "dZoneManager.h" +#include "dpWorld.h" #include "eTriggerCommandType.h" #include "eTriggerEventType.h" @@ -554,6 +555,14 @@ void Zone::LoadPath(std::istream& file) { if (ldfConfig) waypoint.config.push_back(ldfConfig); } } + // We verify the waypoint heights against the navmesh because in many movement paths, + // the waypoint is located near 0 height, + if (path.pathType == PathType::Movement) { + if (dpWorld::Instance().IsLoaded()) { + // 2000 should be large enough for every world. + waypoint.position.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(waypoint.position, 2000.0f); + } + } path.pathWaypoints.push_back(waypoint); } m_Paths.push_back(path); From f4f13e081aa3f140082eabd21e3cfab410d6d553 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 13 Aug 2023 17:05:04 -0700 Subject: [PATCH 099/111] Update Commands.md (#1184) If this fails to build im going to be nice to people --- docs/Commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Commands.md b/docs/Commands.md index c997c3c4..85edfd3b 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -105,7 +105,7 @@ These commands are primarily for development and testing. The usage of many of t |unlock-emote|`/unlock-emote `|Unlocks for your character the emote of the given id.|8| |Set Level|`/setlevel (username)`|Sets the using entities level to the requested level. Takes an optional parameter of an in-game players username to set the level of.|8| |crash|`/crash`|Crashes the server.|9| -|rollloot|`/rollloot `|Rolls loot matrix.|9| +|rollloot|`/rollloot `|Given a `loot matrix index`, look for `item id` in that matrix `amount` times and print to the chat box statistics of rolling that loot matrix.|9| ## Detailed `/inspect` Usage From d893ecddeb52a0f802c7c68329f16e6ae5b308de Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 18 Aug 2023 14:14:40 -0500 Subject: [PATCH 100/111] Renamed RocketLaunchLUP to MultiZoneEntrance (#1185) --- dCommon/dEnums/eReplicaComponentType.h | 2 +- dGame/Entity.cpp | 8 ++++---- dGame/dComponents/CMakeLists.txt | 2 +- ...LupComponent.cpp => MultiZoneEntranceComponent.cpp} | 10 +++++----- ...unchLupComponent.h => MultiZoneEntranceComponent.h} | 9 ++++----- dGame/dComponents/RocketLaunchpadControlComponent.cpp | 4 ++-- dGame/dGameMessages/GameMessages.cpp | 8 ++++---- 7 files changed, 21 insertions(+), 22 deletions(-) rename dGame/dComponents/{RocketLaunchLupComponent.cpp => MultiZoneEntranceComponent.cpp} (72%) rename dGame/dComponents/{RocketLaunchLupComponent.h => MultiZoneEntranceComponent.h} (84%) diff --git a/dCommon/dEnums/eReplicaComponentType.h b/dCommon/dEnums/eReplicaComponentType.h index 2d24c19e..a0be9dd4 100644 --- a/dCommon/dEnums/eReplicaComponentType.h +++ b/dCommon/dEnums/eReplicaComponentType.h @@ -101,7 +101,7 @@ enum class eReplicaComponentType : uint32_t { TRADE, USER_CONTROL, IGNORE_LIST, - ROCKET_LAUNCH_LUP, + MULTI_ZONE_ENTRANCE, BUFF_REAL, // the real buff component, should just be name BUFF INTERACTION_MANAGER, DONATION_VENDOR, diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index b5abe918..b577d1f5 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -30,7 +30,7 @@ #include "Component.h" #include "ControllablePhysicsComponent.h" #include "RenderComponent.h" -#include "RocketLaunchLupComponent.h" +#include "MultiZoneEntranceComponent.h" #include "CharacterComponent.h" #include "DestroyableComponent.h" #include "BuffComponent.h" @@ -451,9 +451,9 @@ void Entity::Initialize() { m_Components.insert(std::make_pair(eReplicaComponentType::INVENTORY, comp)); } // if this component exists, then we initialize it. it's value is always 0 - if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH_LUP, -1) != -1) { - auto comp = new RocketLaunchLupComponent(this); - m_Components.insert(std::make_pair(eReplicaComponentType::ROCKET_LAUNCH_LUP, comp)); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MULTI_ZONE_ENTRANCE, -1) != -1) { + auto comp = new MultiZoneEntranceComponent(this); + m_Components.insert(std::make_pair(eReplicaComponentType::MULTI_ZONE_ENTRANCE, comp)); } /** diff --git a/dGame/dComponents/CMakeLists.txt b/dGame/dComponents/CMakeLists.txt index 67f4ece5..6c02cf0b 100644 --- a/dGame/dComponents/CMakeLists.txt +++ b/dGame/dComponents/CMakeLists.txt @@ -31,7 +31,7 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp" "RebuildComponent.cpp" "RenderComponent.cpp" "RigidbodyPhantomPhysicsComponent.cpp" - "RocketLaunchLupComponent.cpp" + "MultiZoneEntranceComponent.cpp" "RocketLaunchpadControlComponent.cpp" "ScriptedActivityComponent.cpp" "ShootingGalleryComponent.cpp" diff --git a/dGame/dComponents/RocketLaunchLupComponent.cpp b/dGame/dComponents/MultiZoneEntranceComponent.cpp similarity index 72% rename from dGame/dComponents/RocketLaunchLupComponent.cpp rename to dGame/dComponents/MultiZoneEntranceComponent.cpp index 3c326540..e5a51031 100644 --- a/dGame/dComponents/RocketLaunchLupComponent.cpp +++ b/dGame/dComponents/MultiZoneEntranceComponent.cpp @@ -1,9 +1,9 @@ -#include "RocketLaunchLupComponent.h" +#include "MultiZoneEntranceComponent.h" #include "RocketLaunchpadControlComponent.h" #include "InventoryComponent.h" #include "CharacterComponent.h" -RocketLaunchLupComponent::RocketLaunchLupComponent(Entity* parent) : Component(parent) { +MultiZoneEntranceComponent::MultiZoneEntranceComponent(Entity* parent) : Component(parent) { m_Parent = parent; std::string zoneString = GeneralUtils::UTF16ToWTF8(m_Parent->GetVar(u"MultiZoneIDs")); std::stringstream ss(zoneString); @@ -14,9 +14,9 @@ RocketLaunchLupComponent::RocketLaunchLupComponent(Entity* parent) : Component(p } } -RocketLaunchLupComponent::~RocketLaunchLupComponent() {} +MultiZoneEntranceComponent::~MultiZoneEntranceComponent() {} -void RocketLaunchLupComponent::OnUse(Entity* originator) { +void MultiZoneEntranceComponent::OnUse(Entity* originator) { auto* rocket = originator->GetComponent()->RocketEquip(originator); if (!rocket) return; @@ -24,7 +24,7 @@ void RocketLaunchLupComponent::OnUse(Entity* originator) { GameMessages::SendPropertyEntranceBegin(m_Parent->GetObjectID(), m_Parent->GetSystemAddress()); } -void RocketLaunchLupComponent::OnSelectWorld(Entity* originator, uint32_t index) { +void MultiZoneEntranceComponent::OnSelectWorld(Entity* originator, uint32_t index) { auto* rocketLaunchpadControlComponent = m_Parent->GetComponent(); if (!rocketLaunchpadControlComponent) return; diff --git a/dGame/dComponents/RocketLaunchLupComponent.h b/dGame/dComponents/MultiZoneEntranceComponent.h similarity index 84% rename from dGame/dComponents/RocketLaunchLupComponent.h rename to dGame/dComponents/MultiZoneEntranceComponent.h index 226fa1b2..9c1f4360 100644 --- a/dGame/dComponents/RocketLaunchLupComponent.h +++ b/dGame/dComponents/MultiZoneEntranceComponent.h @@ -1,7 +1,6 @@ #pragma once #include "Entity.h" -#include "GameMessages.h" #include "Component.h" #include "eReplicaComponentType.h" @@ -9,16 +8,16 @@ * Component that handles the LUP/WBL rocket launchpad that can be interacted with to travel to WBL worlds. * */ -class RocketLaunchLupComponent : public Component { +class MultiZoneEntranceComponent : public Component { public: - static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH_LUP; + static const eReplicaComponentType ComponentType = eReplicaComponentType::MULTI_ZONE_ENTRANCE; /** * Constructor for this component, builds the m_LUPWorlds vector * @param parent parent that contains this component */ - RocketLaunchLupComponent(Entity* parent); - ~RocketLaunchLupComponent() override; + MultiZoneEntranceComponent(Entity* parent); + ~MultiZoneEntranceComponent() override; /** * Handles an OnUse event from some entity, preparing it for launch to some other world diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 10908d9e..c61ede23 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -13,7 +13,7 @@ #include "ChatPackets.h" #include "MissionComponent.h" #include "PropertyEntranceComponent.h" -#include "RocketLaunchLupComponent.h" +#include "MultiZoneEntranceComponent.h" #include "dServer.h" #include "PacketUtils.h" #include "eObjectWorldState.h" @@ -94,7 +94,7 @@ void RocketLaunchpadControlComponent::OnUse(Entity* originator) { return; } - auto* rocketLaunchLUP = m_Parent->GetComponent(); + auto* rocketLaunchLUP = m_Parent->GetComponent(); if (rocketLaunchLUP) { return; } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 020e0abe..6113b1ee 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -24,7 +24,7 @@ #include "dConfig.h" #include "TeamManager.h" #include "ChatPackets.h" -#include "RocketLaunchLupComponent.h" +#include "MultiZoneEntranceComponent.h" #include "eUnequippableActiveType.h" #include "eMovementPlatformState.h" #include "LeaderboardManager.h" @@ -2795,9 +2795,9 @@ void GameMessages::HandleEnterProperty(RakNet::BitStream* inStream, Entity* enti return; } - auto rocketLaunchLupComponent = entity->GetComponent(); - if (rocketLaunchLupComponent != nullptr) { - rocketLaunchLupComponent->OnSelectWorld(player, index); + auto multiZoneEntranceComponent = entity->GetComponent(); + if (multiZoneEntranceComponent != nullptr) { + multiZoneEntranceComponent->OnSelectWorld(player, index); } } From 2e386d29dfc58d2b2b963a67e10357c179b9fe4c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 18 Aug 2023 18:58:27 -0500 Subject: [PATCH 101/111] fix: Limit the number of players that can join a team (#1187) * Limit the number of players that can join a team after being invited * Notify player if they weren't added to the team * check pointer --- dChatServer/PlayerContainer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index 689ffd77..4e4da6f2 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -10,6 +10,7 @@ #include "Database.h" #include "eConnectionType.h" #include "eChatInternalMessageType.h" +#include "ChatPackets.h" PlayerContainer::PlayerContainer() { } @@ -207,6 +208,14 @@ TeamData* PlayerContainer::GetTeam(LWOOBJID playerID) { } void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) { + if (team->memberIDs.size() >= 4){ + Game::logger->Log("PlayerContainer", "Tried to add player to team that already had 4 players"); + auto* player = GetPlayerData(playerID); + if (!player) return; + ChatPackets::SendSystemMessage(player->sysAddr, u"The teams is full! You have not been added to a team!"); + return; + } + const auto index = std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID); if (index != team->memberIDs.end()) return; From ca78a166d94d603835e4f45cfedca8a9d3fb6639 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 19 Sep 2023 05:59:02 -0500 Subject: [PATCH 102/111] fix #1194 (#1196) --- dGame/dComponents/MultiZoneEntranceComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dComponents/MultiZoneEntranceComponent.cpp b/dGame/dComponents/MultiZoneEntranceComponent.cpp index e5a51031..7c2e2b79 100644 --- a/dGame/dComponents/MultiZoneEntranceComponent.cpp +++ b/dGame/dComponents/MultiZoneEntranceComponent.cpp @@ -21,7 +21,7 @@ void MultiZoneEntranceComponent::OnUse(Entity* originator) { if (!rocket) return; // the LUP world menu is just the property menu, the client knows how to handle it - GameMessages::SendPropertyEntranceBegin(m_Parent->GetObjectID(), m_Parent->GetSystemAddress()); + GameMessages::SendPropertyEntranceBegin(m_Parent->GetObjectID(), originator->GetSystemAddress()); } void MultiZoneEntranceComponent::OnSelectWorld(Entity* originator, uint32_t index) { From 08020cd86d5722497e7030a0752233eaa36d72dc Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Wed, 20 Sep 2023 20:06:28 -0500 Subject: [PATCH 103/111] chore: cleanup LU(W)string writing (#1188) * chore: cleanup LU(W)string writing and add methods for reading remove redunent "packet" from packet reading helpers move write header to bitstreamutils since it's not packet related add tests for reading/writing LU(W)Strings * remove un-needed function defintions in header * make reading and writing more efficient * p p * quotes * remove unneeded default --------- Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> --- dChatServer/ChatPacketHandler.cpp | 79 ++++++------ dChatServer/PlayerContainer.cpp | 6 +- dCommon/dEnums/dCommonVars.h | 3 +- dGame/UserManager.cpp | 33 ++--- dGame/dBehaviors/BehaviorContext.cpp | 4 +- .../RocketLaunchpadControlComponent.cpp | 4 +- .../dComponents/ScriptedActivityComponent.cpp | 4 +- dGame/dComponents/SkillComponent.cpp | 6 +- dGame/dGameMessages/GameMessageHandler.cpp | 6 +- dGame/dGameMessages/GameMessages.cpp | 16 +-- dGame/dUtilities/Mail.cpp | 13 +- dGame/dUtilities/SlashCommandHandler.cpp | 8 +- dMasterServer/InstanceManager.cpp | 6 +- dMasterServer/MasterServer.cpp | 9 +- dNet/AuthPackets.cpp | 54 ++++---- dNet/BitStreamUtils.h | 104 +++++++++++++++ dNet/ChatPackets.cpp | 11 +- dNet/MasterPackets.cpp | 21 +-- dNet/PacketUtils.cpp | 83 +----------- dNet/PacketUtils.h | 23 +--- dNet/WorldPackets.cpp | 31 ++--- dNet/ZoneInstanceManager.cpp | 8 +- dNet/dServer.cpp | 5 +- dWorldServer/WorldServer.cpp | 31 ++--- tests/dCommonTests/CMakeLists.txt | 2 + tests/dCommonTests/TestLUString.cpp | 121 ++++++++++++++++++ tests/dCommonTests/TestLUWString.cpp | 121 ++++++++++++++++++ 27 files changed, 537 insertions(+), 275 deletions(-) create mode 100644 dNet/BitStreamUtils.h create mode 100644 tests/dCommonTests/TestLUString.cpp create mode 100644 tests/dCommonTests/TestLUWString.cpp diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index 878cc71c..3d6fca31 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -3,6 +3,7 @@ #include "Database.h" #include #include "PacketUtils.h" +#include "BitStreamUtils.h" #include "Game.h" #include "dServer.h" #include "GeneralUtils.h" @@ -75,11 +76,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { //Now, we need to send the friendlist to the server they came from: CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE); bitStream.Write(0); bitStream.Write(1); //Length of packet -- just writing one as it doesn't matter, client skips it. bitStream.Write((uint16_t)friends.size()); @@ -412,21 +413,21 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) { const auto otherName = std::string(otherMember->playerName.c_str()); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(otherMember->playerID); - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); bitStream.Write(otherMember->playerID); bitStream.Write(8); bitStream.Write(69); - PacketUtils::WritePacketWString(senderName, 33, &bitStream); + bitStream.Write(LUWString(senderName)); bitStream.Write(sender->playerID); bitStream.Write(0); bitStream.Write(0); //not mythran nametag - PacketUtils::WritePacketWString(otherName, 33, &bitStream); + bitStream.Write(LUWString(otherName)); bitStream.Write(0); //not mythran for receiver bitStream.Write(0); //teams? - PacketUtils::WritePacketWString(message, 512, &bitStream); + bitStream.Write(LUWString(message, 512)); SystemAddress sysAddr = otherMember->sysAddr; SEND_PACKET; @@ -434,7 +435,7 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) { } void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { - LWOOBJID senderID = PacketUtils::ReadPacketS64(0x08, packet); + LWOOBJID senderID = PacketUtils::ReadS64(0x08, packet); std::string receiverName = PacketUtils::ReadString(0x66, packet, true); std::string message = PacketUtils::ReadString(0xAA, packet, true, 512); @@ -451,21 +452,21 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { //To the sender: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(goonA->playerID); - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); bitStream.Write(goonA->playerID); bitStream.Write(7); bitStream.Write(69); - PacketUtils::WritePacketWString(goonAName, 33, &bitStream); + bitStream.Write(LUWString(goonAName)); bitStream.Write(goonA->playerID); bitStream.Write(0); bitStream.Write(0); //not mythran nametag - PacketUtils::WritePacketWString(goonBName, 33, &bitStream); + bitStream.Write(LUWString(goonBName)); bitStream.Write(0); //not mythran for receiver bitStream.Write(0); //success - PacketUtils::WritePacketWString(message, 512, &bitStream); + bitStream.Write(LUWString(message, 512)); SystemAddress sysAddr = goonA->sysAddr; SEND_PACKET; @@ -474,21 +475,21 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { //To the receiver: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(goonB->playerID); - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); bitStream.Write(goonA->playerID); bitStream.Write(7); bitStream.Write(69); - PacketUtils::WritePacketWString(goonAName, 33, &bitStream); + bitStream.Write(LUWString(goonAName)); bitStream.Write(goonA->playerID); bitStream.Write(0); bitStream.Write(0); //not mythran nametag - PacketUtils::WritePacketWString(goonBName, 33, &bitStream); + bitStream.Write(LUWString(goonBName)); bitStream.Write(0); //not mythran for receiver bitStream.Write(3); //new whisper - PacketUtils::WritePacketWString(message, 512, &bitStream); + bitStream.Write(LUWString(message, 512)); SystemAddress sysAddr = goonB->sysAddr; SEND_PACKET; @@ -709,13 +710,13 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) { void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE); - PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); + bitStream.Write(LUWString(sender->playerName.c_str())); bitStream.Write(sender->playerID); SystemAddress sysAddr = receiver->sysAddr; @@ -724,7 +725,7 @@ void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -751,7 +752,7 @@ void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeader void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -776,7 +777,7 @@ void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderI void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64PlayerID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -793,7 +794,7 @@ void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64Play void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -822,7 +823,7 @@ void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTria void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -848,7 +849,7 @@ void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband void ChatPacketHandler::SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -882,16 +883,16 @@ void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* pla [bool] - is FTP*/ CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(friendData->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY); bitStream.Write(notifyType); std::string playerName = playerData->playerName.c_str(); - PacketUtils::WritePacketWString(playerName, 33, &bitStream); + bitStream.Write(LUWString(playerName)); bitStream.Write(playerData->zoneID.GetMapID()); bitStream.Write(playerData->zoneID.GetInstanceID()); @@ -921,12 +922,12 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send } CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST); - PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST); + bitStream.Write(LUWString(sender->playerName.c_str())); bitStream.Write(0); // This is a BFF flag however this is unused in live and does not have an implementation client side. SystemAddress sysAddr = receiver->sysAddr; @@ -937,16 +938,16 @@ void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sen if (!receiver || !sender) return; CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); // Portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE); bitStream.Write(responseCode); // For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver. bitStream.Write(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS); // Then write the player name - PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); + bitStream.Write(LUWString(sender->playerName.c_str())); // Then if this is an acceptance code, write the following extra info. if (responseCode == eAddFriendResponseType::ACCEPTED) { bitStream.Write(sender->playerID); @@ -962,13 +963,13 @@ void ChatPacketHandler::SendRemoveFriend(PlayerData* receiver, std::string& pers if (!receiver) return; CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE); bitStream.Write(isSuccessful); //isOnline - PacketUtils::WritePacketWString(personToRemove, 33, &bitStream); + bitStream.Write(LUWString(personToRemove)); SystemAddress sysAddr = receiver->sysAddr; SEND_PACKET; diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index 4e4da6f2..e49630ed 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -6,7 +6,7 @@ #include "dLogger.h" #include "ChatPacketHandler.h" #include "GeneralUtils.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include "Database.h" #include "eConnectionType.h" #include "eChatInternalMessageType.h" @@ -147,7 +147,7 @@ void PlayerContainer::CreateTeamServer(Packet* packet) { void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); bitStream.Write(player); bitStream.Write(time); @@ -354,7 +354,7 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) { void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::TEAM_UPDATE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::TEAM_UPDATE); bitStream.Write(team->teamID); bitStream.Write(deleteTeam); diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index f67145da..dc7a1d54 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -9,6 +9,7 @@ #include "BitStream.h" #include "eConnectionType.h" #include "eClientMessageType.h" +#include "BitStreamUtils.h" #pragma warning (disable:4251) //Disables SQL warnings @@ -32,7 +33,7 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate); #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 CMSGHEADER BitStreamUtils::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/dGame/UserManager.cpp b/dGame/UserManager.cpp index 9e409019..e0951405 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -28,6 +28,7 @@ #include "eRenameResponse.h" #include "eConnectionType.h" #include "eChatInternalMessageType.h" +#include "BitStreamUtils.h" UserManager* UserManager::m_Address = nullptr; @@ -251,21 +252,21 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) std::string name = PacketUtils::ReadString(8, packet, true); - uint32_t firstNameIndex = PacketUtils::ReadPacketU32(74, packet); - uint32_t middleNameIndex = PacketUtils::ReadPacketU32(78, packet); - uint32_t lastNameIndex = PacketUtils::ReadPacketU32(82, packet); + uint32_t firstNameIndex = PacketUtils::ReadU32(74, packet); + uint32_t middleNameIndex = PacketUtils::ReadU32(78, packet); + uint32_t lastNameIndex = PacketUtils::ReadU32(82, packet); std::string predefinedName = GetPredefinedName(firstNameIndex, middleNameIndex, lastNameIndex); - uint32_t shirtColor = PacketUtils::ReadPacketU32(95, packet); - uint32_t shirtStyle = PacketUtils::ReadPacketU32(99, packet); - uint32_t pantsColor = PacketUtils::ReadPacketU32(103, packet); - uint32_t hairStyle = PacketUtils::ReadPacketU32(107, packet); - uint32_t hairColor = PacketUtils::ReadPacketU32(111, packet); - uint32_t lh = PacketUtils::ReadPacketU32(115, packet); - uint32_t rh = PacketUtils::ReadPacketU32(119, packet); - uint32_t eyebrows = PacketUtils::ReadPacketU32(123, packet); - uint32_t eyes = PacketUtils::ReadPacketU32(127, packet); - uint32_t mouth = PacketUtils::ReadPacketU32(131, packet); + uint32_t shirtColor = PacketUtils::ReadU32(95, packet); + uint32_t shirtStyle = PacketUtils::ReadU32(99, packet); + uint32_t pantsColor = PacketUtils::ReadU32(103, packet); + uint32_t hairStyle = PacketUtils::ReadU32(107, packet); + uint32_t hairColor = PacketUtils::ReadU32(111, packet); + uint32_t lh = PacketUtils::ReadU32(115, packet); + uint32_t rh = PacketUtils::ReadU32(119, packet); + uint32_t eyebrows = PacketUtils::ReadU32(123, packet); + uint32_t eyes = PacketUtils::ReadU32(127, packet); + uint32_t mouth = PacketUtils::ReadU32(131, packet); LOT shirtLOT = FindCharShirtID(shirtColor, shirtStyle); LOT pantsLOT = FindCharPantsID(pantsColor); @@ -387,7 +388,7 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) return; } - LWOOBJID objectID = PacketUtils::ReadPacketS64(8, packet); + LWOOBJID objectID = PacketUtils::ReadS64(8, packet); uint32_t charID = static_cast(objectID); Game::logger->Log("UserManager", "Received char delete req for ID: %llu (%u)", objectID, charID); @@ -423,7 +424,7 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) stmt->execute(); delete stmt; CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); bitStream.Write(objectID); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } @@ -483,7 +484,7 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet) return; } - LWOOBJID objectID = PacketUtils::ReadPacketS64(8, packet); + LWOOBJID objectID = PacketUtils::ReadS64(8, packet); GeneralUtils::ClearBit(objectID, eObjectBits::CHARACTER); GeneralUtils::ClearBit(objectID, eObjectBits::PERSISTENT); diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index 43ba8457..91276b80 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -6,7 +6,7 @@ #include "Game.h" #include "dLogger.h" #include "dServer.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include @@ -253,7 +253,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) { // Write message RakNet::BitStream message; - PacketUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); message.Write(this->originator); echo.Serialize(&message); diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index c61ede23..34c34dd1 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -15,7 +15,7 @@ #include "PropertyEntranceComponent.h" #include "MultiZoneEntranceComponent.h" #include "dServer.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include "eObjectWorldState.h" #include "eConnectionType.h" #include "eMasterMessageType.h" @@ -137,7 +137,7 @@ LWOCLONEID RocketLaunchpadControlComponent::GetSelectedCloneId(LWOOBJID player) void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PREP_ZONE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PREP_ZONE); bitStream.Write(zoneID); Game::server->SendToMaster(&bitStream); } diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index e971aa30..2aae6297 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -11,7 +11,7 @@ #include "EntityManager.h" #include "ChatPackets.h" #include "Player.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include "dServer.h" #include "GeneralUtils.h" #include "dZoneManager.h" @@ -516,7 +516,7 @@ void ActivityInstance::StartZone() { // only make a team if we have more than one participant if (participants.size() > 1) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::CREATE_TEAM); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::CREATE_TEAM); bitStream.Write(leader->GetObjectID()); bitStream.Write(m_Participants.size()); diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index c32e1b43..13cf98f6 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -15,7 +15,7 @@ #include "dServer.h" #include "EntityManager.h" #include "Game.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include "BaseCombatAIComponent.h" #include "ScriptComponent.h" #include "BuffComponent.h" @@ -304,7 +304,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c // Write message RakNet::BitStream message; - PacketUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); message.Write(this->m_Parent->GetObjectID()); start.Serialize(&message); @@ -437,7 +437,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) RakNet::BitStream message; - PacketUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); message.Write(this->m_Parent->GetObjectID()); projectileImpact.Serialize(&message); diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 99592ed2..b2af8ca7 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -5,7 +5,7 @@ #include "GameMessageHandler.h" #include "MissionComponent.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include "dServer.h" #include "../thirdparty/raknet/Source/RakNetworkFactory.h" #include @@ -315,7 +315,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System if (success) { //Broadcast our startSkill: RakNet::BitStream bitStreamLocal; - PacketUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); bitStreamLocal.Write(entity->GetObjectID()); EchoStartSkill echoStartSkill; @@ -337,7 +337,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case eGameMessageType::SYNC_SKILL: { RakNet::BitStream bitStreamLocal; - PacketUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitStreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); bitStreamLocal.Write(entity->GetObjectID()); //bitStreamLocal.Write((unsigned short)eGameMessageType::ECHO_SYNC_SKILL); //bitStreamLocal.Write(inStream); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 6113b1ee..83f832b2 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2,6 +2,7 @@ #include "User.h" #include "Entity.h" #include "PacketUtils.h" +#include "BitStreamUtils.h" #include "BitStream.h" #include "Game.h" #include "SlashCommandHandler.h" @@ -173,7 +174,7 @@ void GameMessages::SendPlayAnimation(Entity* entity, const std::u16string& anima bitStream.Write(eGameMessageType::PLAY_ANIMATION); bitStream.Write(animationIDLength); - PacketUtils::WriteWString(bitStream, animationName, animationIDLength); + bitStream.Write(LUWString(animationName, animationIDLength)); bitStream.Write(bExpectAnimToExist); @@ -326,13 +327,6 @@ void GameMessages::SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& s bitStream.Write(static_cast(audioGUID[k])); } - //PacketUtils::WriteString(bitStream, audioGUID, audioGUID.size()); - - //bitStream.Write(uint32_t(audioGUID.size())); - //for (char character : audioGUID) { - // bitStream.Write(character); - //} - bitStream.Write(uint32_t(0)); bitStream.Write0(); bitStream.Write0(); @@ -2181,7 +2175,7 @@ void GameMessages::HandleUnUseModel(RakNet::BitStream* inStream, Entity* entity, if (unknown) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); bitStream.Write(LWOOBJID_EMPTY); //always zero so that a check on the client passes bitStream.Write(eBlueprintSaveResponseType::PlacementFailed); // Sending a non-zero error code here prevents the client from deleting its in progress build for some reason? bitStream.Write(0); @@ -2433,7 +2427,7 @@ void GameMessages::HandleBBBLoadItemRequest(RakNet::BitStream* inStream, Entity* void GameMessages::SendBlueprintLoadItemResponse(const SystemAddress& sysAddr, bool success, LWOOBJID oldItemId, LWOOBJID newItemId) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_LOAD_RESPONSE_ITEMID); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_LOAD_RESPONSE_ITEMID); bitStream.Write(static_cast(success)); bitStream.Write(oldItemId); bitStream.Write(newItemId); @@ -2681,7 +2675,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent //Tell the client their model is saved: (this causes us to actually pop out of our current state): CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); bitStream.Write(localId); bitStream.Write(eBlueprintSaveResponseType::EverythingWorked); bitStream.Write(1); diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index d33af6dc..a828efa0 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -13,6 +13,7 @@ #include "Entity.h" #include "Character.h" #include "PacketUtils.h" +#include "BitStreamUtils.h" #include "dLogger.h" #include "EntityManager.h" #include "InventoryComponent.h" @@ -283,7 +284,7 @@ void Mail::HandleDataRequest(RakNet::BitStream* packet, const SystemAddress& sys sql::ResultSet* res = stmt->executeQuery(); RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::MailData)); bitStream.Write(int(0)); @@ -406,7 +407,7 @@ void Mail::HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t obje void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::SendResponse)); bitStream.Write(int(response)); Game::server->Send(&bitStream, sysAddr, false); @@ -414,7 +415,7 @@ void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse respo void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); uint64_t messageType = 2; uint64_t s1 = 0; uint64_t s2 = 0; @@ -433,7 +434,7 @@ void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) { void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::AttachmentCollectConfirm)); bitStream.Write(int(0)); //unknown bitStream.Write(mailID); @@ -442,7 +443,7 @@ void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t ma void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::MailDeleteConfirm)); bitStream.Write(int(0)); //unknown bitStream.Write(mailID); @@ -456,7 +457,7 @@ void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOO void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::MailReadConfirm)); bitStream.Write(int(0)); //unknown bitStream.Write(mailID); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 03e3cc89..95fe7472 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -49,7 +49,7 @@ #include "dpWorld.h" #include "Item.h" #include "PropertyManagementComponent.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include "Loot.h" #include "EntityInfo.h" #include "LUTriggers.h" @@ -761,7 +761,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == eGameMasterLevel::OPERATOR) { //Tell the master server that we're going to be shutting down whole "universe": CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_UNIVERSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_UNIVERSE); Game::server->SendToMaster(&bitStream); ChatPackets::SendSystemMessage(sysAddr, u"Sent universe shutdown notification to master."); @@ -1092,7 +1092,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //Notify chat about it CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); bitStream.Write(characterId); bitStream.Write(expire); @@ -2013,7 +2013,7 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std:: //Notify chat about it CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ANNOUNCEMENT); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ANNOUNCEMENT); bitStream.Write(title.size()); for (auto character : title) { diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index 50f55b72..9ef3077a 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -8,7 +8,7 @@ #include "CDClientManager.h" #include "CDZoneTableTable.h" #include "MasterPackets.h" -#include "PacketUtils.h" +#include "BitStreamUtils.h" #include "BinaryPathFinder.h" #include "eConnectionType.h" #include "eMasterMessageType.h" @@ -202,7 +202,7 @@ void InstanceManager::RequestAffirmation(Instance* instance, const PendingInstan CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_REQUEST); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_REQUEST); bitStream.Write(request.id); @@ -406,7 +406,7 @@ bool Instance::GetShutdownComplete() const { void Instance::Shutdown() { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); Game::server->Send(&bitStream, this->m_SysAddr, false); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index f56cad7f..94257471 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -42,6 +42,7 @@ #include "ObjectIDManager.h" #include "PacketUtils.h" #include "FdbToSqlite.h" +#include "BitStreamUtils.h" namespace Game { dLogger* logger = nullptr; @@ -632,7 +633,7 @@ void HandlePacket(Packet* packet) { activeSessions.erase(it.first); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::NEW_SESSION_ALERT); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::NEW_SESSION_ALERT); bitStream.Write(sessionKey); bitStream.Write(username.size()); for (auto character : username) { @@ -657,9 +658,9 @@ void HandlePacket(Packet* packet) { for (auto key : activeSessions) { if (key.second == username) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SESSION_KEY_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SESSION_KEY_RESPONSE); bitStream.Write(key.first); - PacketUtils::WriteString(bitStream, key.second, 64); + bitStream.Write(LUString(key.second, 64)); Game::server->Send(&bitStream, packet->systemAddress, false); break; } @@ -903,7 +904,7 @@ void ShutdownSequence(int32_t signal) { { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true); Game::logger->Log("MasterServer", "Triggered master shutdown"); } diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 4d0d2fad..3fe9b35b 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -1,5 +1,6 @@ #include "AuthPackets.h" #include "PacketUtils.h" +#include "BitStreamUtils.h" #include "dNetCommon.h" #include "dServer.h" @@ -39,7 +40,7 @@ void AuthPackets::HandleHandshake(dServer* server, Packet* packet) { void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM); uint32_t netVersion; if (!GeneralUtils::TryParse(Game::config->GetValue("client_net_version"), netVersion)) { Game::logger->Log("AuthPackets", "Failed to parse client_net_version. Cannot authenticate to %s:%i", nextServerIP.c_str(), nextServerPort); @@ -197,20 +198,19 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) { void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username) { RakNet::BitStream packet; - PacketUtils::WriteHeader(packet, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE); + BitStreamUtils::WriteHeader(packet, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE); packet.Write(static_cast(responseCode)); - PacketUtils::WritePacketString("Talk_Like_A_Pirate", 33, &packet); - - // 7 unknown strings - perhaps other IP addresses? - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); + // Event Gating + packet.Write(LUString("Talk_Like_A_Pirate")); + packet.Write(LUString("")); + packet.Write(LUString("")); + packet.Write(LUString("")); + packet.Write(LUString("")); + packet.Write(LUString("")); + packet.Write(LUString("")); + packet.Write(LUString("")); packet.Write(static_cast(1)); // Version Major packet.Write(static_cast(10)); // Version Current @@ -220,34 +220,34 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd uint32_t sessionKey = GeneralUtils::GenerateRandomNumber(); std::string userHash = std::to_string(sessionKey); userHash = md5(userHash); - PacketUtils::WritePacketWString(userHash, 33, &packet); + packet.Write(LUWString(userHash)); // Write the Character and Chat IPs - PacketUtils::WritePacketString(wServerIP, 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); + packet.Write(LUString(wServerIP)); + packet.Write(LUString("")); // Write the Character and Chat Ports packet.Write(static_cast(wServerPort)); packet.Write(static_cast(0)); - // Write another IP - PacketUtils::WritePacketString("", 33, &packet); + // CDN Key + packet.Write(LUString("")); - // Write a GUID or something... - PacketUtils::WritePacketString("00000000-0000-0000-0000-000000000000", 37, &packet); + // CDN Ticket + packet.Write(LUString("00000000-0000-0000-0000-000000000000", 37)); - packet.Write(static_cast(0)); // ??? + packet.Write(static_cast(0)); // Language // Write the localization - PacketUtils::WritePacketString("US", 3, &packet); + packet.Write(LUString("US", 3)); - packet.Write(static_cast(false)); // User first logged in? - packet.Write(static_cast(false)); // User is F2P? - packet.Write(static_cast(0)); // ??? + packet.Write(static_cast(false)); // Just upgraded from F2P + packet.Write(static_cast(false)); // User is F2P + packet.Write(static_cast(0)); // Time Remaining in F2P // Write custom error message packet.Write(static_cast(errorMsg.length())); - PacketUtils::WritePacketWString(errorMsg, static_cast(errorMsg.length()), &packet); + packet.Write(LUWString(errorMsg, static_cast(errorMsg.length()))); // Here write auth logs packet.Write(static_cast(20)); @@ -263,9 +263,9 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd //Inform the master server that we've created a session for this user: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY); bitStream.Write(sessionKey); - PacketUtils::WriteString(bitStream, username, 66); + bitStream.Write(LUString(username, 66)); server->SendToMaster(&bitStream); server->GetLogger()->Log("AuthPackets", "Set sessionKey: %i for user %s", sessionKey, username.c_str()); diff --git a/dNet/BitStreamUtils.h b/dNet/BitStreamUtils.h new file mode 100644 index 00000000..6daa1c17 --- /dev/null +++ b/dNet/BitStreamUtils.h @@ -0,0 +1,104 @@ +#ifndef __BITSTREAMUTILS__H__ +#define __BITSTREAMUTILS__H__ + +#include "GeneralUtils.h" +#include "MessageIdentifiers.h" +#include "BitStream.h" +#include + +enum class eConnectionType : uint16_t; + +struct LUString { + std::string string; + uint32_t size; + + LUString(uint32_t size) { + this->size = size; + }; + LUString(std::string string, uint32_t size = 33) { + this->string = string; + this->size = size; + }; + std::u16string GetAsU16String() const { + return GeneralUtils::ASCIIToUTF16(this->string); + }; +}; + +struct LUWString { + std::u16string string; + uint32_t size; + + LUWString(uint32_t size) { + this->size = size; + }; + LUWString(std::u16string string, uint32_t size = 33) { + this->string = string; + this->size = size; + }; + LUWString(std::string string, uint32_t size = 33) { + this->string = GeneralUtils::ASCIIToUTF16(string); + this->size = size; + }; + std::string GetAsString() const { + return GeneralUtils::UTF16ToWTF8(this->string); + }; +}; + +namespace BitStreamUtils { + template + void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) { + bitStream.Write(MessageID(ID_USER_PACKET_ENUM)); + bitStream.Write(connectionType); + bitStream.Write(static_cast(internalPacketID)); + bitStream.Write(0); + } + +} + +namespace RakNet { +#ifndef __BITSTREAM_NATIVE_END +#error No definition for big endian reading of LUString +#endif + + template <> + inline bool RakNet::BitStream::Read(LUString& value) { + value.string.resize(value.size); + bool res = ReadBits(reinterpret_cast(value.string.data()), BYTES_TO_BITS(value.string.size()), true); + if (!res) return false; + value.string.erase(std::find(value.string.begin(), value.string.end(), '\0'), value.string.end()); + return res; + } + + template <> + inline bool RakNet::BitStream::Read(LUWString& value) { + value.string.resize(value.size); + bool res = ReadBits(reinterpret_cast(value.string.data()), BYTES_TO_BITS(value.string.size()) * sizeof(std::u16string::value_type), true); + if (!res) return false; + value.string.erase(std::find(value.string.begin(), value.string.end(), u'\0'), value.string.end()); + return res; + } + + template <> + inline void RakNet::BitStream::Write(std::string value) { + this->WriteBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size())); + } + + template <> + inline void RakNet::BitStream::Write(std::u16string value) { + this->WriteBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size()) * sizeof(std::u16string::value_type)); + } + + template <> + inline void RakNet::BitStream::Write(LUString value) { + value.string.resize(value.size); + this->Write(value.string); + } + + template <> + inline void RakNet::BitStream::Write(LUWString value) { + value.string.resize(value.size); + this->Write(value.string); + } +}; + +#endif //!__BITSTREAMUTILS__H__ diff --git a/dNet/ChatPackets.cpp b/dNet/ChatPackets.cpp index 41661523..20f8aafa 100644 --- a/dNet/ChatPackets.cpp +++ b/dNet/ChatPackets.cpp @@ -8,19 +8,20 @@ #include "BitStream.h" #include "Game.h" #include "PacketUtils.h" +#include "BitStreamUtils.h" #include "dServer.h" #include "eConnectionType.h" #include "eChatMessageType.h" void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel, const std::string& senderName, LWOOBJID playerObjectID, bool senderMythran, const std::u16string& message) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); bitStream.Write(static_cast(0)); bitStream.Write(chatChannel); bitStream.Write(static_cast(message.size())); - PacketUtils::WriteWString(bitStream, senderName, 33); + bitStream.Write(LUWString(senderName)); bitStream.Write(playerObjectID); bitStream.Write(static_cast(0)); @@ -36,13 +37,13 @@ void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel void ChatPackets::SendSystemMessage(const SystemAddress& sysAddr, const std::u16string& message, const bool broadcast) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); bitStream.Write(static_cast(0)); bitStream.Write(static_cast(4)); bitStream.Write(static_cast(message.size())); - PacketUtils::WriteWString(bitStream, "", 33); + bitStream.Write(LUWString("", 33)); bitStream.Write(static_cast(0)); bitStream.Write(static_cast(0)); @@ -68,7 +69,7 @@ void ChatPackets::SendMessageFail(const SystemAddress& sysAddr) { //0x01 - "Upgrade to a full LEGO Universe Membership to chat with other players." CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SEND_CANNED_TEXT); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SEND_CANNED_TEXT); bitStream.Write(0); //response type, options above ^ //docs say there's a wstring here-- no idea what it's for, or if it's even needed so leaving it as is for now. SEND_PACKET; diff --git a/dNet/MasterPackets.cpp b/dNet/MasterPackets.cpp index 4233a37d..03330cc9 100644 --- a/dNet/MasterPackets.cpp +++ b/dNet/MasterPackets.cpp @@ -5,19 +5,20 @@ #include "dServer.h" #include "eConnectionType.h" #include "eMasterMessageType.h" +#include "BitStreamUtils.h" #include void MasterPackets::SendPersistentIDRequest(dServer* server, uint64_t requestID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID); bitStream.Write(requestID); server->SendToMaster(&bitStream); } void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, uint32_t objID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE); bitStream.Write(requestID); bitStream.Write(objID); @@ -27,7 +28,7 @@ void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddres void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t cloneID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER); bitStream.Write(requestID); bitStream.Write(static_cast(mythranShift)); @@ -39,7 +40,7 @@ void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID, void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint32_t cloneID, const std::string& password) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::CREATE_PRIVATE_ZONE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::CREATE_PRIVATE_ZONE); bitStream.Write(zoneID); bitStream.Write(cloneID); @@ -54,7 +55,7 @@ void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID, bool mythranShift, const std::string& password) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PRIVATE_ZONE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PRIVATE_ZONE); bitStream.Write(requestID); bitStream.Write(static_cast(mythranShift)); @@ -69,7 +70,7 @@ void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID, void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCEID instanceId) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::WORLD_READY); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::WORLD_READY); bitStream.Write(zoneId); bitStream.Write(instanceId); @@ -79,7 +80,7 @@ void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCE void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, const std::string& serverIP, uint32_t serverPort) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE); bitStream.Write(requestID); bitStream.Write(static_cast(mythranShift)); @@ -87,7 +88,7 @@ void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddres bitStream.Write(zoneInstance); bitStream.Write(zoneClone); bitStream.Write(static_cast(serverPort)); - PacketUtils::WriteString(bitStream, serverIP, static_cast(serverIP.size() + 1)); + bitStream.Write(LUString(serverIP, static_cast(serverIP.size() + 1))); server->Send(&bitStream, sysAddr, false); } @@ -111,13 +112,13 @@ void MasterPackets::HandleServerInfo(Packet* packet) { void MasterPackets::SendServerInfo(dServer* server, Packet* packet) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SERVER_INFO); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SERVER_INFO); bitStream.Write(server->GetPort()); bitStream.Write(server->GetZoneID()); bitStream.Write(server->GetInstanceID()); bitStream.Write(server->GetServerType()); - PacketUtils::WriteString(bitStream, server->GetIP(), server->GetIP().size()); + bitStream.Write(LUString(server->GetIP(), server->GetIP().size())); server->SendToMaster(&bitStream); } diff --git a/dNet/PacketUtils.cpp b/dNet/PacketUtils.cpp index 77b314d6..c1929826 100644 --- a/dNet/PacketUtils.cpp +++ b/dNet/PacketUtils.cpp @@ -4,7 +4,7 @@ #include "dLogger.h" #include "Game.h" -uint16_t PacketUtils::ReadPacketU16(uint32_t startLoc, Packet* packet) { +uint16_t PacketUtils::ReadU16(uint32_t startLoc, Packet* packet) { if (startLoc + 2 > packet->length) return 0; std::vector t; @@ -12,7 +12,7 @@ uint16_t PacketUtils::ReadPacketU16(uint32_t startLoc, Packet* packet) { return *(uint16_t*)t.data(); } -uint32_t PacketUtils::ReadPacketU32(uint32_t startLoc, Packet* packet) { +uint32_t PacketUtils::ReadU32(uint32_t startLoc, Packet* packet) { if (startLoc + 4 > packet->length) return 0; std::vector t; @@ -22,7 +22,7 @@ uint32_t PacketUtils::ReadPacketU32(uint32_t startLoc, Packet* packet) { return *(uint32_t*)t.data(); } -uint64_t PacketUtils::ReadPacketU64(uint32_t startLoc, Packet* packet) { +uint64_t PacketUtils::ReadU64(uint32_t startLoc, Packet* packet) { if (startLoc + 8 > packet->length) return 0; std::vector t; @@ -30,7 +30,7 @@ uint64_t PacketUtils::ReadPacketU64(uint32_t startLoc, Packet* packet) { return *(uint64_t*)t.data(); } -int64_t PacketUtils::ReadPacketS64(uint32_t startLoc, Packet* packet) { +int64_t PacketUtils::ReadS64(uint32_t startLoc, Packet* packet) { if (startLoc + 8 > packet->length) return 0; std::vector t; @@ -59,81 +59,6 @@ std::string PacketUtils::ReadString(uint32_t startLoc, Packet* packet, bool wide return readString; } -void PacketUtils::WritePacketString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream) { - uint32_t size = static_cast(string.size()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream->Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream->Write(static_cast(0)); - } -} - -void PacketUtils::WriteString(RakNet::BitStream& bitStream, const std::string& s, uint32_t maxSize) { - uint32_t size = s.size(); - uint32_t emptySize = maxSize - size; - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; i++) { - bitStream.Write((char)s[i]); - } - - for (uint32_t i = 0; i < emptySize; i++) { - bitStream.Write((char)0); - } -} - -void PacketUtils::WriteWString(RakNet::BitStream& bitStream, const std::string& string, uint32_t maxSize) { - uint32_t size = static_cast(string.length()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream.Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream.Write(static_cast(0)); - } -} - -void PacketUtils::WriteWString(RakNet::BitStream& bitStream, const std::u16string& string, uint32_t maxSize) { - uint32_t size = static_cast(string.length()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream.Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream.Write(static_cast(0)); - } -} - -void PacketUtils::WritePacketWString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream) { - uint32_t size = static_cast(string.length()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream->Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream->Write(static_cast(0)); - } -} - //! Saves a packet to the filesystem void PacketUtils::SavePacket(const std::string& filename, const char* data, size_t length) { //If we don't log to the console, don't save the bin files either. This takes up a lot of time. diff --git a/dNet/PacketUtils.h b/dNet/PacketUtils.h index d07759a0..2afd53c7 100644 --- a/dNet/PacketUtils.h +++ b/dNet/PacketUtils.h @@ -8,26 +8,11 @@ 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(static_cast(internalPacketID)); - bitStream.Write(0); - } - - uint16_t ReadPacketU16(uint32_t startLoc, Packet* packet); - uint32_t ReadPacketU32(uint32_t startLoc, Packet* packet); - uint64_t ReadPacketU64(uint32_t startLoc, Packet* packet); - int64_t ReadPacketS64(uint32_t startLoc, Packet* packet); + uint16_t ReadU16(uint32_t startLoc, Packet* packet); + uint32_t ReadU32(uint32_t startLoc, Packet* packet); + uint64_t ReadU64(uint32_t startLoc, Packet* packet); + int64_t ReadS64(uint32_t startLoc, Packet* packet); std::string ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen = 33); - - void WritePacketString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream); - void WriteString(RakNet::BitStream& bitStream, const std::string& s, uint32_t maxSize); - void WriteWString(RakNet::BitStream& bitStream, const std::string& string, uint32_t maxSize); - void WriteWString(RakNet::BitStream& bitStream, const std::u16string& string, uint32_t maxSize); - void WritePacketWString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream); - void SavePacket(const std::string& filename, const char* data, size_t length); }; diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index 35c985eb..18c2c8a5 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -14,10 +14,11 @@ #include "CharacterComponent.h" #include "ZCompression.h" #include "eConnectionType.h" +#include "BitStreamUtils.h" void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE); auto zone = Game::zoneManager->GetZone()->GetZoneID(); bitStream.Write(static_cast(zone.GetMapID())); @@ -41,7 +42,7 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) { if (!user) return; RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE); std::vector characters = user->GetCharacters(); bitStream.Write(static_cast(characters.size())); @@ -51,13 +52,13 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) { bitStream.Write(characters[i]->GetObjectID()); bitStream.Write(static_cast(0)); - PacketUtils::WriteWString(bitStream, characters[i]->GetName(), 33); - PacketUtils::WriteWString(bitStream, characters[i]->GetUnapprovedName(), 33); + bitStream.Write(LUWString(characters[i]->GetName())); + bitStream.Write(LUWString(characters[i]->GetUnapprovedName())); bitStream.Write(static_cast(characters[i]->GetNameRejected())); bitStream.Write(static_cast(false)); - PacketUtils::WriteString(bitStream, "", 10); + bitStream.Write(LUString("", 10)); bitStream.Write(characters[i]->GetShirtColor()); bitStream.Write(characters[i]->GetShirtStyle()); @@ -90,30 +91,30 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) { void WorldPackets::SendCharacterCreationResponse(const SystemAddress& sysAddr, eCharacterCreationResponse response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_CREATE_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_CREATE_RESPONSE); bitStream.Write(response); SEND_PACKET; } void WorldPackets::SendCharacterRenameResponse(const SystemAddress& sysAddr, eRenameResponse response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_RENAME_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_RENAME_RESPONSE); bitStream.Write(response); SEND_PACKET; } void WorldPackets::SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DELETE_CHARACTER_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DELETE_CHARACTER_RESPONSE); bitStream.Write(static_cast(response)); SEND_PACKET; } void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TRANSFER_TO_WORLD); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TRANSFER_TO_WORLD); - PacketUtils::WriteString(bitStream, serverIP, 33); + bitStream.Write(LUString(serverIP)); bitStream.Write(static_cast(serverPort)); bitStream.Write(static_cast(mythranShift)); @@ -122,14 +123,14 @@ void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std:: void WorldPackets::SendServerState(const SystemAddress& sysAddr) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SERVER_STATES); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SERVER_STATES); bitStream.Write(static_cast(1)); //If the server is receiving this request, it probably is ready anyway. SEND_PACKET; } void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CREATE_CHARACTER); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CREATE_CHARACTER); RakNet::BitStream data; data.Write(7); //LDF key count @@ -198,7 +199,7 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector> unacceptedItems) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHAT_MODERATION_STRING); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHAT_MODERATION_STRING); bitStream.Write(unacceptedItems.empty()); // Is sentence ok? bitStream.Write(0x16); // Source ID, unknown @@ -206,7 +207,7 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool bitStream.Write(static_cast(requestID)); // request ID bitStream.Write(static_cast(0)); // chat mode - PacketUtils::WritePacketWString(receiver, 42, &bitStream); // receiver name + bitStream.Write(LUWString(receiver, 42)); // receiver name for (auto it : unacceptedItems) { bitStream.Write(it.first); // start index @@ -222,7 +223,7 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAKE_GM_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAKE_GM_RESPONSE); bitStream.Write(success); bitStream.Write(static_cast(highestLevel)); diff --git a/dNet/ZoneInstanceManager.cpp b/dNet/ZoneInstanceManager.cpp index b57bb634..f9285579 100644 --- a/dNet/ZoneInstanceManager.cpp +++ b/dNet/ZoneInstanceManager.cpp @@ -28,10 +28,10 @@ void ZoneInstanceManager::RequestZoneTransfer(dServer* server, uint32_t zoneID, void ZoneInstanceManager::HandleRequestZoneTransferResponse(uint64_t requestID, Packet* packet) { bool mythranShift = static_cast(packet->data[16]); - uint32_t zoneID = PacketUtils::ReadPacketU32(17, packet); - uint32_t zoneInstance = PacketUtils::ReadPacketU32(21, packet); - uint32_t zoneClone = PacketUtils::ReadPacketU32(25, packet); - uint16_t serverPort = PacketUtils::ReadPacketU16(29, packet); + uint32_t zoneID = PacketUtils::ReadU32(17, packet); + uint32_t zoneInstance = PacketUtils::ReadU32(21, packet); + uint32_t zoneClone = PacketUtils::ReadU32(25, packet); + uint16_t serverPort = PacketUtils::ReadU16(29, packet); std::string serverIP = PacketUtils::ReadString(31, packet, false); for (uint32_t i = 0; i < this->requests.size(); ++i) { diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 610f06a5..75cd4091 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -11,6 +11,7 @@ #include "eMasterMessageType.h" #include "PacketUtils.h" +#include "BitStreamUtils.h" #include "MasterPackets.h" #include "ZoneInstanceManager.h" @@ -123,7 +124,7 @@ Packet* dServer::ReceiveFromMaster() { if (static_cast(packet->data[1]) == eConnectionType::MASTER) { switch (static_cast(packet->data[3])) { case eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE: { - uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); + uint64_t requestID = PacketUtils::ReadU64(8, packet); ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet); break; } @@ -168,7 +169,7 @@ void dServer::SendToMaster(RakNet::BitStream* bitStream) { void dServer::Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::DISCONNECT_NOTIFY); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::DISCONNECT_NOTIFY); bitStream.Write(disconNotifyID); mPeer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, sysAddr, false); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 644e6ce8..73c33c84 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -29,6 +29,7 @@ #include "AuthPackets.h" #include "PacketUtils.h" +#include "BitStreamUtils.h" #include "WorldPackets.h" #include "UserManager.h" #include "CDClientManager.h" @@ -708,7 +709,7 @@ void HandlePacket(Packet* packet) { { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); bitStream.Write(user->GetLoggedInChar()); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } @@ -720,7 +721,7 @@ void HandlePacket(Packet* packet) { } CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_REMOVED); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_REMOVED); bitStream.Write((LWOMAPID)Game::server->GetZoneID()); bitStream.Write((LWOINSTANCEID)instanceID); Game::server->SendToMaster(&bitStream); @@ -736,14 +737,14 @@ void HandlePacket(Packet* packet) { if (static_cast(packet->data[1]) == eConnectionType::MASTER) { switch (static_cast(packet->data[3])) { case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: { - uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); - uint32_t objectID = PacketUtils::ReadPacketU32(16, packet); + uint64_t requestID = PacketUtils::ReadU64(8, packet); + uint32_t objectID = PacketUtils::ReadU32(16, packet); ObjectIDManager::Instance()->HandleRequestPersistentIDResponse(requestID, objectID); break; } case eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE: { - uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); + uint64_t requestID = PacketUtils::ReadU64(8, packet); ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet); break; } @@ -805,7 +806,7 @@ void HandlePacket(Packet* packet) { //Notify master: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_ADDED); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_ADDED); bitStream.Write((LWOMAPID)Game::server->GetZoneID()); bitStream.Write((LWOINSTANCEID)instanceID); Game::server->SendToMaster(&bitStream); @@ -815,13 +816,13 @@ void HandlePacket(Packet* packet) { break; } case eMasterMessageType::AFFIRM_TRANSFER_REQUEST: { - const uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); + const uint64_t requestID = PacketUtils::ReadU64(8, packet); Game::logger->Log("MasterServer", "Got affirmation request of transfer %llu", requestID); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_RESPONSE); bitStream.Write(requestID); Game::server->SendToMaster(&bitStream); @@ -907,8 +908,8 @@ void HandlePacket(Packet* packet) { //Request the session info from Master: CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_SESSION_KEY); - PacketUtils::WriteString(bitStream, username, 64); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_SESSION_KEY); + bitStream.Write(LUString(username, 64)); Game::server->SendToMaster(&bitStream); //Insert info into our pending list @@ -981,7 +982,7 @@ void HandlePacket(Packet* packet) { // This means we swapped characters and we need to remove the previous player from the container. if (static_cast(lastCharacter) != playerID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); bitStream.Write(lastCharacter); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } @@ -1130,7 +1131,7 @@ void HandlePacket(Packet* packet) { GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); bitStream.Write(LWOOBJID_EMPTY); //always zero so that a check on the client passes bitStream.Write(eBlueprintSaveResponseType::EverythingWorked); bitStream.Write(1); @@ -1171,7 +1172,7 @@ void HandlePacket(Packet* packet) { //RakNet::RakString playerName(player->GetCharacter()->GetName().c_str()); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION); bitStream.Write(player->GetObjectID()); bitStream.Write(playerName.size()); for (size_t i = 0; i < playerName.size(); i++) { @@ -1222,7 +1223,7 @@ void HandlePacket(Packet* packet) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, packet->data[14]); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, packet->data[14]); //We need to insert the player's objectID so the chat server can find who originated this request: LWOOBJID objectID = 0; @@ -1348,6 +1349,6 @@ void FinalizeShutdown() { void SendShutdownMessageToMaster() { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_RESPONSE); + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_RESPONSE); Game::server->SendToMaster(&bitStream); } diff --git a/tests/dCommonTests/CMakeLists.txt b/tests/dCommonTests/CMakeLists.txt index a345863d..006102fa 100644 --- a/tests/dCommonTests/CMakeLists.txt +++ b/tests/dCommonTests/CMakeLists.txt @@ -5,6 +5,8 @@ set(DCOMMONTEST_SOURCES "TestLDFFormat.cpp" "TestNiPoint3.cpp" "TestEncoding.cpp" + "TestLUString.cpp" + "TestLUWString.cpp" "dCommonDependencies.cpp" ) diff --git a/tests/dCommonTests/TestLUString.cpp b/tests/dCommonTests/TestLUString.cpp new file mode 100644 index 00000000..3abec985 --- /dev/null +++ b/tests/dCommonTests/TestLUString.cpp @@ -0,0 +1,121 @@ +#include + +#include "dCommonVars.h" + +TEST(LUString33Test, SerializeWriteTestOld) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + std::string result; + char c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeWriteTestOldPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::string result; + char c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeWriteTestNew) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + std::string result; + char c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeWriteTestNewPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + std::string result; + char c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeReadTestOld) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + std::string result; + char c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeReadTestOldPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::string result; + char c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeReadTestNew) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + LUString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +} + +TEST(LUString33Test, SerializeReadTestNewPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + LUString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +} diff --git a/tests/dCommonTests/TestLUWString.cpp b/tests/dCommonTests/TestLUWString.cpp new file mode 100644 index 00000000..a16dd911 --- /dev/null +++ b/tests/dCommonTests/TestLUWString.cpp @@ -0,0 +1,121 @@ +#include + +#include "dCommonVars.h" + +TEST(LUWString33Test, SerializeWriteTestOld) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + std::u16string result; + char16_t c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeWriteTestOldPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::u16string result; + char16_t c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeWriteTestNew) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + std::u16string result; + char16_t c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeWriteTestNewPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + std::u16string result; + char16_t c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeReadTestOld) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + std::u16string result; + char16_t c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeReadTestOldPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::u16string result; + char16_t c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeReadTestNew) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + LUWString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +} + +TEST(LUWString33Test, SerializeReadTestNewPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + LUWString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +} From 51540568fb91c5b798827c245aa84f2634efbf27 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:48:35 -0700 Subject: [PATCH 104/111] Strengthen checks for slash commands (#1198) --- dGame/dGameMessages/GameMessages.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 83f832b2..2a6405fd 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4909,6 +4909,13 @@ void GameMessages::HandleParseChatMessage(RakNet::BitStream* inStream, Entity* e inStream->Read(character); wsString.push_back(character); } + + auto player = Player::GetPlayer(sysAddr); + if (!player || !player->GetCharacter()) return; + if (player->GetObjectID() != entity->GetObjectID()) { + Game::logger->Log("GameMessages", "Player %s is trying to send a chat message from an entity %llu they do not own!", player->GetCharacter()->GetName().c_str(), entity->GetObjectID()); + return; + } if (wsString[0] == L'/') { SlashCommandHandler::HandleChatCommand(wsString, entity, sysAddr); From 44f466ac72d34d3188822997bc706df6ecea4ca6 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 24 Sep 2023 00:55:54 -0700 Subject: [PATCH 105/111] fix: deleting last character still shows the character (#1123) * Fix deleting last character Fix an issue where deleting your last character caused the character to still show up on the character selection screen. Tested that deleting my final character results in an empty character selection scene. * Update UserManager.cpp --- dGame/UserManager.cpp | 54 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index e0951405..4bbf8bd4 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -204,40 +204,38 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) { stmt->setUInt(1, u->GetAccountID()); sql::ResultSet* res = stmt->executeQuery(); - if (res->rowsCount() > 0) { - std::vector& chars = u->GetCharacters(); - - for (size_t i = 0; i < chars.size(); ++i) { - if (chars[i]->GetEntity() == nullptr) // We don't have entity data to save - { - delete chars[i]; - - continue; - } - - auto* skillComponent = chars[i]->GetEntity()->GetComponent(); - - if (skillComponent != nullptr) { - skillComponent->Reset(); - } - - Game::entityManager->DestroyEntity(chars[i]->GetEntity()); - - chars[i]->SaveXMLToDatabase(); - - chars[i]->GetEntity()->SetCharacter(nullptr); + std::vector& chars = u->GetCharacters(); + for (size_t i = 0; i < chars.size(); ++i) { + if (chars[i]->GetEntity() == nullptr) // We don't have entity data to save + { delete chars[i]; + + continue; } - chars.clear(); + auto* skillComponent = chars[i]->GetEntity()->GetComponent(); - while (res->next()) { - LWOOBJID objID = res->getUInt64(1); - Character* character = new Character(uint32_t(objID), u); - character->SetIsNewLogin(); - chars.push_back(character); + if (skillComponent != nullptr) { + skillComponent->Reset(); } + + Game::entityManager->DestroyEntity(chars[i]->GetEntity()); + + chars[i]->SaveXMLToDatabase(); + + chars[i]->GetEntity()->SetCharacter(nullptr); + + delete chars[i]; + } + + chars.clear(); + + while (res->next()) { + LWOOBJID objID = res->getUInt64(1); + Character* character = new Character(uint32_t(objID), u); + character->SetIsNewLogin(); + chars.push_back(character); } delete res; From bd65fc6e33a5beafd48c62dc8360e813d86825c0 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 25 Sep 2023 06:23:23 -0700 Subject: [PATCH 106/111] Fix version number (#1199) Accidentally reverted the changes in a previous PR. --- CMakeVariables.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeVariables.txt b/CMakeVariables.txt index 732a615b..abfe9e15 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -1,5 +1,5 @@ PROJECT_VERSION_MAJOR=1 -PROJECT_VERSION_MINOR=0 +PROJECT_VERSION_MINOR=1 PROJECT_VERSION_PATCH=1 # LICENSE LICENSE=AGPL-3.0 From b24775f4729118d1a527a98e07141c1d245bf898 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 28 Sep 2023 10:16:11 -0700 Subject: [PATCH 107/111] feat: Security improvements for spoofed packets (#1201) * Add cheat detection for spoofed packets * Add config option for ip loggin * remove packet saving --- dGame/UserManager.cpp | 38 ++++--- dGame/dGameMessages/GameMessages.cpp | 7 -- dGame/dUtilities/CMakeLists.txt | 1 + dGame/dUtilities/CheatDetection.cpp | 137 +++++++++++++++++++++++++ dGame/dUtilities/CheatDetection.h | 30 ++++++ dNet/ClientPackets.cpp | 15 ++- dWorldServer/WorldServer.cpp | 23 ++++- migrations/dlu/10_Security_updates.sql | 8 ++ resources/worldconfig.ini | 3 + 9 files changed, 237 insertions(+), 25 deletions(-) create mode 100644 dGame/dUtilities/CheatDetection.cpp create mode 100644 dGame/dUtilities/CheatDetection.h create mode 100644 migrations/dlu/10_Security_updates.sql diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 4bbf8bd4..90e44187 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -29,6 +29,7 @@ #include "eConnectionType.h" #include "eChatInternalMessageType.h" #include "BitStreamUtils.h" +#include "CheatDetection.h" UserManager* UserManager::m_Address = nullptr; @@ -391,15 +392,14 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) Game::logger->Log("UserManager", "Received char delete req for ID: %llu (%u)", objectID, charID); - //Check if this user has this character: - bool hasCharacter = false; - std::vector& characters = u->GetCharacters(); - for (size_t i = 0; i < characters.size(); ++i) { - if (characters[i]->GetID() == charID) { hasCharacter = true; } - } + bool hasCharacter = CheatDetection::VerifyLwoobjidIsSender( + objectID, + sysAddr, + CheckType::User, + "User %i tried to delete a character that it does not own!", + u->GetAccountID()); if (!hasCharacter) { - Game::logger->Log("UserManager", "User %i tried to delete a character that it does not own!", u->GetAccountID()); WorldPackets::SendCharacterDeleteResponse(sysAddr, false); } else { Game::logger->Log("UserManager", "Deleting character %i", charID); @@ -494,16 +494,24 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet) Character* character = nullptr; //Check if this user has this character: - bool hasCharacter = false; - std::vector& characters = u->GetCharacters(); - for (size_t i = 0; i < characters.size(); ++i) { - if (characters[i]->GetID() == charID) { hasCharacter = true; character = characters[i]; } - } + bool ownsCharacter = CheatDetection::VerifyLwoobjidIsSender( + objectID, + sysAddr, + CheckType::User, + "User %i tried to rename a character that it does not own!", + u->GetAccountID()); - if (!hasCharacter || !character) { - Game::logger->Log("UserManager", "User %i tried to rename a character that it does not own!", u->GetAccountID()); + std::find_if(u->GetCharacters().begin(), u->GetCharacters().end(), [&](Character* c) { + if (c->GetID() == charID) { + character = c; + return true; + } + return false; + }); + + if (!ownsCharacter || !character) { WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::UNKNOWN_ERROR); - } else if (hasCharacter && character) { + } else if (ownsCharacter && character) { if (newName == character->GetName()) { WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::NAME_UNAVAILABLE); return; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 2a6405fd..83f832b2 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4909,13 +4909,6 @@ void GameMessages::HandleParseChatMessage(RakNet::BitStream* inStream, Entity* e inStream->Read(character); wsString.push_back(character); } - - auto player = Player::GetPlayer(sysAddr); - if (!player || !player->GetCharacter()) return; - if (player->GetObjectID() != entity->GetObjectID()) { - Game::logger->Log("GameMessages", "Player %s is trying to send a chat message from an entity %llu they do not own!", player->GetCharacter()->GetName().c_str(), entity->GetObjectID()); - return; - } if (wsString[0] == L'/') { SlashCommandHandler::HandleChatCommand(wsString, entity, sysAddr); diff --git a/dGame/dUtilities/CMakeLists.txt b/dGame/dUtilities/CMakeLists.txt index 55ca5797..639f9cf4 100644 --- a/dGame/dUtilities/CMakeLists.txt +++ b/dGame/dUtilities/CMakeLists.txt @@ -1,4 +1,5 @@ set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp" + "CheatDetection.cpp" "GUID.cpp" "Loot.cpp" "Mail.cpp" diff --git a/dGame/dUtilities/CheatDetection.cpp b/dGame/dUtilities/CheatDetection.cpp new file mode 100644 index 00000000..6459bb2c --- /dev/null +++ b/dGame/dUtilities/CheatDetection.cpp @@ -0,0 +1,137 @@ +#include "CheatDetection.h" +#include "Database.h" +#include "Entity.h" +#include "PossessableComponent.h" +#include "Player.h" +#include "Game.h" +#include "EntityManager.h" +#include "Character.h" +#include "User.h" +#include "UserManager.h" +#include "dConfig.h" + +Entity* GetPossessedEntity(const LWOOBJID& objId) { + auto* entity = Game::entityManager->GetEntity(objId); + if (!entity) return nullptr; + + auto* possessableComponent = entity->GetComponent(); + // If no possessable, then this entity is the most possessed entity. + if (!possessableComponent) return entity; + + // If not, get the entity that possesses the fetched entity. + return Game::entityManager->GetEntity(possessableComponent->GetPossessor()); +} + +void ReportCheat(User* user, const SystemAddress& sysAddr, const char* messageIfNotSender, va_list args) { + if (!user) { + Game::logger->Log("CheatDetection", "WARNING: User is null, using defaults."); + } + std::unique_ptr stmt(Database::CreatePreppedStmt( + "INSERT INTO player_cheat_detections (account_id, name, violation_msg, violation_system_address) VALUES (?, ?, ?, ?)") + ); + stmt->setInt(1, user ? user->GetAccountID() : 0); + stmt->setString(2, user ? user->GetUsername().c_str() : "User is null."); + + constexpr int32_t bufSize = 4096; + char buffer[bufSize]; + vsnprintf(buffer, bufSize, messageIfNotSender, args); + + stmt->setString(3, buffer); + stmt->setString(4, Game::config->GetValue("log_ip_addresses_for_anti_cheat") == "1" ? sysAddr.ToString() : "IP logging disabled."); + stmt->execute(); + Game::logger->Log("CheatDetection", "Anti-cheat message: %s", buffer); +} + +void LogAndSaveFailedAntiCheatCheck(const LWOOBJID& id, const SystemAddress& sysAddr, const CheckType checkType, const char* messageIfNotSender, va_list args) { + User* toReport = nullptr; + switch (checkType) { + case CheckType::Entity: { + auto* player = Player::GetPlayer(sysAddr); + auto* entity = GetPossessedEntity(id); + + // If player exists and entity exists in world, use both for logging info. + if (entity && player) { + Game::logger->Log("CheatDetection", "Player (%s) (%llu) at system address (%s) with sending player (%s) (%llu) does not match their own.", + player->GetCharacter()->GetName().c_str(), player->GetObjectID(), + sysAddr.ToString(), + entity->GetCharacter()->GetName().c_str(), entity->GetObjectID()); + // In the case that the target entity id did not exist, just log the player info. + } else if (player) { + Game::logger->Log("CheatDetection", "Player (%s) (%llu) at system address (%s) with sending player (%llu) does not match their own.", + player->GetCharacter()->GetName().c_str(), player->GetObjectID(), + sysAddr.ToString(), id); + // In the rare case that the player does not exist, just log the system address and who the target id was. + } else { + Game::logger->Log("CheatDetection", "Player at system address (%s) with sending player (%llu) does not match their own.", + sysAddr.ToString(), id); + } + toReport = player->GetParentUser(); + break; + } + case CheckType::User: { + auto* user = UserManager::Instance()->GetUser(sysAddr); + + if (user) { + Game::logger->Log("CheatDetection", "User at system address (%s) (%s) (%llu) sent a packet as (%i) which is not an id they own.", + sysAddr.ToString(), user->GetLastUsedChar()->GetName().c_str(), user->GetLastUsedChar()->GetObjectID(), static_cast(id)); + // Can't know sending player. Just log system address for IP banning. + } else { + Game::logger->Log("CheatDetection", "No user found for system address (%s).", sysAddr.ToString()); + } + toReport = user; + break; + } + }; + ReportCheat(toReport, sysAddr, messageIfNotSender, args); +} + +void CheatDetection::ReportCheat(User* user, const SystemAddress& sysAddr, const char* messageIfNotSender, ...) { + va_list args; + va_start(args, messageIfNotSender); + ReportCheat(user, sysAddr, messageIfNotSender, args); + va_end(args); +} + +bool CheatDetection::VerifyLwoobjidIsSender(const LWOOBJID& id, const SystemAddress& sysAddr, const CheckType checkType, const char* messageIfNotSender, ...) { + // Get variables we'll need for the whole function + bool invalidPacket = false; + switch (checkType) { + case CheckType::Entity: { + // In this case, the sender may be an entity in the world. + auto* entity = GetPossessedEntity(id); + if (entity) { + invalidPacket = entity->IsPlayer() && entity->GetSystemAddress() != sysAddr; + } + break; + } + case CheckType::User: { + // In this case, the player is not an entity in the world, but may be a user still in world server if they are connected. + // Check here if the system address has a character with id matching the lwoobjid after unsetting the flag bits. + auto* sendingUser = UserManager::Instance()->GetUser(sysAddr); + if (!sendingUser) { + Game::logger->Log("CheatDetection", "No user found for system address (%s).", sysAddr.ToString()); + return false; + } + invalidPacket = true; + const uint32_t characterId = static_cast(id); + // Check to make sure the ID provided is one of the user's characters. + for (const auto& character : sendingUser->GetCharacters()) { + if (character && character->GetID() == characterId) { + invalidPacket = false; + break; + } + } + } + }; + + // This will be true if the player does not possess the entity they are trying to send a packet as. + // or if the user does not own the character they are trying to send a packet as. + if (invalidPacket) { + va_list args; + va_start(args, messageIfNotSender); + LogAndSaveFailedAntiCheatCheck(id, sysAddr, checkType, messageIfNotSender, args); + va_end(args); + } + + return !invalidPacket; +} diff --git a/dGame/dUtilities/CheatDetection.h b/dGame/dUtilities/CheatDetection.h new file mode 100644 index 00000000..ee0dce89 --- /dev/null +++ b/dGame/dUtilities/CheatDetection.h @@ -0,0 +1,30 @@ +#ifndef __CHEATDETECTION__H__ +#define __CHEATDETECTION__H__ + +#include "dCommonVars.h" + +struct SystemAddress; + +enum class CheckType : uint8_t { + User, + Entity, +}; + +namespace CheatDetection { + /** + * @brief Verify that the object ID provided in this function is in someway connected to the system address who sent it. + * + * @param id The object ID to check ownership of + * @param sysAddr The system address which sent the packet + * @param checkType The check type to perform + * @param messageIfNotSender The message to log if the sender is not the owner of the object ID + * @param ... format args + * @return true If the sender is the owner of the object ID + * @return false If the sender is not the owner of the object ID + */ + bool VerifyLwoobjidIsSender(const LWOOBJID& id, const SystemAddress& sysAddr, const CheckType checkType, const char* messageIfNotSender, ...); + void ReportCheat(User* user, const SystemAddress& sysAddr, const char* messageIfNotSender, ...); +}; + +#endif //!__CHEATDETECTION__H__ + diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 8bebda93..e797ea21 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -33,6 +33,7 @@ #include "Database.h" #include "eGameMasterLevel.h" #include "eReplicaComponentType.h" +#include "CheatDetection.h" void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) { User* user = UserManager::Instance()->GetUser(sysAddr); @@ -65,8 +66,18 @@ void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* pack std::string playerName = user->GetLastUsedChar()->GetName(); bool isMythran = user->GetLastUsedChar()->GetGMLevel() > eGameMasterLevel::CIVILIAN; - - if (!user->GetLastChatMessageApproved() && !isMythran) return; + bool isOk = Game::chatFilter->IsSentenceOkay(GeneralUtils::UTF16ToWTF8(message), user->GetLastUsedChar()->GetGMLevel()).empty(); + Game::logger->LogDebug("ClientPackets", "Msg: %s was approved previously? %i", GeneralUtils::UTF16ToWTF8(message).c_str(), user->GetLastChatMessageApproved()); + if (!isOk) { + // Add a limit to the string converted by general utils because it is a user received string and may be a bad actor. + CheatDetection::ReportCheat( + user, + sysAddr, + "Player %s attempted to bypass chat filter with message: %s", + playerName.c_str(), + GeneralUtils::UTF16ToWTF8(message, 512).c_str()); + } + if (!isOk && !isMythran) return; std::string sMessage = GeneralUtils::UTF16ToWTF8(message); Game::logger->Log("Chat", "%s: %s", playerName.c_str(), sMessage.c_str()); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 73c33c84..6e038b06 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -73,6 +73,7 @@ #include "eGameMessageType.h" #include "ZCompression.h" #include "EntityManager.h" +#include "CheatDetection.h" namespace Game { dLogger* logger = nullptr; @@ -957,7 +958,15 @@ void HandlePacket(Packet* packet) { RakNet::BitStream dataStream; bitStream.Read(dataStream, bitStream.GetNumberOfUnreadBits()); - GameMessageHandler::HandleMessage(&dataStream, packet->systemAddress, objectID, messageID); + auto isSender = CheatDetection::VerifyLwoobjidIsSender( + objectID, + packet->systemAddress, + CheckType::Entity, + "Sending GM with a sending player that does not match their own. GM ID: %i", + static_cast(messageID) + ); + + if (isSender) GameMessageHandler::HandleMessage(&dataStream, packet->systemAddress, objectID, messageID); break; } @@ -972,6 +981,17 @@ void HandlePacket(Packet* packet) { LWOOBJID playerID = 0; inStream.Read(playerID); + + bool valid = CheatDetection::VerifyLwoobjidIsSender( + playerID, + packet->systemAddress, + CheckType::User, + "Sending login request with a sending player that does not match their own. Player ID: %llu", + playerID + ); + + if (!valid) return; + GeneralUtils::ClearBit(playerID, eObjectBits::CHARACTER); GeneralUtils::ClearBit(playerID, eObjectBits::PERSISTENT); @@ -1204,6 +1224,7 @@ void HandlePacket(Packet* packet) { case eWorldMessageType::MAIL: { RakNet::BitStream bitStream(packet->data, packet->length, false); + // FIXME: Change this to the macro to skip the header... LWOOBJID space; bitStream.Read(space); Mail::HandleMailStuff(&bitStream, packet->systemAddress, UserManager::Instance()->GetUser(packet->systemAddress)->GetLastUsedChar()->GetEntity()); diff --git a/migrations/dlu/10_Security_updates.sql b/migrations/dlu/10_Security_updates.sql new file mode 100644 index 00000000..4cbf51a0 --- /dev/null +++ b/migrations/dlu/10_Security_updates.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS player_cheat_detections ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + account_id INT REFERENCES accounts(id), + name TEXT REFERENCES charinfo(name), + violation_msg TEXT NOT NULL, + violation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(), + violation_system_address TEXT NOT NULL +); diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index b05614b4..c0a0a10a 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -61,3 +61,6 @@ hardcore_lose_uscore_on_death_percent=10 # Allow civilian players the ability to turn the nameplate above their head off. Must be exactly 1 to be enabled for civilians. allow_nameplate_off=0 + +# Turn logging of IP addresses for anti-cheat reporting on (1) or off(0) +log_ip_addresses_for_anti_cheat=1 From 1ec8da8bf7c93baccfb6b081ae4baec5570b4446 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 30 Sep 2023 06:22:32 -0500 Subject: [PATCH 108/111] fix: remove foreign key on name in cheat_detection table (#1202) --- migrations/dlu/11_fix_cheat_detection_table.sql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 migrations/dlu/11_fix_cheat_detection_table.sql diff --git a/migrations/dlu/11_fix_cheat_detection_table.sql b/migrations/dlu/11_fix_cheat_detection_table.sql new file mode 100644 index 00000000..21464834 --- /dev/null +++ b/migrations/dlu/11_fix_cheat_detection_table.sql @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS `player_cheat_detections`; +CREATE TABLE IF NOT EXISTS player_cheat_detections ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + account_id INT REFERENCES accounts(id), + name TEXT NOT NULL, + violation_msg TEXT NOT NULL, + violation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(), + violation_system_address TEXT NOT NULL +); From a8820c14f2c43dd817347044764dda9335f4c3a0 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 30 Sep 2023 16:48:12 -0700 Subject: [PATCH 109/111] AssetManager: Match allocators (#1205) Currently on line 116 of AssetManager.cpp, we have the following `*data = (char*)malloc(*len);` however on line 45 of AssetManager.h we have `delete m_Base;` which is not the same allocator as we used to allocate the memory. This PR matches the malloc and free to be the correct calls. --- dCommon/dClient/AssetManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dCommon/dClient/AssetManager.h b/dCommon/dClient/AssetManager.h index bc7e5ff7..d2543489 100644 --- a/dCommon/dClient/AssetManager.h +++ b/dCommon/dClient/AssetManager.h @@ -42,7 +42,7 @@ struct AssetMemoryBuffer : std::streambuf { } void close() { - delete m_Base; + free(m_Base); } }; From 258ee5c1eebeaf0aefadad94c55c8c5e78b649b0 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 5 Oct 2023 15:31:05 -0700 Subject: [PATCH 110/111] CheatDetection: Move player access (#1209) --- dGame/dUtilities/CheatDetection.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dGame/dUtilities/CheatDetection.cpp b/dGame/dUtilities/CheatDetection.cpp index 6459bb2c..11a68263 100644 --- a/dGame/dUtilities/CheatDetection.cpp +++ b/dGame/dUtilities/CheatDetection.cpp @@ -55,17 +55,18 @@ void LogAndSaveFailedAntiCheatCheck(const LWOOBJID& id, const SystemAddress& sys player->GetCharacter()->GetName().c_str(), player->GetObjectID(), sysAddr.ToString(), entity->GetCharacter()->GetName().c_str(), entity->GetObjectID()); + toReport = player->GetParentUser(); // In the case that the target entity id did not exist, just log the player info. } else if (player) { Game::logger->Log("CheatDetection", "Player (%s) (%llu) at system address (%s) with sending player (%llu) does not match their own.", player->GetCharacter()->GetName().c_str(), player->GetObjectID(), sysAddr.ToString(), id); + toReport = player->GetParentUser(); // In the rare case that the player does not exist, just log the system address and who the target id was. } else { Game::logger->Log("CheatDetection", "Player at system address (%s) with sending player (%llu) does not match their own.", sysAddr.ToString(), id); } - toReport = player->GetParentUser(); break; } case CheckType::User: { From b33e9935f54d702eadc919163e5db7d9f40e10f4 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 6 Oct 2023 01:20:20 -0500 Subject: [PATCH 111/111] fix: GM 1272 was labled as 1273 (#1210) --- 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 d5751b51..df822c52 100644 --- a/dCommon/dEnums/eGameMessageType.h +++ b/dCommon/dEnums/eGameMessageType.h @@ -1152,7 +1152,7 @@ enum class eGameMessageType : uint16_t { COLLISION_POINT_REMOVED = 1269, SET_ATTACHED = 1270, SET_DESTROYABLE_MODEL_BRICKS = 1271, - VEHICLE_SET_POWERSLIDE_LOCK_WHEELS = 1273, + VEHICLE_SET_POWERSLIDE_LOCK_WHEELS = 1272, VEHICLE_SET_WHEEL_LOCK_STATE = 1273, SHOW_HEALTH_BAR = 1274, GET_SHOWS_HEALTH_BAR = 1275,